Merge "Update field for ACTION_ANOMALY_TRIGGERED" into pi-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b892dee..5a2e01a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -742,6 +742,10 @@
             android:exported="true"
             android:taskAffinity="com.android.settings"
             android:parentActivityName="Settings">
+            <intent-filter android:priority="1">
+                <action android:name="android.settings.ZEN_MODE_BLOCKED_EFFECTS_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                        android:value="com.android.settings.notification.ZenModeBlockedEffectsSettings" />
             <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
@@ -749,6 +753,20 @@
         </activity>
 
         <activity
+            android:name=".notification.ZenOnboardingActivity"
+            android:label="@string/zen_onboarding_dnd_visual_disturbances_header"
+            android:icon="@drawable/ic_settings_notifications"
+            android:theme="@style/Theme.Settings.NoActionBar"
+            android:exported="true"
+            android:taskAffinity="com.android.settings"
+            android:parentActivityName="Settings">
+            <intent-filter android:priority="1">
+                <action android:name="android.settings.ZEN_MODE_ONBOARDING" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity
             android:name="Settings$ZenModeBehaviorSettingsActivity"
             android:label="@string/zen_mode_behavior_settings_title"
             android:icon="@drawable/ic_settings_notifications"
@@ -1842,43 +1860,39 @@
 
         <!-- Exported for SystemUI to launch into -->
         <activity android:name=".deviceinfo.StorageWizardInit"
-                android:theme="@style/SetupWizardStorageStyle"
+                android:theme="@style/GlifTheme.Light"
                 android:taskAffinity="com.android.settings.storage_wizard"
                 android:exported="true"
                 android:permission="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
-        <activity android:name=".deviceinfo.StorageWizardFormatConfirm"
-                android:theme="@style/SetupWizardStorageStyle"
-                android:taskAffinity="com.android.settings.storage_wizard"
-                android:exported="false" />
         <activity android:name=".deviceinfo.StorageWizardFormatProgress"
-                android:theme="@style/SetupWizardStorageStyle"
+                android:theme="@style/GlifTheme.Light"
                 android:taskAffinity="com.android.settings.storage_wizard"
                 android:exported="false" />
-        <activity android:name=".deviceinfo.StorageWizardMigrate"
-                android:theme="@style/SetupWizardStorageStyle"
+        <activity android:name=".deviceinfo.StorageWizardFormatSlow"
+                android:theme="@style/GlifTheme.Light"
                 android:taskAffinity="com.android.settings.storage_wizard"
                 android:exported="false" />
         <activity android:name=".deviceinfo.StorageWizardMigrateConfirm"
-                android:theme="@style/SetupWizardStorageStyle"
+                android:theme="@style/GlifTheme.Light"
                 android:taskAffinity="com.android.settings.storage_wizard"
                 android:exported="false" />
         <activity android:name=".deviceinfo.StorageWizardMigrateProgress"
-                android:theme="@style/SetupWizardStorageStyle"
+                android:theme="@style/GlifTheme.Light"
                 android:taskAffinity="com.android.settings.storage_wizard"
                 android:exported="true"
                 android:permission="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
         <activity android:name=".deviceinfo.StorageWizardReady"
-                android:theme="@style/SetupWizardStorageStyle"
+                android:theme="@style/GlifTheme.Light"
                 android:taskAffinity="com.android.settings.storage_wizard"
                 android:exported="true"
                 android:permission="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
 
         <activity android:name=".deviceinfo.StorageWizardMoveConfirm"
-                android:theme="@style/SetupWizardStorageStyle"
+                android:theme="@style/GlifTheme.Light"
                 android:taskAffinity="com.android.settings.storage_wizard"
                 android:exported="false" />
         <activity android:name=".deviceinfo.StorageWizardMoveProgress"
-                android:theme="@style/SetupWizardStorageStyle"
+                android:theme="@style/GlifTheme.Light"
                 android:taskAffinity="com.android.settings.storage_wizard"
                 android:exported="true"
                 android:permission="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
diff --git a/res/drawable-nodpi/auto_awesome_battery b/res/drawable-nodpi/auto_awesome_battery
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/drawable-nodpi/auto_awesome_battery
diff --git a/res/drawable/ic_apps_alt.xml b/res/drawable/ic_apps_alt.xml
new file mode 100644
index 0000000..6902a96
--- /dev/null
+++ b/res/drawable/ic_apps_alt.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M4,8h4L8,4L4,4v4zM10,20h4v-4h-4v4zM4,20h4v-4L4,16v4zM4,14h4v-4L4,10v4zM10,14h4v-4h-4v4zM16,4v4h4L20,4h-4zM10,8h4L14,4h-4v4zM16,14h4v-4h-4v4zM16,20h4v-4h-4v4z"
+        android:fillColor="#000000"/>
+</vector>
diff --git a/res/drawable/ic_battery_charging_full.xml b/res/drawable/ic_battery_charging_full.xml
new file mode 100644
index 0000000..c2a614e
--- /dev/null
+++ b/res/drawable/ic_battery_charging_full.xml
@@ -0,0 +1,24 @@
+<!--
+    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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33v15.33C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V5.33C17,4.6 16.4,4 15.67,4zM11,20v-5.5H9L13,7v5.5h2L11,20z"
+        android:fillColor="#000000"/>
+</vector>
diff --git a/res/drawable/ic_sd_card.xml b/res/drawable/ic_sd_card.xml
new file mode 100644
index 0000000..ff88779
--- /dev/null
+++ b/res/drawable/ic_sd_card.xml
@@ -0,0 +1,24 @@
+<!--
+    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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M18,2h-8L4.02,8 4,20c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,4c0,-1.1 -0.9,-2 -2,-2zM12,8h-2L10,4h2v4zM15,8h-2L13,4h2v4zM18,8h-2L16,4h2v4z"
+        android:fillColor="#000000"/>
+</vector>
diff --git a/res/drawable/ic_settings_aod.xml b/res/drawable/ic_settings_aod.xml
new file mode 100644
index 0000000..8d91349
--- /dev/null
+++ b/res/drawable/ic_settings_aod.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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+
+    <path
+        android:fillColor="#000000"
+        android:pathData="M17,1.01L7,1C5.9,1,5,1.9,5,3v18c0,1.1,0.9,2,2,2h10c1.1,0,2-0.9,2-2V3C19,1.9,18.1,1.01,17,1.01z M17,21H7l0-1h10V21z M17,18H7V6h10V18z M17,4H7V3h10V4z" />
+    <path
+        android:fillColor="#000000"
+        android:pathData="M 8 10 H 16 V 11.5 H 8 V 10 Z" />
+    <path
+        android:fillColor="#000000"
+        android:pathData="M 9 13 H 15 V 14.5 H 9 V 13 Z" />
+    <path
+        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_storage_wizard_external.xml b/res/drawable/ic_storage_wizard_external.xml
new file mode 100644
index 0000000..c11334d
--- /dev/null
+++ b/res/drawable/ic_storage_wizard_external.xml
@@ -0,0 +1,89 @@
+<!--
+    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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="144dp"
+        android:height="144dp"
+        android:viewportWidth="144.0"
+        android:viewportHeight="144.0">
+    <path
+        android:pathData="M20.98,105C19.88,105 19,104.12 19,103.03L19,44.97C19,43.88 19.88,43 20.98,43L49.02,43C50.12,43 51,43.88 51,44.97L51,103.03C51,104.12 50.12,105 49.02,105L20.98,105Z"
+        android:strokeColor="#00000000"
+        android:fillType="evenOdd"
+        android:fillColor="#FFFFFF"
+        android:strokeWidth="1"/>
+    <path
+        android:pathData="M20.98,106C19.33,106 18,104.68 18,103.03L18,44.97C18,43.32 19.33,42 20.98,42L49.02,42C50.67,42 52,43.32 52,44.97L52,103.03C52,104.68 50.67,106 49.02,106L20.98,106Z"
+        android:fillType="nonZero"
+        android:strokeColor="#DADCE0"
+        android:fillColor="#00000000"
+        android:strokeWidth="2"/>
+    <path
+        android:pathData="M20.98,104L49.02,104C49.57,104 50,103.57 50,103.03L50,44.97C50,44.43 49.57,44 49.02,44L20.98,44C20.43,44 20,44.43 20,44.97L20,103.03C20,103.57 20.43,104 20.98,104Z"
+        android:fillType="nonZero"
+        android:strokeColor="#F1F3F4"
+        android:fillColor="#00000000"
+        android:strokeWidth="2"/>
+    <path
+        android:pathData="M79,97L159,97A1,1 0,0 1,160 98L160,106A1,1 0,0 1,159 107L79,107A1,1 0,0 1,78 106L78,98A1,1 0,0 1,79 97z"
+        android:strokeColor="#00000000"
+        android:fillType="evenOdd"
+        android:fillColor="#F1F3F4"
+        android:strokeWidth="1"/>
+    <path
+        android:pathData="M80,98L158,98A1,1 0,0 1,159 99L159,105A1,1 0,0 1,158 106L80,106A1,1 0,0 1,79 105L79,99A1,1 0,0 1,80 98z"
+        android:fillType="evenOdd"
+        android:strokeColor="#DADCE0"
+        android:fillColor="#00000000"
+        android:strokeWidth="2"/>
+    <path
+        android:pathData="M95,37L173,37C174.1,37 175,37.9 175,39L175,97C175,98.1 174.1,99 173,99L93,99L93,39C93,37.9 93.9,37 95,37Z"
+        android:strokeColor="#00000000"
+        android:fillType="evenOdd"
+        android:fillColor="#F1F3F4"
+        android:strokeWidth="1"/>
+    <path
+        android:pathData="M94,98L173,98C173.55,98 174,97.55 174,97L174,39C174,38.45 173.55,38 173,38L95,38C94.45,38 94,38.45 94,39L94,98Z"
+        android:fillType="evenOdd"
+        android:strokeColor="#DADCE0"
+        android:fillColor="#00000000"
+        android:strokeWidth="2"/>
+    <path
+        android:pathData="M100,43L180,43A1,1 0,0 1,181 44L181,92A1,1 0,0 1,180 93L100,93A1,1 0,0 1,99 92L99,44A1,1 0,0 1,100 43z"
+        android:strokeColor="#00000000"
+        android:fillType="evenOdd"
+        android:fillColor="#FFFFFF"
+        android:strokeWidth="1"/>
+    <path
+        android:pathData="M76.63,54L71.13,54L67.01,58.2L67,66.6C67,67.37 67.62,68 68.38,68L76.63,68C77.38,68 78,67.37 78,66.6L78,55.4C78,54.63 77.38,54 76.63,54ZM72.5,58.2L71.13,58.2L71.13,55.4L72.5,55.4L72.5,58.2ZM74.56,58.2L73.19,58.2L73.19,55.4L74.56,55.4L74.56,58.2ZM76.63,58.2L75.25,58.2L75.25,55.4L76.63,55.4L76.63,58.2Z"
+        android:strokeColor="#00000000"
+        android:fillType="nonZero"
+        android:fillAlpha="0.87"
+        android:fillColor="?android:attr/colorAccent"
+        android:strokeWidth="1"/>
+    <path
+        android:pathData="M66.99,82L63,86L66.99,90L66.99,87L74,87L74,85L66.99,85L66.99,82ZM81,80L77.01,76L77.01,79L70,79L70,81L77.01,81L77.01,84L81,80Z"
+        android:strokeColor="#00000000"
+        android:fillType="nonZero"
+        android:fillAlpha="0.87"
+        android:fillColor="?android:attr/colorAccent"
+        android:strokeWidth="1"/>
+    <path
+        android:pathData="M72,72m-71.04,0a71.04,71.04 0,1 1,142.08 0a71.04,71.04 0,1 1,-142.08 0"
+        android:fillType="evenOdd"
+        android:strokeColor="#DADCE0"
+        android:fillColor="#00000000"
+        android:strokeWidth="1.92"/>
+</vector>
diff --git a/res/drawable/ic_storage_wizard_internal.xml b/res/drawable/ic_storage_wizard_internal.xml
new file mode 100644
index 0000000..f6c660b
--- /dev/null
+++ b/res/drawable/ic_storage_wizard_internal.xml
@@ -0,0 +1,75 @@
+<!--
+    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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="82dp"
+        android:height="150dp"
+        android:viewportWidth="82.0"
+        android:viewportHeight="150.0">
+    <path
+        android:pathData="M42,62L45,62L45,64L42,64L42,67L40,67L40,64L37,64L37,62L40,62L40,59L42,59L42,62Z"
+        android:fillAlpha="0.87"
+        android:strokeColor="#00000000"
+        android:fillType="evenOdd"
+        android:fillColor="?android:attr/colorAccent"
+        android:strokeWidth="1"
+        android:strokeAlpha="0.87"/>
+    <path
+        android:pathData="M58.63,56L53.13,56L49.01,60.2L49,68.6C49,69.37 49.62,70 50.38,70L58.63,70C59.38,70 60,69.37 60,68.6L60,57.4C60,56.63 59.38,56 58.63,56ZM54.5,60.2L53.13,60.2L53.13,57.4L54.5,57.4L54.5,60.2ZM56.56,60.2L55.19,60.2L55.19,57.4L56.56,57.4L56.56,60.2ZM58.63,60.2L57.25,60.2L57.25,57.4L58.63,57.4L58.63,60.2Z"
+        android:fillAlpha="0.87"
+        android:strokeColor="#00000000"
+        android:fillType="nonZero"
+        android:fillColor="?android:attr/colorAccent"
+        android:strokeWidth="1"
+        android:strokeAlpha="0.87"/>
+    <path
+        android:pathData="M16,77L64,77A4,4 0,0 1,68 81L68,81A4,4 0,0 1,64 85L16,85A4,4 0,0 1,12 81L12,81A4,4 0,0 1,16 77z"
+        android:fillAlpha="0.87"
+        android:strokeColor="#00000000"
+        android:fillType="evenOdd"
+        android:fillColor="?android:attr/colorAccent"
+        android:strokeWidth="1"
+        android:strokeAlpha="0.87"/>
+    <path
+        android:pathData="M9,77h31v8h-31z"
+        android:strokeColor="#00000000"
+        android:fillType="evenOdd"
+        android:fillColor="#DADCE0"
+        android:strokeWidth="1"/>
+    <path
+        android:pathData="M6,144L74,144L74,6L6,6L6,144ZM4.95,150C2.21,150 0,147.88 0,145.24L0,4.76C0,2.12 2.21,0 4.95,0L75.05,0C77.79,0 80,2.12 80,4.76L80,145.24C80,147.88 77.79,150 75.05,150L4.95,150Z"
+        android:strokeColor="#00000000"
+        android:fillType="nonZero"
+        android:fillColor="#F1F3F4"
+        android:strokeWidth="1"/>
+    <path
+        android:pathData="M4.95,148L75.05,148C76.7,148 78,146.75 78,145.24L78,4.76C78,3.25 76.7,2 75.05,2L4.95,2C3.3,2 2,3.25 2,4.76L2,145.24C2,146.75 3.3,148 4.95,148ZM4.95,150C2.21,150 0,147.88 0,145.24L0,4.76C0,2.12 2.21,0 4.95,0L75.05,0C77.79,0 80,2.12 80,4.76L80,145.24C80,147.88 77.79,150 75.05,150L4.95,150Z"
+        android:strokeColor="#00000000"
+        android:fillType="nonZero"
+        android:fillColor="#DADCE0"
+        android:strokeWidth="1"/>
+    <path
+        android:pathData="M80,58L80,58C81.1,58 82,58.9 82,60L82,76C82,77.1 81.1,78 80,78L80,58Z"
+        android:strokeColor="#00000000"
+        android:fillType="evenOdd"
+        android:fillColor="#DADCE0"
+        android:strokeWidth="1"/>
+    <path
+        android:pathData="M80,32L80,32C81.1,32 82,32.9 82,34L82,40C82,41.1 81.1,42 80,42L80,32Z"
+        android:strokeColor="#00000000"
+        android:fillType="evenOdd"
+        android:fillColor="#DADCE0"
+        android:strokeWidth="1"/>
+</vector>
diff --git a/res/drawable/ic_swap_horiz.xml b/res/drawable/ic_swap_horiz.xml
new file mode 100644
index 0000000..a38833b
--- /dev/null
+++ b/res/drawable/ic_swap_horiz.xml
@@ -0,0 +1,24 @@
+<!--
+    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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z"
+        android:fillColor="#000000"/>
+</vector>
diff --git a/res/layout/preference_app.xml b/res/layout/preference_app.xml
index b27a12b..6605041 100644
--- a/res/layout/preference_app.xml
+++ b/res/layout/preference_app.xml
@@ -31,7 +31,6 @@
         android:gravity="start|center_vertical"
         android:minWidth="56dp"
         android:orientation="horizontal"
-        android:paddingStart="4dp"
         android:paddingEnd="8dp"
         android:paddingTop="4dp"
         android:paddingBottom="4dp">
@@ -96,8 +95,8 @@
         android:id="@android:id/widget_frame"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:gravity="end|center_vertical"
-        android:paddingStart="16dp"
+        android:gravity="center"
+        android:minWidth="64dp"
         android:orientation="vertical" />
 
 </LinearLayout>
diff --git a/res/layout/preference_radio.xml b/res/layout/preference_radio.xml
new file mode 100644
index 0000000..1ce8b81
--- /dev/null
+++ b/res/layout/preference_radio.xml
@@ -0,0 +1,104 @@
+<?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.
+-->
+<!-- This file is copied from preference_app.xml with modification to
+     support widget on the opposite side horizontally -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?android:attr/selectableItemBackground"
+    android:gravity="center_vertical"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+    <LinearLayout
+        android:id="@android:id/widget_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:minWidth="56dp"
+        android:layout_marginEnd="16dp"
+        android:orientation="vertical" />
+
+    <LinearLayout
+        android:id="@+id/icon_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:minWidth="32dp"
+        android:orientation="horizontal"
+        android:layout_marginEnd="16dp"
+        android:paddingTop="4dp"
+        android:paddingBottom="4dp">
+        <android.support.v7.internal.widget.PreferenceImageView
+            android:id="@android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            settings:maxWidth="@dimen/secondary_app_icon_size"
+            settings:maxHeight="@dimen/secondary_app_icon_size" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:paddingTop="16dp"
+        android:paddingBottom="16dp">
+
+        <TextView android:id="@android:id/title"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:textAppearance="@style/TextAppearance.TileTitle"
+                  android:ellipsize="marquee"
+                  android:fadingEdge="horizontal" />
+
+        <LinearLayout
+            android:id="@+id/summary_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone">
+            <TextView android:id="@android:id/summary"
+                      android:layout_width="0dp"
+                      android:layout_height="wrap_content"
+                      android:layout_weight="1"
+                      android:textAppearance="@style/TextAppearance.Small"
+                      android:textAlignment="viewStart"
+                      android:textColor="?android:attr/textColorSecondary" />
+
+            <TextView android:id="@+id/appendix"
+                      android:layout_width="0dp"
+                      android:layout_height="wrap_content"
+                      android:layout_weight="1"
+                      android:textAppearance="@style/TextAppearance.Small"
+                      android:textAlignment="viewEnd"
+                      android:textColor="?android:attr/textColorSecondary"
+                      android:maxLines="1"
+                      android:ellipsize="end" />
+        </LinearLayout>
+        <ProgressBar
+            android:id="@android:id/progress"
+            style="?android:attr/progressBarStyleHorizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="4dp"
+            android:max="100"
+            android:visibility="gone" />
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout/smart_battery_header.xml b/res/layout/smart_battery_header.xml
deleted file mode 100644
index 960f04a..0000000
--- a/res/layout/smart_battery_header.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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.
-  -->
-
-<!-- Entity header -->
-<LinearLayout
-    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="match_parent"
-    android:minHeight="200dp"
-    android:paddingBottom="32dp"
-    android:paddingStart="@dimen/preference_no_icon_padding_start"
-    android:paddingTop="24dp">
-
-</LinearLayout>
diff --git a/res/layout/storage_wizard_checklist.xml b/res/layout/storage_wizard_checklist.xml
new file mode 100644
index 0000000..6f21bb8
--- /dev/null
+++ b/res/layout/storage_wizard_checklist.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/suw_description_margin_top"
+        android:textColor="?android:attr/textColorPrimary"
+        android:text="@string/storage_wizard_migrate_v2_checklist" />
+    <TextView
+        android:id="@+id/storage_wizard_migrate_v2_checklist_media"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/suw_description_margin_top"
+        android:layout_marginBottom="@dimen/suw_description_margin_bottom"
+        android:textColor="?android:attr/textColorPrimary"
+        android:text="@string/storage_wizard_migrate_v2_checklist_media"
+        android:drawableStart="@drawable/ic_sd_card"
+        android:drawableTint="?android:attr/textColorSecondary"
+        android:drawablePadding="@dimen/suw_description_margin_bottom" />
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/suw_description_margin_bottom"
+        android:textColor="?android:attr/textColorPrimary"
+        android:text="@string/storage_wizard_migrate_v2_checklist_apps"
+        android:drawableStart="@drawable/ic_apps_alt"
+        android:drawableTint="?android:attr/textColorSecondary"
+        android:drawablePadding="@dimen/suw_description_margin_bottom" />
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/suw_description_margin_bottom"
+        android:textColor="?android:attr/textColorPrimary"
+        android:text="@string/storage_wizard_migrate_v2_checklist_battery"
+        android:drawableStart="@drawable/ic_battery_charging_full"
+        android:drawableTint="?android:attr/textColorSecondary"
+        android:drawablePadding="@dimen/suw_description_margin_bottom" />
+</LinearLayout>
diff --git a/res/layout/storage_wizard_footer.xml b/res/layout/storage_wizard_footer.xml
index f8384dc..0ff40aa 100644
--- a/res/layout/storage_wizard_footer.xml
+++ b/res/layout/storage_wizard_footer.xml
@@ -20,6 +20,15 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
+    <Button
+        android:id="@+id/storage_back_button"
+        style="@style/SuwGlifButton.Secondary"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:onClick="onNavigateBack"
+        android:visibility="gone"
+        android:text="@string/suw_back_button_label" />
+
     <Space
         android:layout_width="0dp"
         android:layout_height="0dp"
@@ -30,6 +39,8 @@
         style="@style/SuwGlifButton.Primary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:onClick="onNavigateNext"
+        android:visibility="gone"
         android:text="@string/suw_next_button_label" />
 
 </LinearLayout>
diff --git a/res/layout/storage_wizard_generic.xml b/res/layout/storage_wizard_generic.xml
index b6aab28..fe4c052 100644
--- a/res/layout/storage_wizard_generic.xml
+++ b/res/layout/storage_wizard_generic.xml
@@ -34,18 +34,13 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/suw_description_margin_top"
             android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Body1"
             android:textColor="?android:attr/textColorPrimary" />
 
-        <TextView
-            android:id="@+id/storage_wizard_second_body"
-            android:visibility="gone"
+        <FrameLayout
+            android:id="@+id/storage_wizard_aux"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/suw_description_margin_top"
-            android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Body1"
-            android:textColor="?android:attr/textColorPrimary" />
+            android:visibility="gone" />
 
     </LinearLayout>
 
diff --git a/res/layout/storage_wizard_init.xml b/res/layout/storage_wizard_init.xml
index 5fc298e..4905de6 100644
--- a/res/layout/storage_wizard_init.xml
+++ b/res/layout/storage_wizard_init.xml
@@ -28,41 +28,111 @@
         android:layout_height="match_parent"
         android:orientation="vertical">
 
-        <RadioButton
-            android:id="@+id/storage_wizard_init_external_title"
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/suw_description_margin_top"
-            android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-            android:textColor="?android:attr/textColorPrimary"
-            android:text="@string/storage_wizard_init_external_title" />
-        <TextView
-            android:id="@+id/storage_wizard_init_external_summary"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Body1"
-            android:textColor="?android:attr/textColorSecondary"
-            android:text="@string/storage_wizard_init_external_summary" />
+            android:orientation="horizontal"
+            android:gravity="center_vertical">
+            <ImageView
+                android:layout_width="144dp"
+                android:layout_height="144dp"
+                android:scaleType="centerInside"
+                android:src="@drawable/ic_storage_wizard_internal" />
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_marginStart="@dimen/suw_glif_margin_sides"
+                android:orientation="vertical">
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="@dimen/suw_description_margin_bottom"
+                    android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+                    android:text="@string/storage_wizard_init_v2_internal_title" />
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="@dimen/suw_description_margin_bottom"
+                    android:textColor="?android:attr/textColorSecondary"
+                    android:text="@string/storage_wizard_init_v2_internal_summary" />
+                <Button
+                    android:id="@+id/storage_wizard_init_internal"
+                    style="@style/SuwGlifButton.Primary"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/storage_wizard_init_v2_internal_action"
+                    android:onClick="onNavigateInternal" />
+            </LinearLayout>
+        </LinearLayout>
 
-        <RadioButton
-            android:id="@+id/storage_wizard_init_internal_title"
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/suw_description_margin_top"
-            android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-            android:textColor="?android:attr/textColorPrimary"
-            android:text="@string/storage_wizard_init_internal_title" />
-        <TextView
-            android:id="@+id/storage_wizard_init_internal_summary"
+            android:orientation="horizontal"
+            android:gravity="center_vertical">
+            <View
+                android:layout_width="0dp"
+                android:layout_height="1dp"
+                android:layout_weight="1"
+                android:background="@android:color/black"
+                android:backgroundTint="?android:attr/textColorTertiary" />
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:text="@string/storage_wizard_init_v2_or"
+                android:textColor="?android:attr/textColorTertiary"
+                android:textAllCaps="true" />
+            <View
+                android:layout_width="0dp"
+                android:layout_height="1dp"
+                android:layout_weight="1"
+                android:background="@android:color/black"
+                android:backgroundTint="?android:attr/textColorTertiary" />
+        </LinearLayout>
+
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Body1"
-            android:textColor="?android:attr/textColorSecondary"
-            android:text="@string/storage_wizard_init_internal_summary" />
+            android:layout_marginTop="@dimen/suw_description_margin_top"
+            android:orientation="horizontal"
+            android:gravity="center_vertical">
+            <ImageView
+                android:layout_width="144dp"
+                android:layout_height="144dp"
+                android:scaleType="centerInside"
+                android:src="@drawable/ic_storage_wizard_external" />
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_marginStart="@dimen/suw_glif_margin_sides"
+                android:orientation="vertical">
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="@dimen/suw_description_margin_bottom"
+                    android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+                    android:text="@string/storage_wizard_init_v2_external_title" />
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="@dimen/suw_description_margin_bottom"
+                    android:textColor="?android:attr/textColorSecondary"
+                    android:text="@string/storage_wizard_init_v2_external_summary" />
+                <Button
+                    android:id="@+id/storage_wizard_init_external"
+                    style="@style/SuwGlifButton.Primary"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/storage_wizard_init_v2_external_action"
+                    android:onClick="onNavigateExternal" />
+            </LinearLayout>
+        </LinearLayout>
 
     </LinearLayout>
 
diff --git a/res/layout/storage_wizard_migrate.xml b/res/layout/storage_wizard_migrate.xml
deleted file mode 100644
index a1c1168..0000000
--- a/res/layout/storage_wizard_migrate.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<com.android.setupwizardlib.GlifLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/setup_wizard_layout"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    app:suwFooter="@layout/storage_wizard_footer">
-
-    <LinearLayout
-        style="@style/SuwContentFrame"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical">
-
-        <TextView
-            android:id="@+id/storage_wizard_body"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/suw_description_margin_top"
-            android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Body1"
-            android:textColor="?android:attr/textColorPrimary" />
-
-        <RadioButton
-            android:id="@+id/storage_wizard_migrate_now"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/suw_description_margin_top"
-            android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-            android:textColor="?android:attr/textColorPrimary"
-            android:text="@string/storage_wizard_migrate_now" />
-        <RadioButton
-            android:id="@+id/storage_wizard_migrate_later"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="8dp"
-            android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-            android:textColor="?android:attr/textColorPrimary"
-            android:text="@string/storage_wizard_migrate_later" />
-
-    </LinearLayout>
-
-</com.android.setupwizardlib.GlifLayout>
diff --git a/res/layout/storage_wizard_progress.xml b/res/layout/storage_wizard_progress.xml
index dbeaf66..0b38475 100644
--- a/res/layout/storage_wizard_progress.xml
+++ b/res/layout/storage_wizard_progress.xml
@@ -40,7 +40,6 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Body1"
             android:textColor="?android:attr/textColorSecondary" />
 
         <TextView
@@ -49,8 +48,14 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/suw_description_margin_top"
             android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Body1"
-            android:textColor="?android:attr/textColorPrimary" />
+            android:textColor="?android:attr/textColorPrimary"
+            android:visibility="gone" />
+
+        <FrameLayout
+            android:id="@+id/storage_wizard_aux"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone" />
 
     </LinearLayout>
 
diff --git a/res/layout/storage_wizard_ready.xml b/res/layout/storage_wizard_ready.xml
index 043b89f..a9e4ddf 100644
--- a/res/layout/storage_wizard_ready.xml
+++ b/res/layout/storage_wizard_ready.xml
@@ -34,7 +34,6 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/suw_description_margin_top"
             android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
-            android:textAppearance="@android:style/TextAppearance.Material.Body1"
             android:textColor="?android:attr/textColorPrimary" />
 
     </LinearLayout>
diff --git a/res/layout/suggestion_tile_with_button.xml b/res/layout/suggestion_tile_with_button.xml
index a901a48..cff0566 100644
--- a/res/layout/suggestion_tile_with_button.xml
+++ b/res/layout/suggestion_tile_with_button.xml
@@ -86,15 +86,18 @@
             android:singleLine="true"
             android:textAppearance="@style/TextAppearance.SuggestionSummary" />
 
-        <Button
-            android:id="@android:id/primary"
-            style="@style/ActionPrimaryButton"
-            android:layout_gravity="center"
+        <FrameLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginTop="16dp"
-            android:layout_marginBottom="18dp"
-            android:text="@string/suggestion_button_text" />
+            style="@style/SuggestionCardButton">
+            <Button
+                android:id="@android:id/primary"
+                style="@style/ActionPrimaryButton"
+                android:layout_gravity="center"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/suggestion_button_text" />
+        </FrameLayout>
 
     </LinearLayout>
 
diff --git a/res/layout/video_preference.xml b/res/layout/video_preference.xml
index 9ab52ae..55bc7a5 100644
--- a/res/layout/video_preference.xml
+++ b/res/layout/video_preference.xml
@@ -23,11 +23,11 @@
     android:clipToPadding="false"
     android:gravity="center"
     android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
     android:orientation="horizontal">
 
     <com.android.settings.widget.AspectRatioFrameLayout
-        android:layout_width="240dp"
+        android:id="@+id/video_container"
+        android:layout_width="wrap_content"
         android:layout_height="240dp"
         android:padding="@dimen/gesture_animation_padding">
 
diff --git a/res/layout/zen_onboarding.xml b/res/layout/zen_onboarding.xml
new file mode 100644
index 0000000..05b38f2
--- /dev/null
+++ b/res/layout/zen_onboarding.xml
@@ -0,0 +1,167 @@
+<?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.
+-->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:padding="20dp">
+
+    <ImageView
+        android:id="@+id/header_icon"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_alignParentTop="true"
+        android:layout_centerHorizontal="true"
+        android:src="@drawable/ic_zen"
+        android:tint="?android:attr/colorAccent"/>
+
+    <TextView
+        android:id="@+id/header"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/header_icon"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="12dp"
+        android:text="@string/zen_onboarding_dnd_visual_disturbances_header"
+        android:textAppearance="@android:style/TextAppearance.Material.Headline" />
+
+    <TextView
+        android:id="@+id/feature_description"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/header"
+        android:layout_centerHorizontal="true"
+        android:textAlignment="center"
+        android:layout_marginTop="14dp"
+        android:textAppearance="?android:attr/textAppearanceListItem"
+        android:text="@string/zen_onboarding_dnd_visual_disturbances_description" />
+
+    <LinearLayout
+        android:id="@+id/screen_off"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/feature_description"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="35dp"
+        android:orientation="horizontal">
+
+        <CheckBox
+            android:id="@+id/screen_off_option"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingHorizontal="8dp"
+            android:onClick="logClick" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <TextView
+                android:id="@+id/screen_off_title"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/zen_onboarding_screen_off_title"
+                android:textAppearance="?android:attr/textAppearanceListItem" />
+
+            <TextView
+                android:id="@+id/screen_off_summary"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/zen_onboarding_screen_off_summary" />
+        </LinearLayout>
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/screen_on"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/screen_off"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="10dp"
+        android:orientation="horizontal">
+
+        <CheckBox
+            android:id="@+id/screen_on_option"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingHorizontal="8dp"
+            android:onClick="logClick" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <TextView
+                android:id="@+id/screen_on_title"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/zen_onboarding_screen_off_title"
+                android:textAppearance="?android:attr/textAppearanceListItem" />
+
+            <TextView
+                android:id="@+id/screen_on_summary"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/zen_onboarding_screen_on_summary" />
+        </LinearLayout>
+
+    </LinearLayout>
+
+    <TextView
+        android:id="@+id/further_customize"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/screen_on"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="20dp"
+        android:textAppearance="?android:attr/textAppearanceListItem"
+        android:text="@string/zen_onboarding_more_options" />
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/further_customize"
+        android:layout_marginTop="35dp"
+        android:id="@+id/buttons">
+
+        <TextView
+            android:id="@+id/settings"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentStart="true"
+            android:layout_weight="1"
+            android:layout_centerInParent="true"
+            android:text="@string/zen_onboarding_settings"
+            android:textAppearance="?android:attr/textAppearanceListItem"
+            android:textColor="?android:attr/colorControlActivated"
+            android:onClick="launchSettings" />
+
+        <Button
+            android:id="@+id/ok"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentEnd="true"
+            android:layout_weight="1"
+            android:layout_centerInParent="true"
+            android:text="@string/zen_onboarding_ok"
+            style="@style/ActionPrimaryButton"
+            android:onClick="save" />
+    </RelativeLayout>
+</RelativeLayout>
\ No newline at end of file
diff --git a/res/raw/auto_awesome_battery.mp4 b/res/raw/auto_awesome_battery.mp4
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/raw/auto_awesome_battery.mp4
diff --git a/res/values-ru/arrays.xml b/res/values-ru/arrays.xml
index f29ab53..df2fbff 100644
--- a/res/values-ru/arrays.xml
+++ b/res/values-ru/arrays.xml
@@ -489,7 +489,7 @@
   <string-array name="wifi_metered_entries">
     <item msgid="5200910605264415911">"Определять автоматически"</item>
     <item msgid="8745603368609022803">"Лимитное"</item>
-    <item msgid="2266114985518865625">"Безлимитное"</item>
+    <item msgid="2266114985518865625">"Без тарификации трафика"</item>
   </string-array>
     <!-- no translation found for wifi_hidden_entries:0 (234221371123852300) -->
     <!-- no translation found for wifi_hidden_entries:1 (3863157480502955888) -->
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 406cac2..6a052d2 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -318,6 +318,10 @@
     <dimen name="suggestion_card_inner_margin">12dp</dimen>
     <dimen name="suggestion_card_padding_bottom_one_card">16dp</dimen>
     <dimen name="suggestion_card_corner_radius">2dp</dimen>
+    <dimen name="suggestion_card_icon_side_margin">12dp</dimen>
+    <dimen name="suggestion_card_button_side_margin">8dp</dimen>
+    <dimen name="suggestion_card_button_top_margin">16dp</dimen>
+    <dimen name="suggestion_card_button_bottom_margin">18dp</dimen>
 
     <!-- Padding for the reset screens -->
     <dimen name="reset_checkbox_padding_end">8dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 61c1093..34cac8a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2162,6 +2162,8 @@
     <string name="wifi_hotspot_tethering_on_subtext" product="default">Sharing this phone\u2019s internet connection via hotspot</string>
     <!-- Summary text when hotspot is on for local-only -->
     <string name="wifi_hotspot_on_local_only_subtext">App is sharing content. To share internet connection, turn hotspot off, then on</string>
+    <!-- Summary text when no password is set [CHAR LIMIT=60] -->
+    <string name="wifi_hotspot_no_password_subtext">No password set</string>
 
     <!-- Wifi hotspot settings -->
     <!-- Label for Wifi hotspot name. -->
@@ -6614,6 +6616,8 @@
 
     <!-- Help URL, WiFi [DO NOT TRANSLATE] -->
     <string name="help_url_wifi" translatable="false"></string>
+    <!-- Help URL, WiFi Direct [DO NOT TRANSLATE] -->
+    <string name="help_url_wifi_p2p" translatable="false"></string>
     <!-- Help URL, Bluetooth [DO NOT TRANSLATE] -->
     <string name="help_url_bluetooth" translatable="false"></string>
     <!-- Help URL, Data usage [DO NOT TRANSLATE] -->
@@ -6918,8 +6922,6 @@
     <string name="search_results_title">Settings</string>
     <!-- Text used as a search hint into the search box -->
     <string name="search_menu">Search settings</string>
-    <!-- Text used as a search hint into the search box -->
-    <string name="query_hint_text">Search settings</string>
     <!-- Search breadcrumb connector symbol -->
     <string name="search_breadcrumb_connector" translatable="false">
         <xliff:g name="first_item">%1$s</xliff:g> > <xliff:g name="second_item">%2$s</xliff:g>
@@ -7218,9 +7220,11 @@
     <string name="zen_mode_visual_signals_settings_subtitle">Allow visual signals</string>
 
     <!-- Do not disturb: what to block title [CHAR LIMIT = 60] -->
-    <string name="zen_mode_what_to_block_title">What to block</string>
+    <string name="zen_mode_what_to_block_title">Block visual disturbances</string>
     <!-- Do not disturb: what to block > effects title [CHAR LIMIT = 60] -->
-    <string name="zen_mode_block_effects_title">When notifications arrive</string>
+    <string name="zen_mode_block_effects_screen_on">When the screen is on</string>
+    <!-- Do not disturb: what to block > effects title [CHAR LIMIT = 60] -->
+    <string name="zen_mode_block_effects_screen_off">When the screen is off</string>
     <!-- Do not disturb: what to block option [CHAR LIMIT=NONE] -->
     <string name="zen_mode_block_effect_sound">Mute sound and vibration</string>
     <!-- Do not disturb: what to block option [CHAR LIMIT=NONE] -->
@@ -7238,6 +7242,12 @@
     <!-- Do not disturb: what to block option [CHAR LIMIT=NONE] -->
     <string name="zen_mode_block_effect_list">Hide from notification list</string>
 
+    <!-- Do not disturb: what to block summary, none -->
+    <string name="zen_mode_block_effect_summary_none">Never</string>
+    <!-- Do not disturb: what to block summary, screen off -->
+    <string name="zen_mode_block_effect_summary_screen_off">When screen is off</string>
+    <!-- Do not disturb: what to block summary, screen on -->
+    <string name="zen_mode_block_effect_summary_screen_on">When screen is on</string>
     <!-- Do not disturb: what to block summary, only sound and vibration -->
     <string name="zen_mode_block_effect_summary_sound">Sound and vibration</string>
     <!-- Do not disturb: what to block summary, sound vibration and some visual signals-->
@@ -7245,6 +7255,8 @@
     <!-- Do not disturb: what to block summary, all effects -->
     <string name="zen_mode_block_effect_summary_all">Sound, vibration, and visual signs of notifications</string>
 
+    <string name="zen_mode_blocked_effects_footer">Notifications needed for basic phone activity and status will never be hidden</string>
+
     <!--  Do not disturb: Zen mode no sounds are exceptions to bypass do not disturb-->
     <string name="zen_mode_no_exceptions">None</string>
     <!--  Do not disturb: Zen mode catch all "other" sounds can bypass do not disturb -->
@@ -7313,6 +7325,16 @@
         <item quantity="other"><xliff:g id="on_count" example="3">%d</xliff:g> rules can turn on automatically</item>
     </plurals>
 
+    <string name="zen_onboarding_ok">Ok</string>
+    <string name="zen_onboarding_settings">Settings</string>
+    <string name="zen_onboarding_more_options">You can further customize this in Settings.</string>
+    <string name="zen_onboarding_screen_on_title">Block when the screen is on</string>
+    <string name="zen_onboarding_screen_off_title">Block when the screen is off</string>
+    <string name="zen_onboarding_dnd_visual_disturbances_description">Do Not Disturb can do more than block unwanted sounds - it can block visuals too. This may be helpful if you\'re trying to sleep, focus, or limit time spent on your phone.</string>
+    <string name="zen_onboarding_dnd_visual_disturbances_header">Block sounds and visuals</string>
+    <string name="zen_onboarding_screen_off_summary">Don\'t turn on the screen or show notifications in the ambient display</string>
+    <string name="zen_onboarding_screen_on_summary">Don\'t show notifications at all, except for basic phone activity and status</string>
+
     <!-- Work Sounds: Work sound settings section header.  [CHAR LIMIT=50] -->
     <string name="sound_work_settings">Work profile sounds</string>
 
@@ -7503,9 +7525,9 @@
     <string name="default_notification_assistant">Notification assistant</string>
 
     <!-- app summary of notification app list screen [CHAR LIMIT=100] -->
-    <string name="notifications_sent_daily">~<xliff:g id="number">%1$s</xliff:g> sent daily</string>
+    <string name="notifications_sent_daily">~<xliff:g id="number">%1$s</xliff:g> per day</string>
     <!-- app summary of notification app list screen [CHAR LIMIT=100] -->
-    <string name="notifications_sent_weekly">~<xliff:g id="number">%1$s</xliff:g> sent weekly</string>
+    <string name="notifications_sent_weekly">~<xliff:g id="number">%1$s</xliff:g> per week</string>
     <!-- app summary of notification app list screen [CHAR LIMIT=100] -->
     <string name="notifications_sent_never">Never</string>
 
@@ -9395,6 +9417,15 @@
     <!-- Title for settings suggestion for double twist for camera [CHAR LIMIT=60] -->
     <string name="double_twist_for_camera_suggestion_title">Take selfies faster</string>
 
+    <!-- Title text for swipe up to switch apps [CHAR LIMIT=60] -->
+    <string name="swipe_up_to_switch_apps_title">Swipe up on Home button</string>
+    <!-- Summary text for swipe up to switch apps  [CHAR LIMIT=250] -->
+    <string name="swipe_up_to_switch_apps_summary">To switch apps, swipe up on the Home button. Swipe up again to see all apps. Works from any screen. You’ll no longer have an Overview button on the bottom right of your screen.</string>
+    <!-- Title for settings suggestion for swipe up to switch apps [CHAR LIMIT=60] -->
+    <string name="swipe_up_to_switch_apps_suggestion_title">Try the new Home button</string>
+    <!-- Summary for settings suggestion for swipe up to switch apps [CHAR LIMIT=60] -->
+    <string name="swipe_up_to_switch_apps_suggestion_summary">Turn on the new gesture to switch apps</string>
+
     <!-- Preference and settings suggestion title text for ambient display double tap (phone) [CHAR LIMIT=60]-->
     <string name="ambient_display_title" product="default">Double-tap to check phone</string>
     <!-- Preference and settings suggestion title text for ambient display double tap (tablet) [CHAR LIMIT=60]-->
@@ -9590,8 +9621,8 @@
     <string name="do_disclosure_with_name">This device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%s</xliff:g>.</string>
     <!-- Message indicating that the device is enterprise-managed: Space that separates the main text and the "learn more" link that follows it. [CHAR LIMIT=NONE] -->
     <string name="do_disclosure_learn_more_separator">" "</string>
-    <!-- Message indicating that the device is enterprise-managed: Link to learn more about what a Device Owner app can do [CHAR LIMIT=NONE] -->
-    <string name="do_disclosure_learn_more">Learn more</string>
+    <!-- Button label to allow the user to view additional information [CHAR LIMIT=NONE BACKUP_MESSAGE_ID=2416766240581561009] -->
+    <string name="learn_more">Learn more</string>
 
     <!-- Strings for displaying which applications were set as default for specific actions. -->
     <!-- Title for the apps that have been set as default handlers of camera-related intents. [CHAR LIMIT=30] -->
@@ -9814,6 +9845,9 @@
     <!-- Title for media output settings -->
     <string name="media_output_title">Play media to</string>
 
+    <!-- Summary for media output default settings. (this device) [CHAR LIMIT=30] -->
+    <string name="media_output_default_summary">This device</string>
+
     <!-- Summary for media output settings. (phone) -->
     <string name="media_output_summary" product="default">Phone</string>
 
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 86375fa..23ec207 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -329,6 +329,16 @@
     <style name="SuggestionCardIcon">
         <item name="android:layout_centerHorizontal">false</item>
         <item name="android:layout_alignParentStart">true</item>
+        <item name="android:layout_marginStart">@dimen/suggestion_card_icon_side_margin</item>
+        <item name="android:layout_marginEnd">@dimen/suggestion_card_icon_side_margin</item>
+    </style>
+
+    <style name="SuggestionCardButton">
+        <item name="android:layout_gravity">start</item>
+        <item name="android:layout_marginStart">@dimen/suggestion_card_button_side_margin</item>
+        <item name="android:layout_marginEnd">@dimen/suggestion_card_button_side_margin</item>
+        <item name="android:layout_marginTop">@dimen/suggestion_card_button_top_margin</item>
+        <item name="android:layout_marginBottom">@dimen/suggestion_card_button_bottom_margin</item>
     </style>
 
     <style name="TextAppearance.SuggestionTitle"
@@ -364,9 +374,6 @@
         <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
 
-    <style name="SetupWizardStorageStyle" parent="@style/SuwThemeGlif.Light">
-    </style>
-
     <style name="PreviewPagerPageIndicator">
         <item name="dotGap">8dp</item>
         <item name="pageIndicatorColor">?android:attr/colorControlNormal</item>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 485b009..762b434 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -265,7 +265,7 @@
         <item name="android:backgroundDimEnabled">false</item>
     </style>
 
-    <style name="Theme.ActionBar" parent="@android:style/Widget.Material.ActionBar.Solid">
+    <style name="Theme.ActionBar" parent="@android:style/Widget.DeviceDefault.Light.ActionBar.Solid">
         <item name="android:contentInsetStart">@dimen/actionbar_contentInsetStart</item>
     </style>
 
diff --git a/res/xml/ambient_display_settings.xml b/res/xml/ambient_display_settings.xml
index a23aeaa..4688a80 100644
--- a/res/xml/ambient_display_settings.xml
+++ b/res/xml/ambient_display_settings.xml
@@ -35,12 +35,14 @@
         <Preference
             android:key="ambient_display_double_tap"
             android:title="@string/ambient_display_title"
-            android:fragment="com.android.settings.gestures.DoubleTapScreenSettings" />
+            android:fragment="com.android.settings.gestures.DoubleTapScreenSettings"
+            settings:controller="com.android.settings.gestures.DoubleTapScreenPreferenceController" />
 
         <Preference
             android:key="ambient_display_pick_up"
             android:title="@string/ambient_display_pickup_title"
-            android:fragment="com.android.settings.gestures.PickupGestureSettings" />
+            android:fragment="com.android.settings.gestures.PickupGestureSettings"
+            settings:controller="com.android.settings.gestures.PickupGesturePreferenceController" />
 
     </PreferenceCategory>
 
@@ -52,7 +54,7 @@
             android:key="ambient_display_notification"
             android:title="@string/doze_title"
             android:summary="@string/doze_summary"
-            settings:controller="com.android.settings.display.AmbientDisplayNotificationsPreferenceController"/>
+            settings:controller="com.android.settings.display.AmbientDisplayNotificationsPreferenceController" />
 
     </PreferenceCategory>
 
diff --git a/res/xml/assist_gesture_settings.xml b/res/xml/assist_gesture_settings.xml
index 53b6526..b2ceac9 100644
--- a/res/xml/assist_gesture_settings.xml
+++ b/res/xml/assist_gesture_settings.xml
@@ -29,6 +29,7 @@
     <SwitchPreference
         android:key="gesture_assist"
         android:title="@string/assist_gesture_title"
-        app:keywords="@string/keywords_assist_gesture_launch" />
+        app:keywords="@string/keywords_assist_gesture_launch"
+        app:controller="com.android.settings.gestures.AssistGestureSettingsPreferenceController" />
 
 </PreferenceScreen>
diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml
index 73c1d6f..612f5e7 100644
--- a/res/xml/configure_notification_settings.xml
+++ b/res/xml/configure_notification_settings.xml
@@ -46,7 +46,8 @@
     <Preference
         android:key="gesture_swipe_down_fingerprint_notifications"
         android:title="@string/fingerprint_swipe_for_notifications_title"
-        android:fragment="com.android.settings.gestures.SwipeToNotificationSettings" />
+        android:fragment="com.android.settings.gestures.SwipeToNotificationSettings"
+        settings:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController" />
 
     <com.android.settingslib.RestrictedPreference
         android:key="zen_mode_notifications"
diff --git a/res/xml/double_tap_power_settings.xml b/res/xml/double_tap_power_settings.xml
index 26d0415..6614899 100644
--- a/res/xml/double_tap_power_settings.xml
+++ b/res/xml/double_tap_power_settings.xml
@@ -30,6 +30,7 @@
         android:key="gesture_double_tap_power"
         android:title="@string/double_tap_power_for_camera_title"
         android:summary="@string/double_tap_power_for_camera_summary"
-        app:keywords="@string/keywords_gesture" />
+        app:keywords="@string/keywords_gesture"
+        app:controller="com.android.settings.gestures.DoubleTapPowerPreferenceController" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/double_tap_screen_settings.xml b/res/xml/double_tap_screen_settings.xml
index d40602e..4d2e168 100644
--- a/res/xml/double_tap_screen_settings.xml
+++ b/res/xml/double_tap_screen_settings.xml
@@ -30,6 +30,7 @@
         android:key="gesture_double_tap_screen"
         android:title="@string/ambient_display_title"
         android:summary="@string/ambient_display_summary"
-        app:keywords="@string/keywords_gesture" />
+        app:keywords="@string/keywords_gesture"
+        app:controller="com.android.settings.gestures.DoubleTapScreenPreferenceController" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/double_twist_gesture_settings.xml b/res/xml/double_twist_gesture_settings.xml
index a2af1e4..1da862d 100644
--- a/res/xml/double_twist_gesture_settings.xml
+++ b/res/xml/double_twist_gesture_settings.xml
@@ -30,6 +30,7 @@
         android:key="gesture_double_twist"
         android:title="@string/double_twist_for_camera_mode_title"
         android:summary="@string/double_twist_for_camera_mode_summary"
-        app:keywords="@string/keywords_gesture" />
+        app:keywords="@string/keywords_gesture"
+        app:controller="com.android.settings.gestures.DoubleTwistPreferenceController" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml
index 7083a31..0eaa2a6 100644
--- a/res/xml/gestures.xml
+++ b/res/xml/gestures.xml
@@ -17,38 +17,45 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="gesture_settings_screen"
-    android:title="@string/gesture_preference_title" >
+    android:title="@string/gesture_preference_title">
 
     <Preference
         android:key="gesture_assist_input_summary"
         android:title="@string/assist_gesture_title"
-        android:fragment="com.android.settings.gestures.AssistGestureSettings" />
+        android:fragment="com.android.settings.gestures.AssistGestureSettings"
+        settings:controller="com.android.settings.gestures.AssistGestureSettingsPreferenceController" />
 
     <Preference
         android:key="gesture_swipe_down_fingerprint_input_summary"
         android:title="@string/fingerprint_swipe_for_notifications_title"
-        android:fragment="com.android.settings.gestures.SwipeToNotificationSettings" />
+        android:fragment="com.android.settings.gestures.SwipeToNotificationSettings"
+        settings:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController" />
 
     <Preference
         android:key="gesture_double_tap_power_input_summary"
         android:title="@string/double_tap_power_for_camera_title"
-        android:fragment="com.android.settings.gestures.DoubleTapPowerSettings" />
+        android:fragment="com.android.settings.gestures.DoubleTapPowerSettings"
+        settings:controller="com.android.settings.gestures.DoubleTapPowerPreferenceController" />
 
     <Preference
         android:key="gesture_double_twist_input_summary"
         android:title="@string/double_twist_for_camera_mode_title"
-        android:fragment="com.android.settings.gestures.DoubleTwistGestureSettings" />
+        android:fragment="com.android.settings.gestures.DoubleTwistGestureSettings"
+        settings:controller="com.android.settings.gestures.DoubleTwistPreferenceController" />
 
     <Preference
         android:key="gesture_double_tap_screen_input_summary"
         android:title="@string/ambient_display_title"
-        android:fragment="com.android.settings.gestures.DoubleTapScreenSettings" />
+        android:fragment="com.android.settings.gestures.DoubleTapScreenSettings"
+        settings:controller="com.android.settings.gestures.DoubleTapScreenPreferenceController" />
 
     <Preference
         android:key="gesture_pick_up_input_summary"
         android:title="@string/ambient_display_pickup_title"
-        android:fragment="com.android.settings.gestures.PickupGestureSettings" />
+        android:fragment="com.android.settings.gestures.PickupGestureSettings"
+        settings:controller="com.android.settings.gestures.PickupGesturePreferenceController" />
 
     <Preference
         android:key="gesture_prevent_ringing_summary"
diff --git a/res/xml/manage_assist.xml b/res/xml/manage_assist.xml
index 047f1ca..dec8bc3 100644
--- a/res/xml/manage_assist.xml
+++ b/res/xml/manage_assist.xml
@@ -17,6 +17,7 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="manage_assist_screen"
     android:title="@string/assist_and_voice_input_title">
 
@@ -24,31 +25,32 @@
         android:key="default_assist"
         android:title="@string/default_assist_title"
         android:summary="@string/summary_placeholder"
-        android:fragment="com.android.settings.applications.assist.DefaultAssistPicker"/>
+        android:fragment="com.android.settings.applications.assist.DefaultAssistPicker" />
 
     <Preference
         android:key="gesture_assist_application"
         android:title="@string/assist_gesture_title"
-        android:fragment="com.android.settings.gestures.AssistGestureSettings"/>
+        android:fragment="com.android.settings.gestures.AssistGestureSettings"
+        settings:controller="com.android.settings.gestures.AssistGestureSettingsPreferenceController" />
 
     <SwitchPreference
         android:key="context"
         android:title="@string/assist_access_context_title"
-        android:summary="@string/assist_access_context_summary"/>
+        android:summary="@string/assist_access_context_summary" />
 
     <SwitchPreference
         android:key="screenshot"
         android:title="@string/assist_access_screenshot_title"
-        android:summary="@string/assist_access_screenshot_summary"/>
+        android:summary="@string/assist_access_screenshot_summary" />
 
     <SwitchPreference
         android:key="flash"
         android:title="@string/assist_flash_title"
-        android:summary="@string/assist_flash_summary"/>
+        android:summary="@string/assist_flash_summary" />
 
     <com.android.settings.widget.GearPreference
         android:key="voice_input_settings"
         android:title="@string/voice_input_settings_title"
-        android:fragment="com.android.settings.applications.assist.DefaultVoiceInputPicker"/>
+        android:fragment="com.android.settings.applications.assist.DefaultVoiceInputPicker" />
 
 </PreferenceScreen>
diff --git a/res/xml/pick_up_gesture_settings.xml b/res/xml/pick_up_gesture_settings.xml
index e1414cd..ccf2d8a 100644
--- a/res/xml/pick_up_gesture_settings.xml
+++ b/res/xml/pick_up_gesture_settings.xml
@@ -30,6 +30,7 @@
         android:key="gesture_pick_up"
         android:title="@string/ambient_display_pickup_title"
         android:summary="@string/ambient_display_pickup_summary"
-        app:keywords="@string/keywords_gesture" />
+        app:keywords="@string/keywords_gesture"
+        app:controller="com.android.settings.gestures.PickupGesturePreferenceController" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/smart_battery_detail.xml b/res/xml/smart_battery_detail.xml
index e7fb9f7..e1246ed 100644
--- a/res/xml/smart_battery_detail.xml
+++ b/res/xml/smart_battery_detail.xml
@@ -21,18 +21,16 @@
     android:key="smart_battery_detail"
     android:title="@string/smart_battery_manager_title">
 
-    <!-- TODO(b/71722498): Add header back, otherwise also remove smart_battery_header
-    <com.android.settings.applications.LayoutPreference
-        android:key="header_view"
-        android:layout="@layout/smart_battery_header"
-        android:selectable="false"
-        android:order="-10000"/>
-     -->
+    <com.android.settings.widget.VideoPreference
+        android:key="auto_awesome_battery"
+        settings:animation="@raw/auto_awesome_battery"
+        settings:preview="@drawable/auto_awesome_battery"/>
 
     <SwitchPreference
         android:key="smart_battery"
         android:title="@string/smart_battery_title"
-        android:summary="@string/smart_battery_summary"/>
+        android:summary="@string/smart_battery_summary"
+        settings:allowDividerAbove="true"/>
 
     <SwitchPreference
         android:key="auto_restriction"
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index 23936a7..7fd3709 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -27,6 +27,7 @@
         android:key="media_volume"
         android:icon="@*android:drawable/ic_audio_media"
         android:title="@string/media_volume_option_title"
+        settings:controller="com.android.settings.notification.MediaVolumePreferenceController"
         android:order="-170"/>
 
     <!-- Alarm volume -->
@@ -34,6 +35,7 @@
         android:key="alarm_volume"
         android:icon="@*android:drawable/ic_audio_alarm"
         android:title="@string/alarm_volume_option_title"
+        settings:controller="com.android.settings.notification.AlarmVolumePreferenceController"
         android:order="-160"/>
 
     <!-- Ring volume -->
@@ -41,6 +43,7 @@
         android:key="ring_volume"
         android:icon="@*android:drawable/ic_audio_ring_notif"
         android:title="@string/ring_volume_option_title"
+        settings:controller="com.android.settings.notification.RingVolumePreferenceController"
         android:order="-150"/>
 
     <!-- Notification volume -->
@@ -48,6 +51,7 @@
         android:key="notification_volume"
         android:icon="@*android:drawable/ic_audio_ring_notif"
         android:title="@string/notification_volume_option_title"
+        settings:controller="com.android.settings.notification.NotificationVolumePreferenceController"
         android:order="-140"/>
 
     <!-- Also vibrate for calls -->
diff --git a/res/xml/swipe_to_notification_settings.xml b/res/xml/swipe_to_notification_settings.xml
index 5b53c10..04dc0c7 100644
--- a/res/xml/swipe_to_notification_settings.xml
+++ b/res/xml/swipe_to_notification_settings.xml
@@ -23,12 +23,13 @@
     <com.android.settings.widget.VideoPreference
         android:key="gesture_swipe_down_fingerprint_video"
         app:animation="@raw/gesture_fingerprint_swipe"
-        app:preview="@drawable/gesture_fingerprint_swipe"/>
+        app:preview="@drawable/gesture_fingerprint_swipe" />
 
     <SwitchPreference
         android:key="gesture_swipe_down_fingerprint"
         android:title="@string/fingerprint_swipe_for_notifications_title"
         android:summary="@string/fingerprint_swipe_for_notifications_summary"
-        app:keywords="@string/keywords_gesture"/>
+        app:keywords="@string/keywords_gesture"
+        app:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/usb_details_fragment.xml b/res/xml/usb_details_fragment.xml
index 5c1efcf..4efad6d 100644
--- a/res/xml/usb_details_fragment.xml
+++ b/res/xml/usb_details_fragment.xml
@@ -36,4 +36,9 @@
     <PreferenceCategory
         android:key="usb_details_power_role"/>
 
+    <!-- Empty category for spacing -->
+    <PreferenceCategory
+        android:key="usb_details_space"
+        settings:allowDividerAbove="false"/>
+
 </PreferenceScreen>
diff --git a/res/xml/zen_mode_block_settings.xml b/res/xml/zen_mode_block_settings.xml
index 595e2ca..63dbd47 100644
--- a/res/xml/zen_mode_block_settings.xml
+++ b/res/xml/zen_mode_block_settings.xml
@@ -18,17 +18,11 @@
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:key="zen_mode_block_settings_page"
-    android:title="@string/zen_mode_behavior_settings_title">
-
-    <!-- sound vibration -->
-    <CheckBoxPreference
-        android:key="zen_effect_sound"
-        android:title="@string/zen_mode_block_effect_sound"
-        android:enabled="false" />
+    android:title="@string/zen_mode_what_to_block_title">
 
    <PreferenceCategory
-       android:title="@string/zen_mode_block_effects_title"
-       android:key="zen_mode_block_vis_effects">
+       android:title="@string/zen_mode_block_effects_screen_off"
+       android:key="zen_mode_block_screen_off">
 
        <CheckBoxPreference
            android:key="zen_effect_intent"
@@ -39,20 +33,24 @@
            android:title="@string/zen_mode_block_effect_light" />
 
        <CheckBoxPreference
-           android:key="zen_effect_peek"
-           android:title="@string/zen_mode_block_effect_peek" />
+           android:key="zen_effect_ambient"
+           android:title="@string/zen_mode_block_effect_ambient" />
 
-       <CheckBoxPreference
-           android:key="zen_effect_status"
-           android:title="@string/zen_mode_block_effect_status" />
-
+   </PreferenceCategory>
+    <PreferenceCategory
+        android:title="@string/zen_mode_block_effects_screen_on"
+        android:key="zen_mode_block_screen_on">
        <CheckBoxPreference
            android:key="zen_effect_badge"
            android:title="@string/zen_mode_block_effect_badge" />
 
-       <CheckBoxPreference
-           android:key="zen_effect_ambient"
-           android:title="@string/zen_mode_block_effect_ambient" />
+        <CheckBoxPreference
+            android:key="zen_effect_status"
+            android:title="@string/zen_mode_block_effect_status" />
+
+        <CheckBoxPreference
+            android:key="zen_effect_peek"
+            android:title="@string/zen_mode_block_effect_peek" />
 
        <CheckBoxPreference
            android:key="zen_effect_list"
diff --git a/res/xml/zen_mode_settings.xml b/res/xml/zen_mode_settings.xml
index cc9e96c..24ed0b9 100644
--- a/res/xml/zen_mode_settings.xml
+++ b/res/xml/zen_mode_settings.xml
@@ -22,6 +22,12 @@
     android:title="@string/zen_mode_settings_title"
     settings:keywords="@string/keywords_zen_mode_settings">
 
+    <!-- sound vibration -->
+    <CheckBoxPreference
+        android:key="zen_effect_sound"
+        android:title="@string/zen_mode_block_effect_sound"
+        android:enabled="false" />
+
     <!-- What to block (effects) -->
     <Preference
         android:key="zen_mode_block_effects_settings"
diff --git a/src/com/android/settings/SettingsDumpService.java b/src/com/android/settings/SettingsDumpService.java
index 67a8f50..07ea73e 100644
--- a/src/com/android/settings/SettingsDumpService.java
+++ b/src/com/android/settings/SettingsDumpService.java
@@ -15,7 +15,9 @@
 package com.android.settings;
 
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.ConnectivityManager;
@@ -27,9 +29,12 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.applications.ProcStatsData;
+import com.android.settings.fuelgauge.batterytip.AnomalyConfigJobService;
 import com.android.settingslib.net.DataUsageController;
+
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -39,12 +44,20 @@
 import java.io.PrintWriter;
 
 public class SettingsDumpService extends Service {
-    @VisibleForTesting static final String KEY_SERVICE = "service";
-    @VisibleForTesting static final String KEY_STORAGE = "storage";
-    @VisibleForTesting static final String KEY_DATAUSAGE = "datausage";
-    @VisibleForTesting static final String KEY_MEMORY = "memory";
-    @VisibleForTesting static final String KEY_DEFAULT_BROWSER_APP = "default_browser_app";
-    @VisibleForTesting static final Intent BROWSER_INTENT =
+    @VisibleForTesting
+    static final String KEY_SERVICE = "service";
+    @VisibleForTesting
+    static final String KEY_STORAGE = "storage";
+    @VisibleForTesting
+    static final String KEY_DATAUSAGE = "datausage";
+    @VisibleForTesting
+    static final String KEY_MEMORY = "memory";
+    @VisibleForTesting
+    static final String KEY_DEFAULT_BROWSER_APP = "default_browser_app";
+    @VisibleForTesting
+    static final String KEY_ANOMALY_DETECTION = "anomaly_detection";
+    @VisibleForTesting
+    static final Intent BROWSER_INTENT =
             new Intent("android.intent.action.VIEW", Uri.parse("http://"));
 
     @Override
@@ -62,6 +75,7 @@
             dump.put(KEY_DATAUSAGE, dumpDataUsage());
             dump.put(KEY_MEMORY, dumpMemory());
             dump.put(KEY_DEFAULT_BROWSER_APP, dumpDefaultBrowser());
+            dump.put(KEY_ANOMALY_DETECTION, dumpAnomalyDetection());
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -151,4 +165,18 @@
             return resolveInfo.activityInfo.packageName;
         }
     }
+
+    @VisibleForTesting
+    JSONObject dumpAnomalyDetection() throws JSONException {
+        final JSONObject obj = new JSONObject();
+        final SharedPreferences sharedPreferences = getSharedPreferences(
+                AnomalyConfigJobService.PREF_DB,
+                Context.MODE_PRIVATE);
+        final int currentVersion = sharedPreferences.getInt(
+                AnomalyConfigJobService.KEY_ANOMALY_CONFIG_VERSION,
+                0 /* defValue */);
+        obj.put("anomaly_config_version", String.valueOf(currentVersion));
+
+        return obj;
+    }
 }
diff --git a/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
index 05cb46b..44d5b79 100644
--- a/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
@@ -25,20 +25,15 @@
 import android.provider.Settings;
 import android.support.v7.preference.Preference;
 import android.text.TextUtils;
-import android.view.View;
 import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
-import com.android.settingslib.core.AbstractPreferenceController;
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 
 public final class MagnificationPreferenceFragment extends DashboardFragment {
@@ -144,13 +139,14 @@
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
                         boolean enabled) {
-                    if (isApplicable(context.getResources())) {
-                        final SearchIndexableResource sir = new SearchIndexableResource(context);
-                        sir.xmlResId = R.xml.accessibility_magnification_settings;
-                        return Arrays.asList(sir);
-                    } else {
-                        return Collections.emptyList();
-                    }
+                    final SearchIndexableResource sir = new SearchIndexableResource(context);
+                    sir.xmlResId = R.xml.accessibility_magnification_settings;
+                    return Arrays.asList(sir);
+                }
+
+                @Override
+                protected boolean isPageSearchEnabled(Context context) {
+                    return isApplicable(context.getResources());
                 }
 
                 @Override
diff --git a/src/com/android/settings/accounts/ProviderPreference.java b/src/com/android/settings/accounts/ProviderPreference.java
index 81e0221..1143f8d 100644
--- a/src/com/android/settings/accounts/ProviderPreference.java
+++ b/src/com/android/settings/accounts/ProviderPreference.java
@@ -34,7 +34,7 @@
     public ProviderPreference(
             Context context, String accountType, Drawable icon, CharSequence providerName) {
         super(context);
-        setUseSmallIcon(true);
+        setIconSize(ICON_SIZE_MEDIUM);
         mAccountType = accountType;
         setIcon(icon);
         setPersistent(false);
diff --git a/src/com/android/settings/applications/assist/ManageAssist.java b/src/com/android/settings/applications/assist/ManageAssist.java
index f5a3838..82db01f 100644
--- a/src/com/android/settings/applications/assist/ManageAssist.java
+++ b/src/com/android/settings/applications/assist/ManageAssist.java
@@ -61,6 +61,12 @@
     }
 
     @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        use(AssistGestureSettingsPreferenceController.class).setAssistOnly(true);
+    }
+
+    @Override
     public void onResume() {
         super.onResume();
 
@@ -73,8 +79,6 @@
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
         controllers.add(new DefaultAssistPreferenceController(context, "default_assist",
                 true /* showSetting */));
-        controllers.add(new AssistGestureSettingsPreferenceController(context, lifecycle,
-                KEY_ASSIST, true /* assistOnly */));
         controllers.add(new AssistContextPreferenceController(context, lifecycle));
         controllers.add(new AssistScreenshotPreferenceController(context, lifecycle));
         controllers.add(new AssistFlashScreenPreferenceController(context, lifecycle));
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java b/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java
index cc3b3d1..ab81290 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java
@@ -86,11 +86,6 @@
         }
     }
 
-    @Override
-    protected int getRadioButtonPreferenceCustomLayoutResId() {
-        return R.layout.preference_app;
-    }
-
     protected ConfirmationDialogFragment newConfirmationDialogFragment(String selectedKey,
             CharSequence confirmationMessage) {
         final ConfirmationDialogFragment fragment = new ConfirmationDialogFragment();
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java
index 6d4d3b2..226daaa 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.applications.defaultapps;
 
+import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_MEDIUM;
+
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
@@ -29,8 +31,8 @@
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.widget.GearPreference;
-import com.android.settingslib.applications.DefaultAppInfo;
 import com.android.settingslib.TwoTargetPreference;
+import com.android.settingslib.applications.DefaultAppInfo;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.wrapper.PackageManagerWrapper;
 
@@ -59,7 +61,7 @@
             // For use small icon because we are displaying an app preference.
             // We only need to do this for TwoTargetPreference because the other prefs are
             // already using AppPreference so their icon is already normalized.
-            ((TwoTargetPreference) preference).setUseSmallIcon(true);
+            ((TwoTargetPreference) preference).setIconSize(ICON_SIZE_MEDIUM);
         }
         if (!TextUtils.isEmpty(defaultAppLabel)) {
             preference.setSummary(defaultAppLabel);
diff --git a/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java b/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java
index b570204..098cdb4 100644
--- a/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java
+++ b/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java
@@ -19,12 +19,12 @@
 import android.hardware.usb.UsbManager;
 import android.hardware.usb.UsbPort;
 import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
 
 import com.android.settings.R;
 import com.android.settings.connecteddevice.DevicePreferenceCallback;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.widget.GearPreference;
 
 /**
  * Controller to maintain connected usb device
@@ -34,7 +34,7 @@
     private UsbBackend mUsbBackend;
     private DevicePreferenceCallback mDevicePreferenceCallback;
     @VisibleForTesting
-    GearPreference mUsbPreference;
+    Preference mUsbPreference;
     @VisibleForTesting
     UsbConnectionBroadcastReceiver mUsbReceiver;
 
@@ -75,17 +75,17 @@
     }
 
     public void initUsbPreference(Context context) {
-        mUsbPreference = new GearPreference(context, null /* AttributeSet */);
+        mUsbPreference = new Preference(context, null /* AttributeSet */);
         mUsbPreference.setTitle(R.string.usb_pref);
         mUsbPreference.setIcon(R.drawable.ic_usb);
-        mUsbPreference.setSelectable(false);
-        mUsbPreference.setOnGearClickListener((GearPreference p) -> {
+        mUsbPreference.setOnPreferenceClickListener((Preference p) -> {
             // New version - uses a separate screen.
             new SubSettingLauncher(mFragment.getContext())
                     .setDestination(UsbDetailsFragment.class.getName())
                     .setTitle(R.string.device_details_title)
                     .setSourceMetricsCategory(mFragment.getMetricsCategory())
                     .launch();
+            return true;
         });
 
         forceUpdate();
diff --git a/src/com/android/settings/dashboard/conditional/DndCondition.java b/src/com/android/settings/dashboard/conditional/DndCondition.java
index 3112d48..4acd332 100644
--- a/src/com/android/settings/dashboard/conditional/DndCondition.java
+++ b/src/com/android/settings/dashboard/conditional/DndCondition.java
@@ -42,9 +42,10 @@
     @VisibleForTesting
     static final IntentFilter DND_FILTER =
         new IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL);
+    @VisibleForTesting
+    protected ZenModeConfig mConfig;
 
     private int mZen;
-    private ZenModeConfig mConfig;
     private final Receiver mReceiver;
 
     public DndCondition(ConditionManager manager) {
@@ -93,7 +94,7 @@
     @Override
     public CharSequence getSummary() {
         return ZenModeConfig.getDescription(mManager.getContext(), mZen != Global.ZEN_MODE_OFF,
-                mConfig);
+                mConfig, true);
     }
 
     @Override
diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeFormat.java b/src/com/android/settings/deviceinfo/PrivateVolumeFormat.java
index 319a09c..4a63e64 100644
--- a/src/com/android/settings/deviceinfo/PrivateVolumeFormat.java
+++ b/src/com/android/settings/deviceinfo/PrivateVolumeFormat.java
@@ -16,6 +16,11 @@
 
 package com.android.settings.deviceinfo;
 
+import static android.os.storage.DiskInfo.EXTRA_DISK_ID;
+
+import static com.android.settings.deviceinfo.StorageWizardBase.EXTRA_FORMAT_FORGET_UUID;
+import static com.android.settings.deviceinfo.StorageWizardBase.EXTRA_FORMAT_PRIVATE;
+
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.storage.DiskInfo;
@@ -30,8 +35,8 @@
 import android.widget.TextView;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.R;
+import com.android.settings.core.InstrumentedPreferenceFragment;
 
 public class PrivateVolumeFormat extends InstrumentedPreferenceFragment {
     private VolumeInfo mVolume;
@@ -65,9 +70,9 @@
         @Override
         public void onClick(View v) {
             final Intent intent = new Intent(getActivity(), StorageWizardFormatProgress.class);
-            intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-            intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
-            intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORGET_UUID, mVolume.getFsUuid());
+            intent.putExtra(EXTRA_DISK_ID, mDisk.getId());
+            intent.putExtra(EXTRA_FORMAT_PRIVATE, false);
+            intent.putExtra(EXTRA_FORMAT_FORGET_UUID, mVolume.getFsUuid());
             startActivity(intent);
             getActivity().finish();
         }
diff --git a/src/com/android/settings/deviceinfo/PublicVolumeSettings.java b/src/com/android/settings/deviceinfo/PublicVolumeSettings.java
index c6337ce..85b7904 100644
--- a/src/com/android/settings/deviceinfo/PublicVolumeSettings.java
+++ b/src/com/android/settings/deviceinfo/PublicVolumeSettings.java
@@ -18,7 +18,6 @@
 
 import android.app.ActivityManager;
 import android.content.Context;
-import android.content.Intent;
 import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Bundle;
@@ -223,19 +222,12 @@
 
     @Override
     public boolean onPreferenceTreeClick(Preference pref) {
-        final Context context = getActivity();
         if (pref == mMount) {
-            new MountTask(context, mVolume).execute();
+            new MountTask(getActivity(), mVolume).execute();
         } else if (pref == mFormatPublic) {
-            final Intent intent = new Intent(context, StorageWizardFormatConfirm.class);
-            intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-            intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
-            startActivity(intent);
+            StorageWizardFormatConfirm.showPublic(getActivity(), mDisk.getId());
         } else if (pref == mFormatPrivate) {
-            final Intent intent = new Intent(context, StorageWizardFormatConfirm.class);
-            intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-            intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, true);
-            startActivity(intent);
+            StorageWizardFormatConfirm.showPrivate(getActivity(), mDisk.getId());
         }
 
         return super.onPreferenceTreeClick(pref);
diff --git a/src/com/android/settings/deviceinfo/StorageWizardBase.java b/src/com/android/settings/deviceinfo/StorageWizardBase.java
index 5b48666..4787ac5 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardBase.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardBase.java
@@ -16,12 +16,14 @@
 
 package com.android.settings.deviceinfo;
 
+import static android.os.storage.DiskInfo.EXTRA_DISK_ID;
+import static android.os.storage.VolumeInfo.EXTRA_VOLUME_ID;
+
 import static com.android.settings.deviceinfo.StorageSettings.TAG;
 
 import android.annotation.LayoutRes;
 import android.app.Activity;
-import android.content.Context;
-import android.content.res.TypedArray;
+import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.SystemClock;
@@ -31,12 +33,15 @@
 import android.os.storage.VolumeInfo;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.Button;
+import android.widget.FrameLayout;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.android.settings.R;
+import com.android.settingslib.Utils;
 import com.android.setupwizardlib.GlifLayout;
 
 import java.text.NumberFormat;
@@ -44,11 +49,17 @@
 import java.util.Objects;
 
 public abstract class StorageWizardBase extends Activity {
+    protected static final String EXTRA_FORMAT_FORGET_UUID = "format_forget_uuid";
+    protected static final String EXTRA_FORMAT_PRIVATE = "format_private";
+    protected static final String EXTRA_FORMAT_SLOW = "format_slow";
+    protected static final String EXTRA_MIGRATE_SKIP = "migrate_skip";
+
     protected StorageManager mStorage;
 
     protected VolumeInfo mVolume;
     protected DiskInfo mDisk;
 
+    private Button mBack;
     private Button mNext;
 
     @Override
@@ -57,12 +68,12 @@
 
         mStorage = getSystemService(StorageManager.class);
 
-        final String volumeId = getIntent().getStringExtra(VolumeInfo.EXTRA_VOLUME_ID);
+        final String volumeId = getIntent().getStringExtra(EXTRA_VOLUME_ID);
         if (!TextUtils.isEmpty(volumeId)) {
             mVolume = mStorage.findVolumeById(volumeId);
         }
 
-        final String diskId = getIntent().getStringExtra(DiskInfo.EXTRA_DISK_ID);
+        final String diskId = getIntent().getStringExtra(EXTRA_DISK_ID);
         if (!TextUtils.isEmpty(diskId)) {
             mDisk = mStorage.findDiskById(diskId);
         } else if (mVolume != null) {
@@ -78,13 +89,10 @@
     public void setContentView(@LayoutRes int layoutResID) {
         super.setContentView(layoutResID);
 
-        mNext = (Button) findViewById(R.id.storage_next_button);
-        mNext.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                onNavigateNext();
-            }
-        });
+        mBack = requireViewById(R.id.storage_back_button);
+        mNext = requireViewById(R.id.storage_next_button);
+
+        setIcon(com.android.internal.R.drawable.ic_sd_card_48dp);
     }
 
     @Override
@@ -93,62 +101,109 @@
         super.onDestroy();
     }
 
+    protected Button getBackButton() {
+        return mBack;
+    }
+
     protected Button getNextButton() {
         return mNext;
     }
 
     protected GlifLayout getGlifLayout() {
-        return (GlifLayout) findViewById(R.id.setup_wizard_layout);
+        return requireViewById(R.id.setup_wizard_layout);
     }
 
     protected ProgressBar getProgressBar() {
-        return (ProgressBar) findViewById(R.id.storage_wizard_progress);
+        return requireViewById(R.id.storage_wizard_progress);
     }
 
     protected void setCurrentProgress(int progress) {
         getProgressBar().setProgress(progress);
-        ((TextView) findViewById(R.id.storage_wizard_progress_summary)).setText(
+        ((TextView) requireViewById(R.id.storage_wizard_progress_summary)).setText(
                 NumberFormat.getPercentInstance().format((double) progress / 100));
     }
 
-    protected void setHeaderText(int resId, String... args) {
+    protected void setHeaderText(int resId, CharSequence... args) {
         final CharSequence headerText = TextUtils.expandTemplate(getText(resId), args);
         getGlifLayout().setHeaderText(headerText);
         setTitle(headerText);
     }
 
-    protected void setBodyText(int resId, String... args) {
-        ((TextView) findViewById(R.id.storage_wizard_body)).setText(
-                TextUtils.expandTemplate(getText(resId), args));
+    protected void setBodyText(int resId, CharSequence... args) {
+        final TextView body = requireViewById(R.id.storage_wizard_body);
+        body.setText(TextUtils.expandTemplate(getText(resId), args));
+        body.setVisibility(View.VISIBLE);
     }
 
-    protected void setSecondaryBodyText(int resId, String... args) {
-        final TextView secondBody = ((TextView) findViewById(R.id.storage_wizard_second_body));
-        secondBody.setText(TextUtils.expandTemplate(getText(resId), args));
-        secondBody.setVisibility(View.VISIBLE);
+    protected void setAuxChecklist() {
+        final FrameLayout aux = requireViewById(R.id.storage_wizard_aux);
+        aux.addView(LayoutInflater.from(aux.getContext())
+                .inflate(R.layout.storage_wizard_checklist, aux, false));
+        aux.setVisibility(View.VISIBLE);
+
+        // Customize string based on disk
+        ((TextView) aux.requireViewById(R.id.storage_wizard_migrate_v2_checklist_media))
+                .setText(TextUtils.expandTemplate(
+                        getText(R.string.storage_wizard_migrate_v2_checklist_media),
+                        mDisk.getShortDescription()));
     }
 
-    protected static final int ILLUSTRATION_SETUP = 0;
-    protected static final int ILLUSTRATION_INTERNAL = 1;
-    protected static final int ILLUSTRATION_PORTABLE = 2;
+    protected void setBackButtonText(int resId, CharSequence... args) {
+        mBack.setText(TextUtils.expandTemplate(getText(resId), args));
+        mBack.setVisibility(View.VISIBLE);
+    }
 
-    protected void setIllustrationType(int type) {
-        // TODO: map type to updated icons once provided by UX
-        TypedArray array = obtainStyledAttributes(new int[] {android.R.attr.colorAccent});
-        Drawable icon = getDrawable(com.android.internal.R.drawable.ic_sd_card_48dp).mutate();
-        icon.setTint(array.getColor(0, 0));
-        array.recycle();
-        getGlifLayout().setIcon(icon);
+    protected void setNextButtonText(int resId, CharSequence... args) {
+        mNext.setText(TextUtils.expandTemplate(getText(resId), args));
+        mNext.setVisibility(View.VISIBLE);
+    }
+
+    protected void setIcon(int resId) {
+        final GlifLayout layout = getGlifLayout();
+        final Drawable icon = getDrawable(resId).mutate();
+        icon.setTint(Utils.getColorAccent(layout.getContext()));
+        layout.setIcon(icon);
     }
 
     protected void setKeepScreenOn(boolean keepScreenOn) {
         getGlifLayout().setKeepScreenOn(keepScreenOn);
     }
 
-    public void onNavigateNext() {
+    public void onNavigateBack(View view) {
         throw new UnsupportedOperationException();
     }
 
+    public void onNavigateNext(View view) {
+        throw new UnsupportedOperationException();
+    }
+
+    private void copyStringExtra(Intent from, Intent to, String key) {
+        if (from.hasExtra(key) && !to.hasExtra(key)) {
+            to.putExtra(key, from.getStringExtra(key));
+        }
+    }
+
+    private void copyBooleanExtra(Intent from, Intent to, String key) {
+        if (from.hasExtra(key) && !to.hasExtra(key)) {
+            to.putExtra(key, from.getBooleanExtra(key, false));
+        }
+    }
+
+    @Override
+    public void startActivity(Intent intent) {
+        final Intent from = getIntent();
+        final Intent to = intent;
+
+        copyStringExtra(from, to, EXTRA_DISK_ID);
+        copyStringExtra(from, to, EXTRA_VOLUME_ID);
+        copyStringExtra(from, to, EXTRA_FORMAT_FORGET_UUID);
+        copyBooleanExtra(from, to, EXTRA_FORMAT_PRIVATE);
+        copyBooleanExtra(from, to, EXTRA_FORMAT_SLOW);
+        copyBooleanExtra(from, to, EXTRA_MIGRATE_SKIP);
+
+        super.startActivity(intent);
+    }
+
     protected VolumeInfo findFirstVolume(int type) {
         return findFirstVolume(type, 1);
     }
diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java
index a9a4db2..7173f08 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java
@@ -16,52 +16,91 @@
 
 package com.android.settings.deviceinfo;
 
+import static android.os.storage.DiskInfo.EXTRA_DISK_ID;
+
+import static com.android.settings.deviceinfo.StorageWizardBase.EXTRA_FORMAT_FORGET_UUID;
+import static com.android.settings.deviceinfo.StorageWizardBase.EXTRA_FORMAT_PRIVATE;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.storage.DiskInfo;
+import android.os.storage.StorageManager;
+import android.text.TextUtils;
 
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 
-public class StorageWizardFormatConfirm extends StorageWizardBase {
-    public static final String EXTRA_FORMAT_PRIVATE = "format_private";
-    public static final String EXTRA_FORGET_UUID = "forget_uuid";
+public class StorageWizardFormatConfirm extends InstrumentedDialogFragment {
+    private static final String TAG_FORMAT_WARNING = "format_warning";
 
-    private boolean mFormatPrivate;
+    public static void showPublic(Activity activity, String diskId) {
+        show(activity, diskId, null, false);
+    }
 
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (mDisk == null) {
-            finish();
-            return;
-        }
-        setContentView(R.layout.storage_wizard_generic);
+    public static void showPublic(Activity activity, String diskId, String forgetUuid) {
+        show(activity, diskId, forgetUuid, false);
+    }
 
-        mFormatPrivate = getIntent().getBooleanExtra(EXTRA_FORMAT_PRIVATE, false);
-        setIllustrationType(
-                mFormatPrivate ? ILLUSTRATION_INTERNAL : ILLUSTRATION_PORTABLE);
+    public static void showPrivate(Activity activity, String diskId) {
+        show(activity, diskId, null, true);
+    }
 
-        if (mFormatPrivate) {
-            setHeaderText(R.string.storage_wizard_format_confirm_title);
-            setBodyText(R.string.storage_wizard_format_confirm_body,
-                    mDisk.getDescription());
-        } else {
-            setHeaderText(R.string.storage_wizard_format_confirm_public_title);
-            setBodyText(R.string.storage_wizard_format_confirm_public_body,
-                    mDisk.getDescription());
-        }
+    private static void show(Activity activity, String diskId, String formatForgetUuid,
+            boolean formatPrivate) {
+        final Bundle args = new Bundle();
+        args.putString(EXTRA_DISK_ID, diskId);
+        args.putString(EXTRA_FORMAT_FORGET_UUID, formatForgetUuid);
+        args.putBoolean(EXTRA_FORMAT_PRIVATE, formatPrivate);
 
-        getNextButton().setText(R.string.storage_wizard_format_confirm_next);
-        getNextButton().setBackgroundTintList(getColorStateList(R.color.storage_wizard_button_red));
+        final StorageWizardFormatConfirm fragment = new StorageWizardFormatConfirm();
+        fragment.setArguments(args);
+        fragment.showAllowingStateLoss(activity.getFragmentManager(), TAG_FORMAT_WARNING);
     }
 
     @Override
-    public void onNavigateNext() {
-        final Intent intent = new Intent(this, StorageWizardFormatProgress.class);
-        intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-        intent.putExtra(EXTRA_FORMAT_PRIVATE, mFormatPrivate);
-        intent.putExtra(EXTRA_FORGET_UUID, getIntent().getStringExtra(EXTRA_FORGET_UUID));
-        startActivity(intent);
-        finishAffinity();
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.DIALOG_VOLUME_FORMAT;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final Context context = getContext();
+
+        final Bundle args = getArguments();
+        final String diskId = args.getString(EXTRA_DISK_ID);
+        final String formatForgetUuid = args.getString(EXTRA_FORMAT_FORGET_UUID);
+        final boolean formatPrivate = args.getBoolean(EXTRA_FORMAT_PRIVATE, false);
+
+        final DiskInfo disk = context.getSystemService(StorageManager.class)
+                .findDiskById(diskId);
+
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        builder.setTitle(TextUtils.expandTemplate(
+                getText(R.string.storage_wizard_format_confirm_v2_title),
+                disk.getShortDescription()));
+        builder.setMessage(TextUtils.expandTemplate(
+                getText(R.string.storage_wizard_format_confirm_v2_body),
+                disk.getDescription(),
+                disk.getShortDescription(),
+                disk.getShortDescription()));
+
+        builder.setNegativeButton(android.R.string.cancel, null);
+        builder.setPositiveButton(
+                TextUtils.expandTemplate(getText(R.string.storage_wizard_format_confirm_v2_action),
+                        disk.getShortDescription()),
+                (dialog, which) -> {
+                    final Intent intent = new Intent(context, StorageWizardFormatProgress.class);
+                    intent.putExtra(EXTRA_DISK_ID, diskId);
+                    intent.putExtra(EXTRA_FORMAT_FORGET_UUID, formatForgetUuid);
+                    intent.putExtra(EXTRA_FORMAT_PRIVATE, formatPrivate);
+                    context.startActivity(intent);
+                });
+
+        return builder.create();
     }
 }
diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
index 3dfc74b..8e3f8ef 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
@@ -20,34 +20,26 @@
 
 import static com.android.settings.deviceinfo.StorageSettings.TAG;
 
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.IPackageMoveObserver;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.IVoldTaskListener;
 import android.os.PersistableBundle;
-import android.os.storage.DiskInfo;
+import android.os.SystemProperties;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
-import android.text.TextUtils;
 import android.util.Log;
-import android.view.View;
 import android.widget.Toast;
 
-import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 
 import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
 public class StorageWizardFormatProgress extends StorageWizardBase {
-    private static final String TAG_SLOW_WARNING = "slow_warning";
+    private static final String PROP_DEBUG_STORAGE_SLOW = "sys.debug.storage_slow";
 
     private boolean mFormatPrivate;
 
@@ -63,16 +55,11 @@
         setContentView(R.layout.storage_wizard_progress);
         setKeepScreenOn(true);
 
-        mFormatPrivate = getIntent().getBooleanExtra(
-                StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
-        setIllustrationType(
-                mFormatPrivate ? ILLUSTRATION_INTERNAL : ILLUSTRATION_PORTABLE);
+        mFormatPrivate = getIntent().getBooleanExtra(EXTRA_FORMAT_PRIVATE, false);
 
-        setHeaderText(R.string.storage_wizard_format_progress_title, mDisk.getDescription());
+        setHeaderText(R.string.storage_wizard_format_progress_title, mDisk.getShortDescription());
         setBodyText(R.string.storage_wizard_format_progress_body, mDisk.getDescription());
 
-        getNextButton().setVisibility(View.GONE);
-
         mTask = (PartitionTask) getLastNonConfigurationInstance();
         if (mTask == null) {
             mTask = new PartitionTask();
@@ -198,93 +185,29 @@
                 // changes.
 
                 Log.d(TAG, "New volume took " + mPrivateBench + "ms to run benchmark");
-                if (mPrivateBench > 2000) {
-                    final SlowWarningFragment dialog = new SlowWarningFragment();
-                    dialog.showAllowingStateLoss(activity.getFragmentManager(), TAG_SLOW_WARNING);
+                if (mPrivateBench > 2000
+                        || SystemProperties.getBoolean(PROP_DEBUG_STORAGE_SLOW, false)) {
+                    mActivity.onFormatFinishedSlow();
                 } else {
-                    activity.onFormatFinished();
+                    mActivity.onFormatFinished();
                 }
             } else {
-                activity.onFormatFinished();
+                mActivity.onFormatFinished();
             }
         }
     }
 
-    public static class SlowWarningFragment extends InstrumentedDialogFragment {
-
-        @Override
-        public int getMetricsCategory() {
-            return MetricsProto.MetricsEvent.DIALOG_VOLUME_SLOW_WARNING;
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final Context context = getActivity();
-
-            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-
-            final StorageWizardFormatProgress target =
-                    (StorageWizardFormatProgress) getActivity();
-            final String descrip = target.getDiskDescription();
-            final String genericDescip = target.getGenericDiskDescription();
-            builder.setMessage(TextUtils.expandTemplate(getText(R.string.storage_wizard_slow_body),
-                    descrip, genericDescip));
-
-            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    final StorageWizardFormatProgress target =
-                            (StorageWizardFormatProgress) getActivity();
-                    target.onFormatFinished();
-                }
-            });
-
-            return builder.create();
-        }
+    public void onFormatFinished() {
+        final Intent intent = new Intent(this, StorageWizardFormatSlow.class);
+        intent.putExtra(EXTRA_FORMAT_SLOW, false);
+        startActivity(intent);
+        finishAffinity();
     }
 
-    private String getDiskDescription() {
-        return mDisk.getDescription();
-    }
-
-    private String getGenericDiskDescription() {
-        // TODO: move this directly to DiskInfo
-        if (mDisk.isSd()) {
-            return getString(com.android.internal.R.string.storage_sd_card);
-        } else if (mDisk.isUsb()) {
-            return getString(com.android.internal.R.string.storage_usb_drive);
-        } else {
-            return null;
-        }
-    }
-
-    private void onFormatFinished() {
-        final String forgetUuid = getIntent().getStringExtra(
-                StorageWizardFormatConfirm.EXTRA_FORGET_UUID);
-        if (!TextUtils.isEmpty(forgetUuid)) {
-            mStorage.forgetVolume(forgetUuid);
-        }
-
-        final boolean offerMigrate;
-        if (mFormatPrivate) {
-            // Offer to migrate only if storage is currently internal
-            final VolumeInfo privateVol = getPackageManager()
-                    .getPrimaryStorageCurrentVolume();
-            offerMigrate = (privateVol != null
-                    && VolumeInfo.ID_PRIVATE_INTERNAL.equals(privateVol.getId()));
-        } else {
-            offerMigrate = false;
-        }
-
-        if (offerMigrate) {
-            final Intent intent = new Intent(this, StorageWizardMigrate.class);
-            intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-            startActivity(intent);
-        } else {
-            final Intent intent = new Intent(this, StorageWizardReady.class);
-            intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-            startActivity(intent);
-        }
+    public void onFormatFinishedSlow() {
+        final Intent intent = new Intent(this, StorageWizardFormatSlow.class);
+        intent.putExtra(EXTRA_FORMAT_SLOW, true);
+        startActivity(intent);
         finishAffinity();
     }
 
diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatSlow.java b/src/com/android/settings/deviceinfo/StorageWizardFormatSlow.java
new file mode 100644
index 0000000..9c80ff6
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/StorageWizardFormatSlow.java
@@ -0,0 +1,92 @@
+/*
+ * 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.deviceinfo;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.storage.DiskInfo;
+import android.os.storage.VolumeInfo;
+import android.text.TextUtils;
+import android.view.View;
+
+import com.android.settings.R;
+
+public class StorageWizardFormatSlow extends StorageWizardBase {
+    private boolean mFormatPrivate;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (mDisk == null) {
+            finish();
+            return;
+        }
+        setContentView(R.layout.storage_wizard_generic);
+
+        mFormatPrivate = getIntent().getBooleanExtra(EXTRA_FORMAT_PRIVATE, false);
+
+        setHeaderText(R.string.storage_wizard_slow_v2_title, mDisk.getShortDescription());
+        setBodyText(R.string.storage_wizard_slow_v2_body, mDisk.getDescription(),
+                mDisk.getShortDescription(), mDisk.getShortDescription(),
+                mDisk.getShortDescription());
+
+        setBackButtonText(R.string.storage_wizard_slow_v2_start_over);
+        setNextButtonText(R.string.storage_wizard_slow_v2_continue);
+
+        // If benchmark wasn't actually slow, skip this warning
+        if (!getIntent().getBooleanExtra(EXTRA_FORMAT_SLOW, false)) {
+            onNavigateNext(null);
+        }
+    }
+
+    @Override
+    public void onNavigateBack(View view) {
+        final Intent intent = new Intent(this, StorageWizardInit.class);
+        startActivity(intent);
+        finishAffinity();
+    }
+
+    @Override
+    public void onNavigateNext(View view) {
+        final String forgetUuid = getIntent().getStringExtra(EXTRA_FORMAT_FORGET_UUID);
+        if (!TextUtils.isEmpty(forgetUuid)) {
+            mStorage.forgetVolume(forgetUuid);
+        }
+
+        final boolean offerMigrate;
+        if (mFormatPrivate) {
+            // Offer to migrate only if storage is currently internal
+            final VolumeInfo privateVol = getPackageManager()
+                    .getPrimaryStorageCurrentVolume();
+            offerMigrate = (privateVol != null
+                    && VolumeInfo.ID_PRIVATE_INTERNAL.equals(privateVol.getId()));
+        } else {
+            offerMigrate = false;
+        }
+
+        if (offerMigrate) {
+            final Intent intent = new Intent(this, StorageWizardMigrateConfirm.class);
+            intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
+            startActivity(intent);
+        } else {
+            final Intent intent = new Intent(this, StorageWizardReady.class);
+            intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
+            startActivity(intent);
+        }
+        finishAffinity();
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/StorageWizardInit.java b/src/com/android/settings/deviceinfo/StorageWizardInit.java
index 05c7b15..2233cf9 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardInit.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardInit.java
@@ -16,29 +16,20 @@
 
 package com.android.settings.deviceinfo;
 
-import static com.android.settings.deviceinfo.StorageSettings.TAG;
-
 import android.app.ActivityManager;
 import android.content.Intent;
-import android.os.AsyncTask;
 import android.os.Bundle;
-import android.os.Environment;
 import android.os.UserManager;
 import android.os.storage.DiskInfo;
 import android.os.storage.VolumeInfo;
-import android.util.DebugUtils;
-import android.util.Log;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.RadioButton;
+import android.view.View;
+import android.widget.Button;
 
 import com.android.settings.R;
 
-import java.io.File;
-
 public class StorageWizardInit extends StorageWizardBase {
-    private RadioButton mRadioExternal;
-    private RadioButton mRadioInternal;
+    private Button mExternal;
+    private Button mInternal;
 
     private boolean mIsPermittedToAdopt;
 
@@ -54,107 +45,46 @@
         mIsPermittedToAdopt = UserManager.get(this).isAdminUser()
                 && !ActivityManager.isUserAMonkey();
 
-        setIllustrationType(ILLUSTRATION_SETUP);
-        setHeaderText(R.string.storage_wizard_init_title, mDisk.getDescription());
+        setHeaderText(R.string.storage_wizard_init_v2_title, mDisk.getShortDescription());
 
-        mRadioExternal = (RadioButton) findViewById(R.id.storage_wizard_init_external_title);
-        mRadioInternal = (RadioButton) findViewById(R.id.storage_wizard_init_internal_title);
+        mExternal = requireViewById(R.id.storage_wizard_init_external);
+        mInternal = requireViewById(R.id.storage_wizard_init_internal);
 
-        mRadioExternal.setOnCheckedChangeListener(mRadioListener);
-        mRadioInternal.setOnCheckedChangeListener(mRadioListener);
-
-        findViewById(R.id.storage_wizard_init_external_summary).setPadding(
-                mRadioExternal.getCompoundPaddingLeft(), 0,
-                mRadioExternal.getCompoundPaddingRight(), 0);
-        findViewById(R.id.storage_wizard_init_internal_summary).setPadding(
-                mRadioExternal.getCompoundPaddingLeft(), 0,
-                mRadioExternal.getCompoundPaddingRight(), 0);
-
-        getNextButton().setEnabled(false);
+        setBackButtonText(R.string.storage_wizard_init_v2_later);
 
         if (!mDisk.isAdoptable()) {
             // If not adoptable, we only have one choice
-            mRadioExternal.setChecked(true);
-            onNavigateNext();
+            onNavigateExternal(null);
             finish();
         } else if (!mIsPermittedToAdopt) {
             // TODO: Show a message about why this is disabled for guest and
             // that only an admin user can adopt an sd card.
-            mRadioInternal.setEnabled(false);
-        } else if (mVolume != null && mVolume.getType() == VolumeInfo.TYPE_PUBLIC
-                && mVolume.isMountedReadable()) {
-            // Device is mounted, so classify contents to possibly pick a
-            // recommended default operation.
-            new ClassifyTask().execute(mVolume.getPath());
+            mInternal.setEnabled(false);
         }
     }
 
-    private final OnCheckedChangeListener mRadioListener = new OnCheckedChangeListener() {
-        @Override
-        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-            if (isChecked) {
-                if (buttonView == mRadioExternal) {
-                    mRadioInternal.setChecked(false);
-                    setIllustrationType(ILLUSTRATION_PORTABLE);
-                } else if (buttonView == mRadioInternal) {
-                    mRadioExternal.setChecked(false);
-                    setIllustrationType(ILLUSTRATION_INTERNAL);
-                }
-                getNextButton().setEnabled(true);
-            }
-        }
-    };
-
     @Override
-    public void onNavigateNext() {
-        if (mRadioExternal.isChecked()) {
-            if (mVolume != null && mVolume.getType() == VolumeInfo.TYPE_PUBLIC
-                    && mVolume.getState() != VolumeInfo.STATE_UNMOUNTABLE) {
-                // Remember that user made decision
-                mStorage.setVolumeInited(mVolume.getFsUuid(), true);
+    public void onNavigateBack(View view) {
+        finish();
+    }
 
-                final Intent intent = new Intent(this, StorageWizardReady.class);
-                intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-                startActivity(intent);
+    public void onNavigateExternal(View view) {
+        if (mVolume != null && mVolume.getType() == VolumeInfo.TYPE_PUBLIC
+                && mVolume.getState() != VolumeInfo.STATE_UNMOUNTABLE) {
+            // Remember that user made decision
+            mStorage.setVolumeInited(mVolume.getFsUuid(), true);
 
-            } else {
-                // Gotta format to get there
-                final Intent intent = new Intent(this, StorageWizardFormatConfirm.class);
-                intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-                intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
-                startActivity(intent);
-            }
-
-        } else if (mRadioInternal.isChecked()) {
-            final Intent intent = new Intent(this, StorageWizardFormatConfirm.class);
+            final Intent intent = new Intent(this, StorageWizardReady.class);
             intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-            intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, true);
             startActivity(intent);
+
+        } else {
+            // Gotta format to get there
+            StorageWizardFormatConfirm.showPublic(this, mDisk.getId());
         }
     }
 
-    /**
-     * Task that classifies the contents of a mounted storage device, and sets a
-     * recommended default operation based on result.
-     */
-    public class ClassifyTask extends AsyncTask<File, Void, Integer> {
-        @Override
-        protected Integer doInBackground(File... params) {
-            int classes = Environment.classifyExternalStorageDirectory(params[0]);
-            Log.v(TAG, "Classified " + params[0] + " as "
-                    + DebugUtils.flagsToString(Environment.class, "HAS_", classes));
-            return classes;
-        }
-
-        @Override
-        protected void onPostExecute(Integer classes) {
-            if (classes == 0) {
-                // Empty is strong signal for adopt
-                mRadioInternal.setChecked(true);
-            } else if ((classes & (Environment.HAS_PICTURES | Environment.HAS_DCIM)) != 0) {
-                // Photos is strong signal for portable
-                mRadioExternal.setChecked(true);
-            }
-        }
+    public void onNavigateInternal(View view) {
+        StorageWizardFormatConfirm.showPrivate(this, mDisk.getId());
     }
 }
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMigrate.java b/src/com/android/settings/deviceinfo/StorageWizardMigrate.java
deleted file mode 100644
index 148282f..0000000
--- a/src/com/android/settings/deviceinfo/StorageWizardMigrate.java
+++ /dev/null
@@ -1,94 +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.deviceinfo;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.storage.DiskInfo;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.RadioButton;
-
-import com.android.settings.R;
-
-public class StorageWizardMigrate extends StorageWizardBase {
-    private MigrateEstimateTask mEstimate;
-
-    private RadioButton mRadioNow;
-    private RadioButton mRadioLater;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (mDisk == null) {
-            finish();
-            return;
-        }
-        setContentView(R.layout.storage_wizard_migrate);
-
-        setIllustrationType(ILLUSTRATION_INTERNAL);
-        setHeaderText(R.string.storage_wizard_migrate_title, mDisk.getDescription());
-        setBodyText(R.string.memory_calculating_size);
-
-        mRadioNow = (RadioButton) findViewById(R.id.storage_wizard_migrate_now);
-        mRadioLater = (RadioButton) findViewById(R.id.storage_wizard_migrate_later);
-
-        mRadioNow.setOnCheckedChangeListener(mRadioListener);
-        mRadioLater.setOnCheckedChangeListener(mRadioListener);
-
-        getNextButton().setEnabled(false);
-
-        mEstimate = new MigrateEstimateTask(this) {
-            @Override
-            public void onPostExecute(String size, String time) {
-                setBodyText(R.string.storage_wizard_migrate_body,
-                        mDisk.getDescription(), time, size);
-            }
-        };
-
-        mEstimate.copyFrom(getIntent());
-        mEstimate.execute();
-    }
-
-    private final OnCheckedChangeListener mRadioListener = new OnCheckedChangeListener() {
-        @Override
-        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-            if (isChecked) {
-                if (buttonView == mRadioNow) {
-                    mRadioLater.setChecked(false);
-                } else if (buttonView == mRadioLater) {
-                    mRadioNow.setChecked(false);
-                }
-                getNextButton().setEnabled(true);
-            }
-        }
-    };
-
-    @Override
-    public void onNavigateNext() {
-        if (mRadioNow.isChecked()) {
-            final Intent intent = new Intent(this, StorageWizardMigrateConfirm.class);
-            intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-            mEstimate.copyTo(intent);
-            startActivity(intent);
-        } else if (mRadioLater.isChecked()) {
-            final Intent intent = new Intent(this, StorageWizardReady.class);
-            intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
-            startActivity(intent);
-        }
-    }
-}
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java
index 8c8b90e..755f093 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java
@@ -28,6 +28,7 @@
 import android.os.storage.VolumeInfo;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
 import android.widget.Toast;
 
 import com.android.settings.R;
@@ -57,30 +58,35 @@
             return;
         }
 
-        final String sourceDescrip = mStorage.getBestVolumeDescription(sourceVol);
-        final String targetDescrip = mStorage.getBestVolumeDescription(mVolume);
-
-        setIllustrationType(ILLUSTRATION_INTERNAL);
-        setHeaderText(R.string.storage_wizard_migrate_confirm_title, targetDescrip);
+        setIcon(R.drawable.ic_swap_horiz);
+        setHeaderText(R.string.storage_wizard_migrate_v2_title, mDisk.getShortDescription());
         setBodyText(R.string.memory_calculating_size);
-        setSecondaryBodyText(R.string.storage_wizard_migrate_details, targetDescrip);
+        setAuxChecklist();
 
         mEstimate = new MigrateEstimateTask(this) {
             @Override
             public void onPostExecute(String size, String time) {
-                setBodyText(R.string.storage_wizard_migrate_confirm_body, time, size,
-                        sourceDescrip);
+                setBodyText(R.string.storage_wizard_migrate_v2_body,
+                        mDisk.getDescription(), size, time);
             }
         };
 
         mEstimate.copyFrom(getIntent());
         mEstimate.execute();
 
-        getNextButton().setText(R.string.storage_wizard_migrate_confirm_next);
+        setBackButtonText(R.string.storage_wizard_migrate_v2_later);
+        setNextButtonText(R.string.storage_wizard_migrate_v2_now);
     }
 
     @Override
-    public void onNavigateNext() {
+    public void onNavigateBack(View view) {
+        final Intent intent = new Intent(this, StorageWizardReady.class);
+        intent.putExtra(EXTRA_MIGRATE_SKIP, true);
+        startActivity(intent);
+    }
+
+    @Override
+    public void onNavigateNext(View view) {
         // Ensure that all users are unlocked so that we can move their data
         if (StorageManager.isFileEncryptedNativeOrEmulated()) {
             for (UserInfo user : getSystemService(UserManager.class).getUsers()) {
@@ -134,7 +140,7 @@
             if (resultCode == RESULT_OK) {
                 // Credentials confirmed, so storage should be unlocked; let's
                 // go look for the next locked user.
-                onNavigateNext();
+                onNavigateNext(null);
             } else {
                 // User wasn't able to confirm credentials, so we're okay
                 // landing back at the wizard page again, where they read
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java b/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java
index ade3bfa..60f3cb5 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java
@@ -16,6 +16,10 @@
 
 package com.android.settings.deviceinfo;
 
+import static android.content.pm.PackageManager.EXTRA_MOVE_ID;
+
+import static com.android.settings.deviceinfo.StorageSettings.TAG;
+
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -24,14 +28,10 @@
 import android.os.Handler;
 import android.os.storage.DiskInfo;
 import android.util.Log;
-import android.view.View;
 import android.widget.Toast;
 
 import com.android.settings.R;
 
-import static android.content.pm.PackageManager.EXTRA_MOVE_ID;
-import static com.android.settings.deviceinfo.StorageSettings.TAG;
-
 public class StorageWizardMigrateProgress extends StorageWizardBase {
     private static final String ACTION_FINISH_WIZARD = "com.android.systemui.action.FINISH_WIZARD";
 
@@ -48,12 +48,9 @@
 
         mMoveId = getIntent().getIntExtra(EXTRA_MOVE_ID, -1);
 
-        final String descrip = mStorage.getBestVolumeDescription(mVolume);
-        setIllustrationType(ILLUSTRATION_INTERNAL);
-        setHeaderText(R.string.storage_wizard_migrate_progress_title, descrip);
-        setBodyText(R.string.storage_wizard_migrate_details, descrip);
-
-        getNextButton().setVisibility(View.GONE);
+        setIcon(R.drawable.ic_swap_horiz);
+        setHeaderText(R.string.storage_wizard_migrate_progress_v2_title);
+        setAuxChecklist();
 
         // Register for updates and push through current status
         getPackageManager().registerMoveCallback(mCallback, new Handler());
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
index e82612c..10b78af 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
@@ -32,6 +32,7 @@
 import android.os.storage.StorageManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
 
 import com.android.internal.util.Preconditions;
 import com.android.settings.R;
@@ -67,15 +68,15 @@
         final String appName = getPackageManager().getApplicationLabel(mApp).toString();
         final String volumeName = mStorage.getBestVolumeDescription(mVolume);
 
-        setIllustrationType(ILLUSTRATION_INTERNAL);
+        setIcon(R.drawable.ic_swap_horiz);
         setHeaderText(R.string.storage_wizard_move_confirm_title, appName);
         setBodyText(R.string.storage_wizard_move_confirm_body, appName, volumeName);
 
-        getNextButton().setText(R.string.move_app);
+        setNextButtonText(R.string.move_app);
     }
 
     @Override
-    public void onNavigateNext() {
+    public void onNavigateNext(View view) {
         // Ensure that all users are unlocked so that we can move their data
         if (StorageManager.isFileEncryptedNativeOrEmulated()) {
             for (UserInfo user : getSystemService(UserManager.class).getUsers()) {
@@ -108,7 +109,7 @@
             if (resultCode == RESULT_OK) {
                 // Credentials confirmed, so storage should be unlocked; let's
                 // go look for the next locked user.
-                onNavigateNext();
+                onNavigateNext(null);
             } else {
                 // User wasn't able to confirm credentials, so we're okay
                 // landing back at the wizard page again, where they read
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
index 69247f6..1f393c5 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
@@ -46,12 +46,10 @@
         final String appName = getIntent().getStringExtra(EXTRA_TITLE);
         final String volumeName = mStorage.getBestVolumeDescription(mVolume);
 
-        setIllustrationType(ILLUSTRATION_INTERNAL);
+        setIcon(R.drawable.ic_swap_horiz);
         setHeaderText(R.string.storage_wizard_move_progress_title, appName);
         setBodyText(R.string.storage_wizard_move_progress_body, volumeName, appName);
 
-        getNextButton().setVisibility(View.GONE);
-
         // Register for updates and push through current status
         getPackageManager().registerMoveCallback(mCallback, new Handler());
         mCallback.onStatusChanged(mMoveId, getPackageManager().getMoveStatus(mMoveId), -1);
diff --git a/src/com/android/settings/deviceinfo/StorageWizardReady.java b/src/com/android/settings/deviceinfo/StorageWizardReady.java
index ac5cf44..55f4ba1 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardReady.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardReady.java
@@ -18,10 +18,12 @@
 
 import android.os.Bundle;
 import android.os.storage.VolumeInfo;
+import android.view.View;
 
 import com.android.settings.R;
 
 public class StorageWizardReady extends StorageWizardBase {
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -31,27 +33,23 @@
         }
         setContentView(R.layout.storage_wizard_generic);
 
-        setHeaderText(R.string.storage_wizard_ready_title, mDisk.getDescription());
+        setHeaderText(R.string.storage_wizard_ready_title, mDisk.getShortDescription());
 
-        // TODO: handle mixed partition cases instead of just guessing based on
-        // first volume type we encounter
-        final VolumeInfo publicVol = findFirstVolume(VolumeInfo.TYPE_PUBLIC);
         final VolumeInfo privateVol = findFirstVolume(VolumeInfo.TYPE_PRIVATE);
-        if (publicVol != null) {
-            setIllustrationType(ILLUSTRATION_PORTABLE);
-            setBodyText(R.string.storage_wizard_ready_external_body,
-                    mDisk.getDescription());
-        } else if (privateVol != null) {
-            setIllustrationType(ILLUSTRATION_INTERNAL);
-            setBodyText(R.string.storage_wizard_ready_internal_body,
+        final boolean migrateSkip = getIntent().getBooleanExtra(EXTRA_MIGRATE_SKIP, false);
+        if (privateVol != null && !migrateSkip) {
+            setBodyText(R.string.storage_wizard_ready_v2_internal_body,
+                    mDisk.getDescription(), mDisk.getShortDescription());
+        } else {
+            setBodyText(R.string.storage_wizard_ready_v2_external_body,
                     mDisk.getDescription());
         }
 
-        getNextButton().setText(R.string.done);
+        setNextButtonText(R.string.done);
     }
 
     @Override
-    public void onNavigateNext() {
+    public void onNavigateNext(View view) {
         finishAffinity();
     }
 }
diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
index 5de49bb..a6d5363 100644
--- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
@@ -69,12 +69,16 @@
         return true;
     }
 
-    public void setConfig(AmbientDisplayConfiguration config) {
+    public AmbientDisplayAlwaysOnPreferenceController setConfig(
+            AmbientDisplayConfiguration config) {
         mConfig = config;
+        return this;
     }
 
-    public void setCallback(OnPreferenceChangedCallback callback) {
+    public AmbientDisplayAlwaysOnPreferenceController setCallback(
+            OnPreferenceChangedCallback callback) {
         mCallback = callback;
+        return this;
     }
 
     public static boolean isAlwaysOnEnabled(AmbientDisplayConfiguration config) {
diff --git a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
index 9cff088..15eb8b3 100644
--- a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
@@ -56,8 +56,10 @@
      *
      * @param config AmbientDisplayConfiguration for this controller
      */
-    public void setConfig(AmbientDisplayConfiguration config) {
+    public AmbientDisplayNotificationsPreferenceController setConfig(
+            AmbientDisplayConfiguration config) {
         mConfig = config;
+        return this;
     }
 
     @Override
diff --git a/src/com/android/settings/display/AmbientDisplaySettings.java b/src/com/android/settings/display/AmbientDisplaySettings.java
index cab28fa..8745e3f 100644
--- a/src/com/android/settings/display/AmbientDisplaySettings.java
+++ b/src/com/android/settings/display/AmbientDisplaySettings.java
@@ -44,35 +44,18 @@
     public static final String KEY_AMBIENT_DISPLAY_ALWAYS_ON = "ambient_display_always_on";
 
     private static final String TAG = "AmbientDisplaySettings";
-    private static final int MY_USER_ID = UserHandle.myUserId();
-
-    private static final String KEY_AMBIENT_DISPLAY_DOUBLE_TAP = "ambient_display_double_tap";
-    private static final String KEY_AMBIENT_DISPLAY_PICK_UP = "ambient_display_pick_up";
-    private static final String KEY_AMBIENT_DISPLAY_NOTIFICATION = "ambient_display_notification";
 
     private AmbientDisplayConfiguration mConfig;
 
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            Lifecycle lifecycle, AmbientDisplayConfiguration config) {
-
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new DoubleTapScreenPreferenceController(context, lifecycle, config,
-                MY_USER_ID, KEY_AMBIENT_DISPLAY_DOUBLE_TAP));
-        controllers.add(new PickupGesturePreferenceController(context, lifecycle, config,
-                MY_USER_ID, KEY_AMBIENT_DISPLAY_PICK_UP));
-        return controllers;
-    }
-
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        final AmbientDisplayAlwaysOnPreferenceController controller = use(
-                AmbientDisplayAlwaysOnPreferenceController.class);
-        controller.setConfig(getConfig(context));
-        controller.setCallback(this::updatePreferenceStates);
-        final AmbientDisplayNotificationsPreferenceController notificationController = use(
-                AmbientDisplayNotificationsPreferenceController.class);
-        notificationController.setConfig(getConfig(context));
+        use(AmbientDisplayAlwaysOnPreferenceController.class)
+            .setConfig(getConfig(context))
+            .setCallback(this::updatePreferenceStates);
+        use(AmbientDisplayNotificationsPreferenceController.class).setConfig(getConfig(context));
+        use(DoubleTapScreenPreferenceController.class).setConfig(getConfig(context));
+        use(PickupGesturePreferenceController.class).setConfig(getConfig(context));
     }
 
     @Override
@@ -86,11 +69,6 @@
     }
 
     @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, getLifecycle(), getConfig(context));
-    }
-
-    @Override
     public int getMetricsCategory() {
         return MetricsProto.MetricsEvent.AMBIENT_DISPLAY_SETTINGS;
     }
@@ -107,13 +85,6 @@
                     result.add(sir);
                     return result;
                 }
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(
-                        Context context) {
-                    return buildPreferenceControllers(context, null,
-                            new AmbientDisplayConfiguration(context));
-                }
             };
 
     private AmbientDisplayConfiguration getConfig(Context context) {
diff --git a/src/com/android/settings/display/ColorModePreferenceFragment.java b/src/com/android/settings/display/ColorModePreferenceFragment.java
index 6e4bd1f..089a5a6 100644
--- a/src/com/android/settings/display/ColorModePreferenceFragment.java
+++ b/src/com/android/settings/display/ColorModePreferenceFragment.java
@@ -41,9 +41,6 @@
     static final String KEY_COLOR_MODE_BOOSTED = "color_mode_boosted";
     @VisibleForTesting
     static final String KEY_COLOR_MODE_SATURATED = "color_mode_saturated";
-    // TODO have a real key for "automatic" rather than just re-using "saturated"
-    @VisibleForTesting
-    static final String KEY_COLOR_MODE_AUTOMATIC = "color_mode_saturated";
 
     private ColorDisplayController mController;
 
@@ -91,18 +88,16 @@
             new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_boosted),
                     KEY_COLOR_MODE_BOOSTED, enabled),
             new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_saturated),
-                    KEY_COLOR_MODE_SATURATED, enabled),
-            new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_automatic),
-                    KEY_COLOR_MODE_AUTOMATIC, enabled)
+                    KEY_COLOR_MODE_SATURATED, enabled)
         );
     }
 
     @Override
     protected String getDefaultKey() {
-        if (mController.getColorMode() == ColorDisplayController.COLOR_MODE_SATURATED) {
+        final int colorMode = mController.getColorMode();
+        if (colorMode == ColorDisplayController.COLOR_MODE_SATURATED) {
             return KEY_COLOR_MODE_SATURATED;
-        }
-        if (mController.getColorMode() == ColorDisplayController.COLOR_MODE_BOOSTED) {
+        } else if (colorMode == ColorDisplayController.COLOR_MODE_BOOSTED) {
             return KEY_COLOR_MODE_BOOSTED;
         }
         return KEY_COLOR_MODE_NATURAL;
diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
index ff43e6e..1c1d2f3 100644
--- a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
+++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
@@ -72,7 +72,7 @@
                 mRestriction);
         return builder
             .setPositiveButton(R.string.okay, null)
-            .setNeutralButton(R.string.admin_more_details,
+            .setNeutralButton(R.string.learn_more,
                     (dialog, which) -> {
                         showAdminPolicies(mEnforcedAdmin, mActivity);
                         mActivity.finish();
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
index eead69f..ab985f0 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
@@ -107,7 +107,7 @@
             disclosure.append(mResources.getString(R.string.do_disclosure_generic));
         }
         disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator));
-        disclosure.append(mResources.getString(R.string.do_disclosure_learn_more),
+        disclosure.append(mResources.getString(R.string.learn_more),
                 new EnterprisePrivacySpan(mContext), 0);
         return disclosure;
     }
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
index 1733a6e..a93d522 100644
--- a/src/com/android/settings/fuelgauge/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -209,6 +209,10 @@
                 name = context.getResources().getString(R.string.power_camera);
                 iconId = R.drawable.ic_settings_camera;
                 break;
+            case AMBIENT_DISPLAY:
+                name = context.getResources().getString(R.string.ambient_display_screen_title);
+                iconId = R.drawable.ic_settings_aod;
+                break;
         }
         if (iconId > 0) {
             icon = context.getDrawable(iconId);
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 3c493b9..e8668d1 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -214,6 +214,11 @@
         }
 
         if (totalActivityTimeMs >= 10 * DateUtils.MINUTE_IN_MILLIS) {
+            if (screenSipper == null) {
+                Log.e(TAG, "screen sipper is null even when app screen time is not zero");
+                return;
+            }
+
             final double screenPowerMah = screenSipper.totalPowerMah;
             for (int i = 0, size = sippers.size(); i < size; i++) {
                 final BatterySipper sipper = sippers.get(i);
diff --git a/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySaverPreferenceController.java b/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySaverPreferenceController.java
index 209723f..9c8ef63 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySaverPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySaverPreferenceController.java
@@ -21,6 +21,7 @@
 import android.support.v7.preference.Preference;
 
 import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.fuelgauge.BatterySaverUtils;
 
 /**
  * Controller that update whether to turn on battery saver automatically
@@ -61,11 +62,8 @@
 
     @Override
     public boolean setChecked(boolean isChecked) {
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL,
-                isChecked
-                        ? mDefaultTriggerLevelForOn
-                        : 0);
+        BatterySaverUtils.setAutoBatterySaverTriggerLevel(mContext,
+                isChecked ? mDefaultTriggerLevelForOn : 0);
         return true;
     }
 }
diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java
index 98eb23e..5686d6e 100644
--- a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java
+++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java
@@ -39,9 +39,8 @@
 public class AnomalyConfigJobService extends JobService {
     private static final String TAG = "AnomalyConfigJobService";
 
-    @VisibleForTesting
-    static final String PREF_DB = "anomaly_pref";
-    private static final String KEY_ANOMALY_CONFIG_VERSION = "anomaly_config_version";
+    public static final String PREF_DB = "anomaly_pref";
+    public static final String KEY_ANOMALY_CONFIG_VERSION = "anomaly_config_version";
     private static final int DEFAULT_VERSION = 0;
 
     @VisibleForTesting
diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java
index dcacaae..bad1c11 100644
--- a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java
+++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java
@@ -48,13 +48,4 @@
             }
         }
     }
-
-    @VisibleForTesting
-    void uploadPendingIntent(StatsManager statsManager, PendingIntent pendingIntent) {
-        Log.i(TAG, "Upload PendingIntent to StatsManager. configKey: "
-                + StatsManagerConfig.ANOMALY_CONFIG_KEY + " subId: "
-                + StatsManagerConfig.SUBSCRIBER_ID);
-        statsManager.setBroadcastSubscriber(StatsManagerConfig.ANOMALY_CONFIG_KEY,
-                StatsManagerConfig.SUBSCRIBER_ID, pendingIntent);
-    }
 }
diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java
index 5bf393a..8928efd 100644
--- a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java
+++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java
@@ -59,9 +59,11 @@
 /** A JobService to store anomaly data to anomaly database */
 public class AnomalyDetectionJobService extends JobService {
     private static final String TAG = "AnomalyDetectionService";
-    private static final int UID_NULL = 0;
-    private static final int STATSD_UID_FILED = 1;
     private static final int ON = 1;
+    @VisibleForTesting
+    static final int UID_NULL = -1;
+    @VisibleForTesting
+    static final int STATSD_UID_FILED = 1;
 
     @VisibleForTesting
     static final long MAX_DELAY_MS = TimeUnit.MINUTES.toMillis(30);
@@ -143,7 +145,8 @@
                     : Settings.Global.getInt(contentResolver,
                             Settings.Global.APP_AUTO_RESTRICTION_ENABLED, ON) == ON;
             final String packageName = batteryUtils.getPackageName(uid);
-            if (!isSystemUid(uid) && !powerWhitelistBackend.isSysWhitelistedExceptIdle(
+            if (uid != UID_NULL && !isSystemUid(uid)
+                    && !powerWhitelistBackend.isSysWhitelistedExceptIdle(
                     packageManager.getPackagesForUid(uid))) {
                 boolean anomalyDetected = true;
                 if (anomalyInfo.anomalyType
@@ -191,7 +194,6 @@
      */
     @VisibleForTesting
     int extractUidFromStatsDimensionsValue(StatsDimensionsValue statsDimensionsValue) {
-        //TODO(b/73172999): Add robo test for this method
         if (statsDimensionsValue == null) {
             return UID_NULL;
         }
diff --git a/src/com/android/settings/gestures/AssistGestureSettings.java b/src/com/android/settings/gestures/AssistGestureSettings.java
index 84f4ab2..df2dd93 100644
--- a/src/com/android/settings/gestures/AssistGestureSettings.java
+++ b/src/com/android/settings/gestures/AssistGestureSettings.java
@@ -82,9 +82,11 @@
 
                 @Override
                 protected boolean isPageSearchEnabled(Context context) {
-                    return new AssistGestureSettingsPreferenceController(context,
-                            null /* lifecycle */, null /* key */, false /* assistOnly */)
-                            .isAvailable();
+                    AssistGestureSettingsPreferenceController controller =
+                            new AssistGestureSettingsPreferenceController(context,
+                                    "gesture_assist_input_summary");
+                    controller.setAssistOnly(false);
+                    return controller.isAvailable();
                 }
             };
 }
diff --git a/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java b/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
index 1ecba0d..fd94f9f 100644
--- a/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
+++ b/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
@@ -24,7 +24,6 @@
 import android.provider.Settings;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.TwoStatePreference;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
@@ -32,11 +31,8 @@
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.InlineSwitchPayload;
 import com.android.settings.search.ResultPayload;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.core.lifecycle.events.OnResume;
 
-public class AssistGestureSettingsPreferenceController extends GesturePreferenceController
-        implements OnResume {
+public class AssistGestureSettingsPreferenceController extends GesturePreferenceController {
 
     private static final String PREF_KEY_VIDEO = "gesture_assist_video";
 
@@ -55,30 +51,25 @@
     @VisibleForTesting
     boolean mAssistOnly;
 
-    public AssistGestureSettingsPreferenceController(Context context, Lifecycle lifecycle,
-            String key, boolean assistOnly) {
-        super(context, lifecycle);
+    public AssistGestureSettingsPreferenceController(Context context,
+            String key) {
+        super(context, key);
         mFeatureProvider = FeatureFactory.getFactory(context).getAssistGestureFeatureProvider();
         mWasAvailable = isAvailable();
         mAssistGesturePrefKey = key;
-        mAssistOnly = assistOnly;
     }
 
     @Override
-    public boolean isAvailable() {
-        if (mAssistOnly) {
-            return mFeatureProvider.isSupported(mContext);
-        } else {
-            return mFeatureProvider.isSensorAvailable(mContext);
-        }
+    public int getAvailabilityStatus() {
+        final boolean isAvailable = mAssistOnly ? mFeatureProvider.isSupported(mContext)
+                : mFeatureProvider.isSensorAvailable(mContext);
+        return isAvailable ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
     public void displayPreference(PreferenceScreen screen) {
         mScreen = screen;
         mPreference = screen.findPreference(getPreferenceKey());
-        // Call super last or AbstractPreferenceController might remove the preference from the
-        // screen (if !isAvailable()) before we can save a reference to it.
         super.displayPreference(screen);
     }
 
@@ -92,6 +83,11 @@
         }
     }
 
+    public AssistGestureSettingsPreferenceController setAssistOnly(boolean assistOnly) {
+        mAssistOnly = assistOnly;
+        return this;
+    }
+
     private void updatePreference() {
         if (mPreference == null) {
             return;
@@ -117,31 +113,9 @@
     }
 
     @Override
-    public void updateState(Preference preference) {
-        boolean isEnabled = isAssistGestureEnabled() && mFeatureProvider.isSupported(mContext);
-
-        if (!mAssistOnly) {
-            isEnabled = isEnabled || isSilenceGestureEnabled();
-        }
-
-        if (preference != null) {
-            if (preference instanceof TwoStatePreference) {
-                ((TwoStatePreference) preference).setChecked(isSwitchPrefEnabled());
-            } else {
-                preference.setSummary(isEnabled
-                        ? R.string.gesture_setting_on
-                        : R.string.gesture_setting_off);
-            }
-        }
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final boolean enabled = (boolean) newValue;
-        Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY_ASSIST,
-                enabled ? ON : OFF);
-        updateState(preference);
-        return true;
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY_ASSIST,
+                isChecked ? ON : OFF);
     }
 
     @Override
@@ -150,17 +124,22 @@
     }
 
     @Override
-    public String getPreferenceKey() {
-        return mAssistGesturePrefKey;
+    public CharSequence getSummary() {
+        boolean isEnabled = isAssistGestureEnabled() && mFeatureProvider.isSupported(mContext);
+        if (!mAssistOnly) {
+            isEnabled = isEnabled || isSilenceGestureEnabled();
+        }
+        return mContext.getText(
+                isEnabled ? R.string.gesture_setting_on : R.string.gesture_setting_off);
     }
 
     @Override
-    protected boolean isSwitchPrefEnabled() {
-        // Does nothing
-        return true;
+    public boolean isChecked() {
+        return Settings.Secure.getInt(mContext.getContentResolver(), SECURE_KEY_ASSIST, OFF) == ON;
     }
 
     @Override
+    //TODO (b/69808376): Remove result payload
     public ResultPayload getResultPayload() {
         final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 AssistGestureSettings.class.getName(), mAssistGesturePrefKey,
diff --git a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
index 049ee18..aebda18 100644
--- a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
@@ -23,13 +23,11 @@
 import android.content.SharedPreferences;
 import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
-import android.support.v7.preference.Preference;
 
 import com.android.settings.R;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.InlineSwitchPayload;
 import com.android.settings.search.ResultPayload;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class DoubleTapPowerPreferenceController extends GesturePreferenceController {
 
@@ -43,8 +41,8 @@
 
     private final String SECURE_KEY = CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED;
 
-    public DoubleTapPowerPreferenceController(Context context, Lifecycle lifecycle, String key) {
-        super(context, lifecycle);
+    public DoubleTapPowerPreferenceController(Context context, String key) {
+        super(context, key);
         mDoubleTapPowerKey = key;
     }
 
@@ -59,8 +57,8 @@
     }
 
     @Override
-    public boolean isAvailable() {
-        return isGestureAvailable(mContext);
+    public int getAvailabilityStatus() {
+        return isGestureAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
@@ -69,25 +67,20 @@
     }
 
     @Override
-    public String getPreferenceKey() {
-        return mDoubleTapPowerKey;
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        boolean enabled = (boolean) newValue;
-        Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY, enabled ? ON : OFF);
-        return true;
-    }
-
-    @Override
-    protected boolean isSwitchPrefEnabled() {
+    public boolean isChecked() {
         final int cameraDisabled = Settings.Secure.getInt(mContext.getContentResolver(),
                 SECURE_KEY, ON);
         return cameraDisabled == ON;
     }
 
     @Override
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY,
+                isChecked ? ON : OFF);
+    }
+
+    @Override
+    //TODO (b/69808376): Remove result payload
     public ResultPayload getResultPayload() {
         final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 DoubleTapPowerSettings.class.getName(), mDoubleTapPowerKey,
diff --git a/src/com/android/settings/gestures/DoubleTapPowerSettings.java b/src/com/android/settings/gestures/DoubleTapPowerSettings.java
index 6b15923..6eec6cd 100644
--- a/src/com/android/settings/gestures/DoubleTapPowerSettings.java
+++ b/src/com/android/settings/gestures/DoubleTapPowerSettings.java
@@ -26,17 +26,13 @@
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
 public class DoubleTapPowerSettings extends DashboardFragment {
 
     private static final String TAG = "DoubleTapPower";
-    private static final String KEY_DOUBLE_TAP_POWER = "gesture_double_tap_power";
 
     public static final String PREF_KEY_SUGGESTION_COMPLETE =
             "pref_double_tap_power_suggestion_complete";
@@ -65,19 +61,6 @@
         return R.xml.double_tap_power_settings;
     }
 
-    @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, getLifecycle());
-    }
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            Lifecycle lifecycle) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new DoubleTapPowerPreferenceController(context, lifecycle,
-                KEY_DOUBLE_TAP_POWER));
-        return controllers;
-    }
-
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
@@ -87,11 +70,5 @@
                     sir.xmlResId = R.xml.double_tap_power_settings;
                     return Arrays.asList(sir);
                 }
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(
-                        Context context) {
-                    return buildPreferenceControllers(context, null /* lifecycle */);
-                }
             };
 }
diff --git a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
index aa08e6f..00fb956 100644
--- a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.support.v7.preference.Preference;
 import android.support.annotation.VisibleForTesting;
@@ -29,7 +30,6 @@
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.InlineSwitchPayload;
 import com.android.settings.search.ResultPayload;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import static android.provider.Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP;
 
@@ -43,18 +43,21 @@
 
     private final String SECURE_KEY = DOZE_PULSE_ON_DOUBLE_TAP;
 
-    private final AmbientDisplayConfiguration mAmbientConfig;
+    private AmbientDisplayConfiguration mAmbientConfig;
     @UserIdInt
     private final int mUserId;
 
-    public DoubleTapScreenPreferenceController(Context context, Lifecycle lifecycle,
-            AmbientDisplayConfiguration config, @UserIdInt int userId, String key) {
-        super(context, lifecycle);
-        mAmbientConfig = config;
-        mUserId = userId;
+    public DoubleTapScreenPreferenceController(Context context, String key) {
+        super(context, key);
+        mUserId = UserHandle.myUserId();
         mDoubleTapScreenPrefKey = key;
     }
 
+    public DoubleTapScreenPreferenceController setConfig(AmbientDisplayConfiguration config) {
+        mAmbientConfig = config;
+        return this;
+    }
+
     public static boolean isSuggestionComplete(Context context, SharedPreferences prefs) {
         return isSuggestionComplete(new AmbientDisplayConfiguration(context), prefs);
     }
@@ -67,20 +70,17 @@
     }
 
     @Override
-    public boolean isAvailable() {
-        return mAmbientConfig.pulseOnDoubleTapAvailable();
+    public int getAvailabilityStatus() {
+        if (mAmbientConfig == null) {
+            mAmbientConfig = new AmbientDisplayConfiguration(mContext);
+        }
+        return mAmbientConfig.pulseOnDoubleTapAvailable() ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
-    public String getPreferenceKey() {
-        return mDoubleTapScreenPrefKey;
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final boolean enabled = (boolean) newValue;
-        Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY, enabled ? ON : OFF);
-        return true;
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY,
+                isChecked ? ON : OFF);
     }
 
     @Override
@@ -89,11 +89,12 @@
     }
 
     @Override
-    protected boolean isSwitchPrefEnabled() {
+    public boolean isChecked() {
         return mAmbientConfig.pulseOnDoubleTapEnabled(mUserId);
     }
 
     @Override
+    //TODO (b/69808376): Remove result payload
     public ResultPayload getResultPayload() {
         final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 DoubleTapScreenSettings.class.getName(), mDoubleTapScreenPrefKey,
diff --git a/src/com/android/settings/gestures/DoubleTapScreenSettings.java b/src/com/android/settings/gestures/DoubleTapScreenSettings.java
index 1f0ff03..29e0a1a 100644
--- a/src/com/android/settings/gestures/DoubleTapScreenSettings.java
+++ b/src/com/android/settings/gestures/DoubleTapScreenSettings.java
@@ -28,8 +28,6 @@
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -38,7 +36,6 @@
 public class DoubleTapScreenSettings extends DashboardFragment {
 
     private static final String TAG = "DoubleTapScreen";
-    private static final String KEY_DOUBLE_TAP_SCREEN = "gesture_double_tap_screen";
 
     public static final String PREF_KEY_SUGGESTION_COMPLETE =
             "pref_double_tap_screen_suggestion_complete";
@@ -50,6 +47,9 @@
                 .getSuggestionFeatureProvider(context);
         SharedPreferences prefs = suggestionFeatureProvider.getSharedPrefs(context);
         prefs.edit().putBoolean(PREF_KEY_SUGGESTION_COMPLETE, true).apply();
+
+        use(DoubleTapScreenPreferenceController.class)
+            .setConfig(new AmbientDisplayConfiguration(context));
     }
 
     @Override
@@ -72,20 +72,6 @@
         return R.string.help_url_double_tap_screen;
     }
 
-    @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, getLifecycle());
-    }
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            Lifecycle lifecycle) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new DoubleTapScreenPreferenceController(context, lifecycle,
-                new AmbientDisplayConfiguration(context), UserHandle.myUserId(),
-                KEY_DOUBLE_TAP_SCREEN));
-        return controllers;
-    }
-
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
@@ -95,11 +81,5 @@
                     sir.xmlResId = R.xml.double_tap_screen_settings;
                     return Arrays.asList(sir);
                 }
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(
-                        Context context) {
-                    return buildPreferenceControllers(context, null /* lifecycle */);
-                }
             };
 }
diff --git a/src/com/android/settings/gestures/DoubleTwistGestureSettings.java b/src/com/android/settings/gestures/DoubleTwistGestureSettings.java
index 69517fe..a3f37f0 100644
--- a/src/com/android/settings/gestures/DoubleTwistGestureSettings.java
+++ b/src/com/android/settings/gestures/DoubleTwistGestureSettings.java
@@ -26,17 +26,13 @@
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
 public class DoubleTwistGestureSettings extends DashboardFragment {
 
     private static final String TAG = "DoubleTwistGesture";
-    private static final String KEY_DOUBLE_TWIST = "gesture_double_twist";
 
     public static final String PREF_KEY_SUGGESTION_COMPLETE =
             "pref_double_twist_suggestion_complete";
@@ -65,18 +61,6 @@
         return R.xml.double_twist_gesture_settings;
     }
 
-    @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, getLifecycle());
-    }
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            Lifecycle lifecycle) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new DoubleTwistPreferenceController(context, lifecycle, KEY_DOUBLE_TWIST));
-        return controllers;
-    }
-
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
@@ -86,11 +70,6 @@
                     sir.xmlResId = R.xml.double_twist_gesture_settings;
                     return Arrays.asList(sir);
                 }
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-                    return buildPreferenceControllers(context, null /* lifecycle */);
-                }
             };
 
 }
diff --git a/src/com/android/settings/gestures/DoubleTwistPreferenceController.java b/src/com/android/settings/gestures/DoubleTwistPreferenceController.java
index 922f74b..f819508 100644
--- a/src/com/android/settings/gestures/DoubleTwistPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTwistPreferenceController.java
@@ -25,12 +25,10 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
-import android.support.v7.preference.Preference;
 import android.text.TextUtils;
 
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class DoubleTwistPreferenceController extends GesturePreferenceController {
 
@@ -41,8 +39,8 @@
     private final String mDoubleTwistPrefKey;
     private final UserManager mUserManager;
 
-    public DoubleTwistPreferenceController(Context context, Lifecycle lifecycle, String key) {
-        super(context, lifecycle);
+    public DoubleTwistPreferenceController(Context context, String key) {
+        super(context, key);
         mDoubleTwistPrefKey = key;
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
     }
@@ -69,8 +67,8 @@
     }
 
     @Override
-    public boolean isAvailable() {
-        return isGestureAvailable(mContext);
+    public int getAvailabilityStatus() {
+        return isGestureAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
@@ -84,9 +82,8 @@
     }
 
     @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final int enabled = (boolean) newValue ? ON : OFF;
-        setDoubleTwistPreference(mContext, mUserManager, enabled);
+    public boolean setChecked(boolean isChecked) {
+        setDoubleTwistPreference(mContext, mUserManager, isChecked ? ON : OFF);
         return true;
     }
 
@@ -97,12 +94,13 @@
         final int managedProfileUserId = getManagedProfileId(userManager);
         if (managedProfileUserId != UserHandle.USER_NULL) {
             Settings.Secure.putIntForUser(context.getContentResolver(),
-                Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, enabled, managedProfileUserId);
+                    Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, enabled,
+                    managedProfileUserId);
         }
     }
 
     @Override
-    protected boolean isSwitchPrefEnabled() {
+    public boolean isChecked() {
         final int doubleTwistEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, ON);
         return doubleTwistEnabled != 0;
diff --git a/src/com/android/settings/gestures/GesturePreferenceController.java b/src/com/android/settings/gestures/GesturePreferenceController.java
index a7f8997..7f1100b 100644
--- a/src/com/android/settings/gestures/GesturePreferenceController.java
+++ b/src/com/android/settings/gestures/GesturePreferenceController.java
@@ -24,19 +24,17 @@
 import android.support.v7.preference.TwoStatePreference;
 
 import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.core.TogglePreferenceController;
 import com.android.settings.widget.VideoPreference;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnCreate;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
 
-public abstract class GesturePreferenceController extends AbstractPreferenceController
-        implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
-        LifecycleObserver, OnResume, OnPause, OnCreate, OnSaveInstanceState  {
+public abstract class GesturePreferenceController extends TogglePreferenceController
+        implements Preference.OnPreferenceChangeListener,
+        LifecycleObserver, OnResume, OnPause, OnCreate, OnSaveInstanceState {
 
     @VisibleForTesting
     static final String KEY_VIDEO_PAUSED = "key_video_paused";
@@ -45,11 +43,8 @@
     @VisibleForTesting
     boolean mVideoPaused;
 
-    public GesturePreferenceController(Context context, Lifecycle lifecycle) {
-        super(context);
-        if (lifecycle != null) {
-            lifecycle.addObserver(this);
-        }
+    public GesturePreferenceController(Context context, String key) {
+        super(context, key);
     }
 
     @Override
@@ -63,14 +58,9 @@
     @Override
     public void updateState(Preference preference) {
         super.updateState(preference);
-        final boolean isEnabled = isSwitchPrefEnabled();
         if (preference != null) {
-            if (preference instanceof TwoStatePreference) {
-                ((TwoStatePreference) preference).setChecked(isEnabled);
-            } else {
-                preference.setSummary(isEnabled
-                        ? R.string.gesture_setting_on
-                        : R.string.gesture_setting_off);
+            if (!(preference instanceof TwoStatePreference)) {
+                preference.setSummary(getSummary());
             }
             // Different meanings of "Enabled" for the Preference and Controller.
             preference.setEnabled(canHandleClicks());
@@ -78,6 +68,12 @@
     }
 
     @Override
+    public CharSequence getSummary() {
+        return mContext.getText(
+                isChecked() ? R.string.gesture_setting_on : R.string.gesture_setting_off);
+    }
+
+    @Override
     public void onCreate(Bundle savedInstanceState) {
         if (savedInstanceState != null) {
             mVideoPaused = savedInstanceState.getBoolean(KEY_VIDEO_PAUSED, false);
@@ -106,8 +102,6 @@
 
     protected abstract String getVideoPrefKey();
 
-    protected abstract boolean isSwitchPrefEnabled();
-
     protected boolean canHandleClicks() {
         return true;
     }
diff --git a/src/com/android/settings/gestures/GestureSettings.java b/src/com/android/settings/gestures/GestureSettings.java
index b3f8b79..f6fe82c 100644
--- a/src/com/android/settings/gestures/GestureSettings.java
+++ b/src/com/android/settings/gestures/GestureSettings.java
@@ -65,33 +65,32 @@
 
     @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        if (mAmbientDisplayConfig == null) {
-            mAmbientDisplayConfig = new AmbientDisplayConfiguration(context);
-        }
-
-        return buildPreferenceControllers(context, getLifecycle(), mAmbientDisplayConfig);
+        return buildPreferenceControllers(context, getLifecycle());
     }
 
     static List<AbstractPreferenceController> buildPreferenceControllers(
-            @NonNull Context context, @Nullable Lifecycle lifecycle,
-            @NonNull AmbientDisplayConfiguration ambientDisplayConfiguration) {
+            @NonNull Context context, @Nullable Lifecycle lifecycle) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new AssistGestureSettingsPreferenceController(context, lifecycle,
-                KEY_ASSIST, false /* assistOnly */));
-        controllers.add(new SwipeToNotificationPreferenceController(context, lifecycle,
-                KEY_SWIPE_DOWN));
-        controllers.add(new DoubleTwistPreferenceController(context, lifecycle, KEY_DOUBLE_TWIST));
-        controllers.add(new DoubleTapPowerPreferenceController(context, lifecycle,
-                KEY_DOUBLE_TAP_POWER));
-        controllers.add(new PickupGesturePreferenceController(context, lifecycle,
-                ambientDisplayConfiguration, UserHandle.myUserId(), KEY_PICK_UP));
-        controllers.add(new DoubleTapScreenPreferenceController(context, lifecycle,
-                ambientDisplayConfiguration, UserHandle.myUserId(), KEY_DOUBLE_TAP_SCREEN));
         controllers.add(new PreventRingingPreferenceController(
                 context, lifecycle, UserHandle.myUserId(), KEY_PREVENT_RINGING));
         return controllers;
     }
 
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        use(AssistGestureSettingsPreferenceController.class).setAssistOnly(false);
+        use(PickupGesturePreferenceController.class).setConfig(getConfig(context));
+        use(DoubleTapScreenPreferenceController.class).setConfig(getConfig(context));
+    }
+
+    private AmbientDisplayConfiguration getConfig(Context context) {
+        if (mAmbientDisplayConfig == null) {
+            mAmbientDisplayConfig = new AmbientDisplayConfiguration(context);
+        }
+        return mAmbientDisplayConfig;
+    }
+
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
@@ -105,8 +104,7 @@
                 @Override
                 public List<AbstractPreferenceController> createPreferenceControllers(
                         Context context) {
-                    return buildPreferenceControllers(context, null,
-                            new AmbientDisplayConfiguration(context));
+                    return buildPreferenceControllers(context, null);
                 }
 
                 @Override
diff --git a/src/com/android/settings/gestures/GesturesSettingPreferenceController.java b/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
index 1df5b90..e4e24d8 100644
--- a/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
+++ b/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
@@ -19,6 +19,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.provider.Settings;
+import android.support.annotation.NonNull;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.settings.R;
@@ -33,6 +34,7 @@
     private List<AbstractPreferenceController> mGestureControllers;
 
     private static final String KEY_GESTURES_SETTINGS = "gesture_settings";
+    private static final String FAKE_PREF_KEY = "fake_key_only_for_get_available";
 
     public GesturesSettingPreferenceController(Context context) {
         super(context, KEY_GESTURES_SETTINGS);
@@ -42,16 +44,38 @@
     @Override
     public int getAvailabilityStatus() {
         if (mGestureControllers == null) {
-            mGestureControllers = GestureSettings.buildPreferenceControllers(mContext,
-                    null /* lifecycle */, new AmbientDisplayConfiguration(mContext));
+            mGestureControllers = buildAllPreferenceControllers(mContext);
         }
         boolean isAvailable = false;
         for (AbstractPreferenceController controller : mGestureControllers) {
             isAvailable = isAvailable || controller.isAvailable();
         }
-        return isAvailable
-                ? AVAILABLE
-                : DISABLED_UNSUPPORTED;
+        return isAvailable ? AVAILABLE : DISABLED_UNSUPPORTED;
+    }
+
+    /**
+     * Get all controllers for their availability status when doing getAvailabilityStatus.
+     * Do not use this method to add controllers into fragment, most of below controllers already
+     * convert to TogglePreferenceController, please register them in xml.
+     * The key is fake because those controllers won't be use to control preference.
+     */
+    private static List<AbstractPreferenceController> buildAllPreferenceControllers(
+            @NonNull Context context) {
+        final AmbientDisplayConfiguration ambientDisplayConfiguration =
+                new AmbientDisplayConfiguration(context);
+        final List<AbstractPreferenceController> controllers =
+                GestureSettings.buildPreferenceControllers(context, null);
+
+        controllers.add(new AssistGestureSettingsPreferenceController(context, FAKE_PREF_KEY)
+                .setAssistOnly(false));
+        controllers.add(new SwipeToNotificationPreferenceController(context, FAKE_PREF_KEY));
+        controllers.add(new DoubleTwistPreferenceController(context, FAKE_PREF_KEY));
+        controllers.add(new DoubleTapPowerPreferenceController(context, FAKE_PREF_KEY));
+        controllers.add(new PickupGesturePreferenceController(context, FAKE_PREF_KEY)
+                .setConfig(ambientDisplayConfiguration));
+        controllers.add(new DoubleTapScreenPreferenceController(context, FAKE_PREF_KEY)
+                .setConfig(ambientDisplayConfiguration));
+        return controllers;
     }
 
     @Override
diff --git a/src/com/android/settings/gestures/PickupGesturePreferenceController.java b/src/com/android/settings/gestures/PickupGesturePreferenceController.java
index 02107c1..46318f5 100644
--- a/src/com/android/settings/gestures/PickupGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/PickupGesturePreferenceController.java
@@ -22,8 +22,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.os.UserHandle;
 import android.provider.Settings;
-import android.support.v7.preference.Preference;
 import android.support.annotation.VisibleForTesting;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
@@ -31,7 +31,6 @@
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.InlineSwitchPayload;
 import com.android.settings.search.ResultPayload;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class PickupGesturePreferenceController extends GesturePreferenceController {
 
@@ -43,18 +42,21 @@
 
     private final String SECURE_KEY = DOZE_PULSE_ON_PICK_UP;
 
-    private final AmbientDisplayConfiguration mAmbientConfig;
+    private AmbientDisplayConfiguration mAmbientConfig;
     @UserIdInt
     private final int mUserId;
 
-    public PickupGesturePreferenceController(Context context, Lifecycle lifecycle,
-            AmbientDisplayConfiguration config, @UserIdInt int userId, String key) {
-        super(context, lifecycle);
-        mAmbientConfig = config;
-        mUserId = userId;
+    public PickupGesturePreferenceController(Context context, String key) {
+        super(context, key);
+        mUserId = UserHandle.myUserId();
         mPickUpPrefKey = key;
     }
 
+    public PickupGesturePreferenceController setConfig(AmbientDisplayConfiguration config) {
+        mAmbientConfig = config;
+        return this;
+    }
+
     public static boolean isSuggestionComplete(Context context, SharedPreferences prefs) {
         AmbientDisplayConfiguration ambientConfig = new AmbientDisplayConfiguration(context);
         return prefs.getBoolean(PickupGestureSettings.PREF_KEY_SUGGESTION_COMPLETE, false)
@@ -62,8 +64,11 @@
     }
 
     @Override
-    public boolean isAvailable() {
-        return mAmbientConfig.pulseOnPickupAvailable();
+    public int getAvailabilityStatus() {
+        if (mAmbientConfig == null) {
+            mAmbientConfig = new AmbientDisplayConfiguration(mContext);
+        }
+        return mAmbientConfig.pulseOnPickupAvailable() ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
@@ -72,7 +77,7 @@
     }
 
     @Override
-    protected boolean isSwitchPrefEnabled() {
+    public boolean isChecked() {
         return mAmbientConfig.pulseOnPickupEnabled(mUserId);
     }
 
@@ -82,11 +87,9 @@
     }
 
     @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final boolean enabled = (boolean) newValue;
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                SECURE_KEY, enabled ? ON : OFF);
-        return true;
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY,
+                isChecked ? ON : OFF);
     }
 
     @Override
diff --git a/src/com/android/settings/gestures/PickupGestureSettings.java b/src/com/android/settings/gestures/PickupGestureSettings.java
index 78ae9c4..8f4e7b3 100644
--- a/src/com/android/settings/gestures/PickupGestureSettings.java
+++ b/src/com/android/settings/gestures/PickupGestureSettings.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.os.UserHandle;
 import android.provider.SearchIndexableResource;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
@@ -28,17 +27,13 @@
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
 public class PickupGestureSettings extends DashboardFragment {
 
     private static final String TAG = "PickupGestureSettings";
-    private static final String KEY_PICK_UP = "gesture_pick_up";
 
     public static final String PREF_KEY_SUGGESTION_COMPLETE =
             "pref_pickup_gesture_suggestion_complete";
@@ -50,6 +45,9 @@
                 .getSuggestionFeatureProvider(context);
         SharedPreferences prefs = suggestionFeatureProvider.getSharedPrefs(context);
         prefs.edit().putBoolean(PREF_KEY_SUGGESTION_COMPLETE, true).apply();
+
+        use(PickupGesturePreferenceController.class)
+            .setConfig(new AmbientDisplayConfiguration(context));
     }
 
     @Override
@@ -72,19 +70,6 @@
         return R.string.help_url_pickup_gesture;
     }
 
-    @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, getLifecycle());
-    }
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            Lifecycle lifecycle) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new PickupGesturePreferenceController(context, lifecycle,
-                new AmbientDisplayConfiguration(context), UserHandle.myUserId(), KEY_PICK_UP));
-        return controllers;
-    }
-
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
@@ -94,12 +79,6 @@
                     sir.xmlResId = R.xml.pick_up_gesture_settings;
                     return Arrays.asList(sir);
                 }
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(
-                        Context context) {
-                    return buildPreferenceControllers(context, null /* lifecycle */);
-                }
             };
 
 }
diff --git a/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java b/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
index b50968f..d755d72 100644
--- a/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
+++ b/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
@@ -21,10 +21,8 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.provider.Settings;
-import android.support.v7.preference.Preference;
 
 import com.android.settings.Utils;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class SwipeToNotificationPreferenceController extends GesturePreferenceController {
 
@@ -32,14 +30,11 @@
     private static final int OFF = 0;
 
     private static final String PREF_KEY_VIDEO = "gesture_swipe_down_fingerprint_video";
-    private final String mSwipeDownFingerPrefKey;
 
     private static final String SECURE_KEY = SYSTEM_NAVIGATION_KEYS_ENABLED;
 
-    public SwipeToNotificationPreferenceController(Context context, Lifecycle lifecycle,
-            String key) {
-        super(context, lifecycle);
-        mSwipeDownFingerPrefKey = key;
+    public SwipeToNotificationPreferenceController(Context context, String key) {
+        super(context, key);
     }
 
     public static boolean isSuggestionComplete(Context context, SharedPreferences prefs) {
@@ -55,28 +50,23 @@
     }
 
     @Override
-    public String getPreferenceKey() {
-        return mSwipeDownFingerPrefKey;
-    }
-
-    @Override
     protected String getVideoPrefKey() {
         return PREF_KEY_VIDEO;
     }
 
     @Override
-    public boolean isAvailable() {
-        return SwipeToNotificationPreferenceController.isAvailable(mContext);
+    public int getAvailabilityStatus() {
+        return isAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        setSwipeToNotification(mContext, (boolean) newValue);
+    public boolean setChecked(boolean isChecked) {
+        setSwipeToNotification(mContext, isChecked);
         return true;
     }
 
     @Override
-    protected boolean isSwitchPrefEnabled() {
+    public boolean isChecked() {
         return isSwipeToNotificationOn(mContext);
     }
 
diff --git a/src/com/android/settings/gestures/SwipeToNotificationSettings.java b/src/com/android/settings/gestures/SwipeToNotificationSettings.java
index 9ddf0d4..c18289c 100644
--- a/src/com/android/settings/gestures/SwipeToNotificationSettings.java
+++ b/src/com/android/settings/gestures/SwipeToNotificationSettings.java
@@ -26,10 +26,7 @@
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -37,8 +34,6 @@
 
     private static final String TAG = "SwipeToNotifSettings";
 
-    private static final String KEY = "gesture_swipe_down_fingerprint";
-
     public static final String PREF_KEY_SUGGESTION_COMPLETE =
             "pref_swipe_to_notification_suggestion_complete";
 
@@ -66,18 +61,6 @@
         return R.xml.swipe_to_notification_settings;
     }
 
-    @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, getLifecycle());
-    }
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            Lifecycle lifecycle) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new SwipeToNotificationPreferenceController(context, lifecycle, KEY));
-        return controllers;
-    }
-
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
@@ -87,11 +70,5 @@
                     sir.xmlResId = R.xml.swipe_to_notification_settings;
                     return Arrays.asList(sir);
                 }
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(
-                        Context context) {
-                    return buildPreferenceControllers(context, null /* lifecycle */);
-                }
             };
 }
diff --git a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
index 71a3e0d..178aa27 100644
--- a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
+++ b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
@@ -53,7 +53,7 @@
 import java.util.Map;
 
 /**
- * Dialog to set the private dns
+ * Dialog to set the Private DNS
  */
 public class PrivateDnsModeDialogPreference extends CustomDialogPreference implements
         DialogInterface.OnClickListener, RadioGroup.OnCheckedChangeListener, TextWatcher {
@@ -78,6 +78,15 @@
     @VisibleForTesting
     static final String HOSTNAME_KEY = Settings.Global.PRIVATE_DNS_SPECIFIER;
 
+    public static String getModeFromSettings(ContentResolver cr) {
+        final String mode = Settings.Global.getString(cr, MODE_KEY);
+        return PRIVATE_DNS_MAP.containsKey(mode) ? mode : PRIVATE_DNS_MODE_OPPORTUNISTIC;
+    }
+
+    public static String getHostnameFromSettings(ContentResolver cr) {
+        return Settings.Global.getString(cr, HOSTNAME_KEY);
+    }
+
     @VisibleForTesting
     EditText mEditText;
     @VisibleForTesting
@@ -121,9 +130,12 @@
     protected void onBindDialogView(View view) {
         final Context context = getContext();
         final ContentResolver contentResolver = context.getContentResolver();
+
+        mMode = getModeFromSettings(context.getContentResolver());
+
         mEditText = view.findViewById(R.id.private_dns_mode_provider_hostname);
         mEditText.addTextChangedListener(this);
-        mEditText.setText(Settings.Global.getString(contentResolver, HOSTNAME_KEY));
+        mEditText.setText(getHostnameFromSettings(contentResolver));
 
         mRadioGroup = view.findViewById(R.id.private_dns_radio_group);
         mRadioGroup.setOnCheckedChangeListener(this);
diff --git a/src/com/android/settings/network/PrivateDnsPreferenceController.java b/src/com/android/settings/network/PrivateDnsPreferenceController.java
index e317530..50224ca 100644
--- a/src/com/android/settings/network/PrivateDnsPreferenceController.java
+++ b/src/com/android/settings/network/PrivateDnsPreferenceController.java
@@ -16,19 +16,46 @@
 
 package com.android.settings.network;
 
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+
 import android.content.Context;
+import android.content.ContentResolver;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 
+
 public class PrivateDnsPreferenceController extends BasePreferenceController
-        implements PreferenceControllerMixin, LifecycleObserver {
+        implements PreferenceControllerMixin, LifecycleObserver, OnStart, OnStop {
     private static final String KEY_PRIVATE_DNS_SETTINGS = "private_dns_settings";
 
+    private static final Uri[] SETTINGS_URIS = new Uri[]{
+        Settings.Global.getUriFor(Settings.Global.PRIVATE_DNS_MODE),
+        Settings.Global.getUriFor(Settings.Global.PRIVATE_DNS_SPECIFIER),
+    };
+
+    private final Handler mHandler;
+    private final ContentObserver mSettingsObserver;
+    private Preference mPreference;
+
     public PrivateDnsPreferenceController(Context context) {
         super(context, KEY_PRIVATE_DNS_SETTINGS);
+        mHandler = new Handler(Looper.getMainLooper());
+        mSettingsObserver = new PrivateDnsSettingsObserver(mHandler);
     }
 
     @Override
@@ -40,4 +67,52 @@
     public int getAvailabilityStatus() {
         return AVAILABLE;
     }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
+    @Override
+    public void onStart() {
+        for (Uri uri : SETTINGS_URIS) {
+            mContext.getContentResolver().registerContentObserver(uri, false, mSettingsObserver);
+        }
+    }
+
+    @Override
+    public void onStop() {
+        mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        final Resources res = mContext.getResources();
+        final ContentResolver cr = mContext.getContentResolver();
+        final String mode = PrivateDnsModeDialogPreference.getModeFromSettings(cr);
+        switch (mode) {
+            case PRIVATE_DNS_MODE_OFF:
+                return res.getString(R.string.private_dns_mode_off);
+            case PRIVATE_DNS_MODE_OPPORTUNISTIC:
+                return res.getString(R.string.private_dns_mode_opportunistic);
+            case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
+                return PrivateDnsModeDialogPreference.getHostnameFromSettings(cr);
+        }
+        return "";
+    }
+
+    private class PrivateDnsSettingsObserver extends ContentObserver {
+        public PrivateDnsSettingsObserver(Handler h) {
+            super(h);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            if (mPreference != null) {
+                PrivateDnsPreferenceController.this.updateState(mPreference);
+            }
+        }
+    }
 }
diff --git a/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceController.java b/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceController.java
index bad626a..03032c5 100644
--- a/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceController.java
+++ b/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceController.java
@@ -24,6 +24,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.accounts.AccountRestrictionHelper;
 import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.core.SliderPreferenceController;
 import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.core.AbstractPreferenceController;
 
@@ -32,17 +33,18 @@
  * restriction
  */
 public abstract class AdjustVolumeRestrictedPreferenceController extends
-        AbstractPreferenceController implements PreferenceControllerMixin {
+        SliderPreferenceController implements PreferenceControllerMixin {
 
     private AccountRestrictionHelper mHelper;
 
-    public AdjustVolumeRestrictedPreferenceController(Context context) {
-        this(context, new AccountRestrictionHelper(context));
+    public AdjustVolumeRestrictedPreferenceController(Context context, String key) {
+        this(context, new AccountRestrictionHelper(context), key);
     }
 
     @VisibleForTesting
-    AdjustVolumeRestrictedPreferenceController(Context context, AccountRestrictionHelper helper) {
-        super(context);
+    AdjustVolumeRestrictedPreferenceController(Context context, AccountRestrictionHelper helper,
+            String key) {
+        super(context, key);
         mHelper = helper;
     }
 
diff --git a/src/com/android/settings/notification/AlarmVolumePreferenceController.java b/src/com/android/settings/notification/AlarmVolumePreferenceController.java
index c9b283b..0900e3c 100644
--- a/src/com/android/settings/notification/AlarmVolumePreferenceController.java
+++ b/src/com/android/settings/notification/AlarmVolumePreferenceController.java
@@ -20,32 +20,21 @@
 import android.media.AudioManager;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.settings.notification.VolumeSeekBarPreference.Callback;
 import com.android.settings.R;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class AlarmVolumePreferenceController extends
     VolumeSeekBarPreferenceController {
 
     private static final String KEY_ALARM_VOLUME = "alarm_volume";
-    private AudioHelper mHelper;
 
-    public AlarmVolumePreferenceController(Context context, Callback callback,
-        Lifecycle lifecycle) {
-        this(context, callback, lifecycle, new AudioHelper(context));
-    }
-
-    @VisibleForTesting
-    AlarmVolumePreferenceController(Context context, Callback callback, Lifecycle lifecycle,
-        AudioHelper helper) {
-        super(context, callback, lifecycle);
-        mHelper = helper;
+    public AlarmVolumePreferenceController(Context context) {
+        super(context, KEY_ALARM_VOLUME);
     }
 
     @Override
-    public boolean isAvailable() {
+    public int getAvailabilityStatus() {
         return mContext.getResources().getBoolean(R.bool.config_show_alarm_volume)
-                && !mHelper.isSingleVolume();
+                && !mHelper.isSingleVolume() ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
@@ -62,5 +51,4 @@
     public int getMuteIcon() {
         return com.android.internal.R.drawable.ic_audio_alarm_mute;
     }
-
 }
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index d334b92..c028298 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -167,9 +167,9 @@
             getPreferenceScreen().addPreference(groupCategory);
             mDynamicPreferences.add(groupCategory);
             if (group.getId() == null) {
-                groupCategory.setTitle(mChannelGroupList.size() > 1
-                        ? R.string.notification_channels_other
-                        : R.string.notification_channels);
+                if (mChannelGroupList.size() > 1) {
+                    groupCategory.setTitle(R.string.notification_channels_other);
+                }
                 groupCategory.setKey(KEY_GENERAL_CATEGORY);
             } else {
                 groupCategory.setTitle(group.getName());
diff --git a/src/com/android/settings/notification/AudioHelper.java b/src/com/android/settings/notification/AudioHelper.java
index 51ba74c..5f745c8 100644
--- a/src/com/android/settings/notification/AudioHelper.java
+++ b/src/com/android/settings/notification/AudioHelper.java
@@ -18,6 +18,7 @@
 
 import android.annotation.UserIdInt;
 import android.content.Context;
+import android.media.AudioManager;
 import android.media.AudioSystem;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -29,9 +30,11 @@
 public class AudioHelper {
 
     private Context mContext;
+    private AudioManager mAudioManager;
 
     public AudioHelper(Context context) {
         mContext = context;
+        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
     }
 
     public boolean isSingleVolume() {
@@ -49,4 +52,25 @@
     public Context createPackageContextAsUser(@UserIdInt int profileId) {
         return Utils.createPackageContextAsUser(mContext, profileId);
     }
+
+    public int getRingerModeInternal() {
+        return mAudioManager.getRingerModeInternal();
+    }
+
+    public int getLastAudibleStreamVolume(int stream) {
+        return mAudioManager.getLastAudibleStreamVolume(stream);
+    }
+
+    public int getStreamVolume(int stream) {
+        return mAudioManager.getStreamVolume(stream);
+    }
+
+    public boolean setStreamVolume(int stream, int volume) {
+        mAudioManager.setStreamVolume(stream, volume, 0);
+        return true;
+    }
+
+    public int getMaxVolume(int stream) {
+        return mAudioManager.getStreamMaxVolume(stream);
+    }
 }
diff --git a/src/com/android/settings/notification/BadgePreferenceController.java b/src/com/android/settings/notification/BadgePreferenceController.java
index 8f0376c..e768ad1 100644
--- a/src/com/android/settings/notification/BadgePreferenceController.java
+++ b/src/com/android/settings/notification/BadgePreferenceController.java
@@ -57,7 +57,7 @@
             return false;
         }
         if (mChannel != null) {
-            if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())) {
+            if (isDefaultChannel()) {
                 return true;
             } else {
                 return mAppRow.showBadge;
diff --git a/src/com/android/settings/notification/BlockPreferenceController.java b/src/com/android/settings/notification/BlockPreferenceController.java
index 9ea29fe..7c6201e 100644
--- a/src/com/android/settings/notification/BlockPreferenceController.java
+++ b/src/com/android/settings/notification/BlockPreferenceController.java
@@ -98,8 +98,7 @@
             // it was blocked and we are unblocking it.
             if (blocked || originalImportance == IMPORTANCE_NONE) {
                 final int importance = blocked ? IMPORTANCE_NONE
-                        : DEFAULT_CHANNEL_ID.equals(mChannel.getId())
-                                ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_DEFAULT;
+                        : isDefaultChannel() ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_DEFAULT;
                 mChannel.setImportance(importance);
                 saveChannel();
             }
diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java
index 26c1bc8..c9aa19d 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -106,8 +106,6 @@
         }
         controllers.add(new RecentNotifyingAppsPreferenceController(
                 context, new NotificationBackend(), app, host));
-        controllers.add(new SwipeToNotificationPreferenceController(context, lifecycle,
-                KEY_SWIPE_DOWN));
         controllers.add(badgeController);
         controllers.add(pulseController);
         controllers.add(lockScreenNotificationController);
diff --git a/src/com/android/settings/notification/HeaderPreferenceController.java b/src/com/android/settings/notification/HeaderPreferenceController.java
index ff687e8..d5e289b 100644
--- a/src/com/android/settings/notification/HeaderPreferenceController.java
+++ b/src/com/android/settings/notification/HeaderPreferenceController.java
@@ -31,6 +31,8 @@
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.widget.EntityHeaderController;
 
+import java.util.Objects;
+
 public class HeaderPreferenceController extends NotificationPreferenceController
         implements PreferenceControllerMixin {
 
@@ -72,7 +74,7 @@
     }
 
     CharSequence getLabel() {
-        return mChannel != null ? mChannel.getName()
+        return (mChannel != null && !isDefaultChannel()) ? mChannel.getName()
                 : mChannelGroup != null
                         ? mChannelGroup.getName()
                         : mAppRow.label;
@@ -80,7 +82,7 @@
 
     @Override
     public CharSequence getSummary() {
-        if (mChannel != null) {
+        if (mChannel != null && !isDefaultChannel()) {
             if (mChannelGroup != null
                     && !TextUtils.isEmpty(mChannelGroup.getName())) {
                 final SpannableStringBuilder summary = new SpannableStringBuilder();
diff --git a/src/com/android/settings/notification/ImportancePreferenceController.java b/src/com/android/settings/notification/ImportancePreferenceController.java
index f95c34a..60b2ebe 100644
--- a/src/com/android/settings/notification/ImportancePreferenceController.java
+++ b/src/com/android/settings/notification/ImportancePreferenceController.java
@@ -58,7 +58,7 @@
         if (mChannel == null) {
             return false;
         }
-        return !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId());
+        return !isDefaultChannel();
     }
 
     @Override
diff --git a/src/com/android/settings/notification/LightsPreferenceController.java b/src/com/android/settings/notification/LightsPreferenceController.java
index 230c3e2..9d5a6c5 100644
--- a/src/com/android/settings/notification/LightsPreferenceController.java
+++ b/src/com/android/settings/notification/LightsPreferenceController.java
@@ -50,8 +50,9 @@
         if (mChannel == null) {
             return false;
         }
-        return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT) && canPulseLight()
-                && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId());
+        return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
+                && canPulseLight()
+                && !isDefaultChannel();
     }
 
     public void updateState(Preference preference) {
diff --git a/src/com/android/settings/notification/MediaVolumePreferenceController.java b/src/com/android/settings/notification/MediaVolumePreferenceController.java
index 381135e..8f0a7f9 100644
--- a/src/com/android/settings/notification/MediaVolumePreferenceController.java
+++ b/src/com/android/settings/notification/MediaVolumePreferenceController.java
@@ -27,13 +27,15 @@
 
     private static final String KEY_MEDIA_VOLUME = "media_volume";
 
-    public MediaVolumePreferenceController(Context context, Callback callback, Lifecycle lifecycle) {
-        super(context, callback, lifecycle);
+    public MediaVolumePreferenceController(Context context) {
+        super(context, KEY_MEDIA_VOLUME);
     }
 
     @Override
-    public boolean isAvailable() {
-        return mContext.getResources().getBoolean(R.bool.config_show_media_volume);
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_media_volume)
+                ? AVAILABLE
+                : DISABLED_UNSUPPORTED;
     }
 
     @Override
@@ -50,5 +52,4 @@
     public int getMuteIcon() {
         return com.android.internal.R.drawable.ic_audio_media_mute;
     }
-
 }
diff --git a/src/com/android/settings/notification/NotificationPreferenceController.java b/src/com/android/settings/notification/NotificationPreferenceController.java
index c0bb705..1a65351 100644
--- a/src/com/android/settings/notification/NotificationPreferenceController.java
+++ b/src/com/android/settings/notification/NotificationPreferenceController.java
@@ -184,4 +184,11 @@
     protected boolean hasValidGroup() {
         return mChannelGroup != null;
     }
+
+    protected final boolean isDefaultChannel() {
+        if (mChannel == null) {
+            return false;
+        }
+        return Objects.equals(NotificationChannel.DEFAULT_CHANNEL_ID, mChannel.getId());
+    }
 }
diff --git a/src/com/android/settings/notification/NotificationVolumePreferenceController.java b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
index 4024f9f..8e7171d 100644
--- a/src/com/android/settings/notification/NotificationVolumePreferenceController.java
+++ b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
@@ -22,32 +22,21 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settings.notification.VolumeSeekBarPreference.Callback;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class NotificationVolumePreferenceController extends
     RingVolumePreferenceController {
 
     private static final String KEY_NOTIFICATION_VOLUME = "notification_volume";
-    private AudioHelper mHelper;
 
-    public NotificationVolumePreferenceController(Context context, Callback callback,
-        Lifecycle lifecycle) {
-        this(context, callback, lifecycle, new AudioHelper(context));
+    public NotificationVolumePreferenceController(Context context) {
+        super(context, KEY_NOTIFICATION_VOLUME);
     }
 
-    @VisibleForTesting
-    NotificationVolumePreferenceController(Context context,
-        Callback callback, Lifecycle lifecycle, AudioHelper helper) {
-        super(context, callback, lifecycle);
-        mHelper = helper;
-    }
-
-
     @Override
-    public boolean isAvailable() {
+    public int getAvailabilityStatus() {
         return mContext.getResources().getBoolean(R.bool.config_show_notification_volume)
-                && !Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume();
+                && !Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume()
+                ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
diff --git a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
index 3867640..4079099 100644
--- a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
@@ -37,14 +37,13 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.applications.AppInfoBase;
-import com.android.settings.applications.InstalledAppCounter;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settingslib.TwoTargetPreference;
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.utils.StringUtil;
-import com.android.settingslib.wrapper.PackageManagerWrapper;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -211,6 +210,7 @@
             pref.setKey(pkgName);
             pref.setTitle(appEntry.label);
             pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info));
+            pref.setIconSize(TwoTargetPreference.ICON_SIZE_SMALL);
             pref.setSummary(StringUtil.formatRelativeTime(mContext,
                     System.currentTimeMillis() - app.getLastNotified(), true));
             pref.setOrder(i);
diff --git a/src/com/android/settings/notification/RingVolumePreferenceController.java b/src/com/android/settings/notification/RingVolumePreferenceController.java
index 5acca04..ea071fa 100644
--- a/src/com/android/settings/notification/RingVolumePreferenceController.java
+++ b/src/com/android/settings/notification/RingVolumePreferenceController.java
@@ -31,8 +31,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settings.notification.VolumeSeekBarPreference.Callback;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.Objects;
 
@@ -41,24 +39,18 @@
     private static final String TAG = "RingVolumeController";
     private static final String KEY_RING_VOLUME = "ring_volume";
 
-    private AudioManager mAudioManager;
     private Vibrator mVibrator;
     private int mRingerMode = -1;
     private ComponentName mSuppressor;
     private final RingReceiver mReceiver = new RingReceiver();
     private final H mHandler = new H();
-    private AudioHelper mHelper;
 
-    public RingVolumePreferenceController(Context context, Callback callback, Lifecycle lifecycle) {
-        this(context, callback, lifecycle, new AudioHelper(context));
+    public RingVolumePreferenceController(Context context) {
+        this(context, KEY_RING_VOLUME);
     }
 
-    @VisibleForTesting
-    RingVolumePreferenceController(Context context, Callback callback, Lifecycle lifecycle,
-        AudioHelper helper) {
-        super(context, callback, lifecycle);
-        mHelper = helper;
-        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+    public RingVolumePreferenceController(Context context, String key) {
+        super(context, key);
         mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
         if (mVibrator != null && !mVibrator.hasVibrator()) {
             mVibrator = null;
@@ -86,8 +78,9 @@
     }
 
     @Override
-    public boolean isAvailable() {
-        return Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume();
+    public int getAvailabilityStatus() {
+        return Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume()
+                ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
@@ -101,7 +94,7 @@
     }
 
     private void updateRingerMode() {
-        final int ringerMode = mAudioManager.getRingerModeInternal();
+        final int ringerMode = mHelper.getRingerModeInternal();
         if (mRingerMode == ringerMode) return;
         mRingerMode = ringerMode;
         updatePreferenceIcon();
@@ -109,7 +102,7 @@
 
     private boolean wasRingerModeVibrate() {
         return mVibrator != null && mRingerMode == AudioManager.RINGER_MODE_SILENT
-            && mAudioManager.getLastAudibleStreamVolume(AudioManager.STREAM_RING) == 0;
+            && mHelper.getLastAudibleStreamVolume(getAudioStream()) == 0;
     }
 
     private void updateEffectsSuppressor() {
diff --git a/src/com/android/settings/notification/SoundPreferenceController.java b/src/com/android/settings/notification/SoundPreferenceController.java
index e4414b6..4ae6ebe 100644
--- a/src/com/android/settings/notification/SoundPreferenceController.java
+++ b/src/com/android/settings/notification/SoundPreferenceController.java
@@ -59,8 +59,7 @@
         if (mChannel == null) {
             return false;
         }
-        return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
-                && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId());
+        return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT) && !isDefaultChannel();
     }
 
     @Override
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index a7ba707..4c9ee38 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -124,7 +124,7 @@
 
     @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, this, mVolumeCallback, getLifecycle());
+        return buildPreferenceControllers(context, this, getLifecycle());
     }
 
     @Override
@@ -143,6 +143,15 @@
         }
     }
 
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        use(AlarmVolumePreferenceController.class).setCallback(mVolumeCallback);
+        use(MediaVolumePreferenceController.class).setCallback(mVolumeCallback);
+        use(RingVolumePreferenceController.class).setCallback(mVolumeCallback);
+        use(NotificationVolumePreferenceController.class).setCallback(mVolumeCallback);
+    }
+
     // === Volumes ===
 
     final class VolumePreferenceCallback implements VolumeSeekBarPreference.Callback {
@@ -176,18 +185,12 @@
     }
 
     private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            SoundSettings fragment, VolumeSeekBarPreference.Callback callback,
-            Lifecycle lifecycle) {
+            SoundSettings fragment, Lifecycle lifecycle) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
         controllers.add(new ZenModePreferenceController(context, lifecycle, KEY_ZEN_MODE));
         controllers.add(new VibrateWhenRingPreferenceController(context));
 
-        // === Volumes ===
-        controllers.add(new AlarmVolumePreferenceController(context, callback, lifecycle));
-        controllers.add(new MediaVolumePreferenceController(context, callback, lifecycle));
-        controllers.add(
-                new NotificationVolumePreferenceController(context, callback, lifecycle));
-        controllers.add(new RingVolumePreferenceController(context, callback, lifecycle));
+        // Volumes are added via xml
 
         // === Phone & notification ringtone ===
         controllers.add(new PhoneRingtonePreferenceController(context));
@@ -257,7 +260,7 @@
                 public List<AbstractPreferenceController> createPreferenceControllers(
                         Context context) {
                     return buildPreferenceControllers(context, null /* fragment */,
-                            null /* callback */, null /* lifecycle */);
+                            null /* lifecycle */);
                 }
 
                 @Override
diff --git a/src/com/android/settings/notification/VibrationPreferenceController.java b/src/com/android/settings/notification/VibrationPreferenceController.java
index f9b786d..9df8e04 100644
--- a/src/com/android/settings/notification/VibrationPreferenceController.java
+++ b/src/com/android/settings/notification/VibrationPreferenceController.java
@@ -47,7 +47,7 @@
             return false;
        }
         return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
-                && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())
+                && !isDefaultChannel()
                 && mVibrator != null
                 && mVibrator.hasVibrator();
     }
diff --git a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
index 501cedc..74e801e 100644
--- a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
+++ b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
@@ -16,31 +16,37 @@
 
 package com.android.settings.notification;
 
+import android.arch.lifecycle.LifecycleObserver;
+import android.arch.lifecycle.OnLifecycleEvent;
 import android.content.Context;
 import android.support.v7.preference.PreferenceScreen;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.notification.VolumeSeekBarPreference.Callback;
 import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
 
 /**
  * Base class for preference controller that handles VolumeSeekBarPreference
  */
 public abstract class VolumeSeekBarPreferenceController extends
-        AdjustVolumeRestrictedPreferenceController implements LifecycleObserver, OnResume, OnPause {
+        AdjustVolumeRestrictedPreferenceController implements LifecycleObserver {
 
     protected VolumeSeekBarPreference mPreference;
     protected VolumeSeekBarPreference.Callback mVolumePreferenceCallback;
+    protected AudioHelper mHelper;
 
-    public VolumeSeekBarPreferenceController(Context context, Callback callback,
-            Lifecycle lifecycle) {
-        super(context);
+    public VolumeSeekBarPreferenceController(Context context, String key) {
+        super(context, key);
+        setAudioHelper(new AudioHelper(context));
+    }
+
+    @VisibleForTesting
+    void setAudioHelper(AudioHelper helper) {
+        mHelper = helper;
+    }
+
+    public void setCallback(Callback callback) {
         mVolumePreferenceCallback = callback;
-        if (lifecycle != null) {
-            lifecycle.addObserver(this);
-        }
     }
 
     @Override
@@ -54,20 +60,44 @@
         }
     }
 
-    @Override
+    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
     public void onResume() {
         if (mPreference != null) {
             mPreference.onActivityResume();
         }
     }
 
-    @Override
+    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
     public void onPause() {
         if (mPreference != null) {
             mPreference.onActivityPause();
         }
     }
 
+    @Override
+    public int getSliderPosition() {
+        if (mPreference != null) {
+            return mPreference.getProgress();
+        }
+        return mHelper.getStreamVolume(getAudioStream());
+    }
+
+    @Override
+    public boolean setSliderPosition(int position) {
+        if (mPreference != null) {
+            mPreference.setProgress(position);
+        }
+        return mHelper.setStreamVolume(getAudioStream(), position);
+    }
+
+    @Override
+    public int getMaxSteps() {
+        if (mPreference != null) {
+            return mPreference.getMax();
+        }
+        return mHelper.getMaxVolume(getAudioStream());
+    }
+
     protected abstract int getAudioStream();
 
     protected abstract int getMuteIcon();
diff --git a/src/com/android/settings/notification/ZenModeBlockedEffectsSettings.java b/src/com/android/settings/notification/ZenModeBlockedEffectsSettings.java
index 0cac9cb..8b0cf5f 100644
--- a/src/com/android/settings/notification/ZenModeBlockedEffectsSettings.java
+++ b/src/com/android/settings/notification/ZenModeBlockedEffectsSettings.java
@@ -25,6 +25,7 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
 
 import android.content.Context;
+import android.os.Bundle;
 import android.provider.SearchIndexableResource;
 import android.support.v7.preference.CheckBoxPreference;
 
@@ -41,13 +42,10 @@
 public class ZenModeBlockedEffectsSettings extends ZenModeSettingsBase implements Indexable {
 
     @Override
-    public void onResume() {
-        super.onResume();
-        CheckBoxPreference soundPreference =
-                (CheckBoxPreference) getPreferenceScreen().findPreference("zen_effect_sound");
-        if (soundPreference != null) {
-            soundPreference.setChecked(true);
-        }
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mFooterPreferenceMixin.createFooterPreference().setTitle(
+                R.string.zen_mode_blocked_effects_footer);
     }
 
     @Override
diff --git a/src/com/android/settings/notification/ZenModePreferenceController.java b/src/com/android/settings/notification/ZenModePreferenceController.java
index 5b59000..5c9c33b 100644
--- a/src/com/android/settings/notification/ZenModePreferenceController.java
+++ b/src/com/android/settings/notification/ZenModePreferenceController.java
@@ -27,13 +27,15 @@
 import android.support.v7.preference.PreferenceScreen;
 import android.util.Slog;
 
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
-public class ZenModePreferenceController extends AdjustVolumeRestrictedPreferenceController
-        implements LifecycleObserver, OnResume, OnPause {
+public class ZenModePreferenceController extends AbstractPreferenceController
+        implements LifecycleObserver, OnResume, OnPause, PreferenceControllerMixin {
 
     private final String mKey;
     private SettingObserver mSettingObserver;
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 5b85440..1f0dcc2 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -25,6 +25,7 @@
 import android.provider.Settings;
 import android.service.notification.ZenModeConfig;
 import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.CheckBoxPreference;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
@@ -40,6 +41,17 @@
 import java.util.Map.Entry;
 
 public class ZenModeSettings extends ZenModeSettingsBase {
+    private static final String KEY_SOUND = "zen_effect_sound";
+    @Override
+    public void onResume() {
+        super.onResume();
+        CheckBoxPreference soundPreference =
+                (CheckBoxPreference) getPreferenceScreen().findPreference(KEY_SOUND);
+        if (soundPreference != null) {
+            soundPreference.setChecked(true);
+        }
+    }
+
     @Override
     protected int getPreferenceScreenResId() {
         return R.xml.zen_mode_settings;
@@ -124,7 +136,7 @@
 
             if (zenMode != Settings.Global.ZEN_MODE_OFF) {
                 ZenModeConfig config = NotificationManager.from(mContext).getZenModeConfig();
-                String description = ZenModeConfig.getDescription(mContext, true, config);
+                String description = ZenModeConfig.getDescription(mContext, true, config, false);
 
                 if (description == null) {
                     return mContext.getString(R.string.zen_mode_sound_summary_on);
@@ -146,15 +158,25 @@
         }
 
         String getBlockedEffectsSummary(Policy policy) {
-            if (policy.suppressedVisualEffects == 0) {
-                return mContext.getResources().getString(
-                        R.string.zen_mode_block_effect_summary_sound);
-            } else if (Policy.areAllVisualEffectsSuppressed(policy.suppressedVisualEffects)) {
-                return mContext.getResources().getString(
-                        R.string.zen_mode_block_effect_summary_all);
+            List<String> blockedStrings = new ArrayList<>();
+            if (Policy.areAnyScreenOffEffectsSuppressed(policy.suppressedVisualEffects)) {
+                blockedStrings.add(mContext.getResources().getString(
+                        R.string.zen_mode_block_effect_summary_screen_off));
             }
-            return mContext.getResources().getString(
-                    R.string.zen_mode_block_effect_summary_some);
+            if (Policy.areAnyScreenOnEffectsSuppressed(policy.suppressedVisualEffects)) {
+                blockedStrings.add(mContext.getResources().getString(
+                        R.string.zen_mode_block_effect_summary_screen_on));
+            }
+
+            if (blockedStrings.size() == 0) {
+                return mContext.getResources().getString(
+                        R.string.zen_mode_block_effect_summary_none);
+            } else if (blockedStrings.size() == 1) {
+                return blockedStrings.get(0);
+            } else {
+                return mContext.getResources().getString(R.string.join_two_unrelated_items,
+                        blockedStrings.get(0), blockedStrings.get(1));
+            }
         }
 
         String getAutomaticRulesSummary() {
diff --git a/src/com/android/settings/notification/ZenOnboardingActivity.java b/src/com/android/settings/notification/ZenOnboardingActivity.java
new file mode 100644
index 0000000..b38bad6
--- /dev/null
+++ b/src/com/android/settings/notification/ZenOnboardingActivity.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.view.View;
+import android.widget.CheckBox;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+
+public class ZenOnboardingActivity extends Activity {
+
+    private NotificationManager mNm;
+    private MetricsLogger mMetrics;
+    CheckBox mScreenOn;
+    CheckBox mScreenOff;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setNotificationManager(getSystemService(NotificationManager.class));
+        setMetricsLogger(new MetricsLogger());
+
+        setupUI();
+    }
+
+    @VisibleForTesting
+    protected void setupUI() {
+        setContentView(R.layout.zen_onboarding);
+        mScreenOn = findViewById(R.id.screen_on_option);
+        mScreenOff = findViewById(R.id.screen_off_option);
+        mScreenOn.setChecked(true);
+        mScreenOff.setChecked(true);
+
+        mMetrics.visible(MetricsEvent.SETTINGS_ZEN_ONBOARDING);
+    }
+
+    @VisibleForTesting
+    protected void setNotificationManager(NotificationManager nm) {
+        mNm = nm;
+    }
+
+    @VisibleForTesting
+    protected void setMetricsLogger(MetricsLogger ml) {
+        mMetrics = ml;
+    }
+
+    public void logClick(View view) {
+        CheckBox checkbox = (CheckBox) view;
+        switch (checkbox.getId()) {
+            case R.id.screen_on_option:
+                mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_SCREEN_ON, checkbox.isChecked());
+                break;
+            case R.id.screen_off_option:
+                mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_SCREEN_OFF,
+                        checkbox.isChecked());
+                break;
+        }
+    }
+
+    public void launchSettings(View button) {
+        mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_SETTINGS);
+        Intent settings = new Intent(Settings.ZEN_MODE_BLOCKED_EFFECTS_SETTINGS);
+        settings.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        startActivity(settings);
+    }
+
+    public void save(View button) {
+        mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_OK);
+        NotificationManager.Policy policy = mNm.getNotificationPolicy();
+        int currentEffects = policy.suppressedVisualEffects;
+
+        currentEffects = NotificationManager.Policy.toggleScreenOnEffectsSuppressed(
+                currentEffects, mScreenOn != null && mScreenOn.isChecked());
+        currentEffects = NotificationManager.Policy.toggleScreenOffEffectsSuppressed(
+                currentEffects, mScreenOff != null && mScreenOff.isChecked());
+
+        NotificationManager.Policy newPolicy = new NotificationManager.Policy(
+                policy.priorityCategories, policy.priorityCallSenders,
+                policy.priorityMessageSenders, currentEffects);
+        mNm.setNotificationPolicy(newPolicy);
+
+        finishAndRemoveTask();
+    }
+}
diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java
index 2d6f83e..80b7519 100644
--- a/src/com/android/settings/slices/SliceBroadcastReceiver.java
+++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java
@@ -40,8 +40,6 @@
 import com.android.settings.core.TogglePreferenceController;
 import com.android.settings.overlay.FeatureFactory;
 
-import androidx.slice.core.SliceHints;
-
 /**
  * Responds to actions performed on slices and notifies slices of updates in state changes.
  */
@@ -64,7 +62,7 @@
                 handleToggleAction(context, key, isPlatformDefined);
                 break;
             case ACTION_SLIDER_CHANGED:
-                int newPosition = intent.getIntExtra(SliceHints.EXTRA_RANGE_VALUE, -1);
+                int newPosition = intent.getIntExtra(Slice.EXTRA_RANGE_VALUE, -1);
                 handleSliderAction(context, key, newPosition);
                 break;
             case ACTION_WIFI_CHANGED:
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index 3e062c8..c54d138 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -253,11 +253,7 @@
     @VisibleForTesting
     static CharSequence getSubtitleText(Context context, AbstractPreferenceController controller,
             SliceData sliceData) {
-        CharSequence summaryText = sliceData.getSummary();
-        if (isValidSummary(context, summaryText)) {
-            return summaryText;
-        }
-
+        CharSequence summaryText;
         if (controller != null) {
             summaryText = controller.getSummary();
 
@@ -266,7 +262,12 @@
             }
         }
 
-        return sliceData.getScreenTitle();
+        summaryText = sliceData.getSummary();
+        if (isValidSummary(context, summaryText)) {
+            return summaryText;
+        }
+
+        return "";
     }
 
     private static boolean isValidSummary(Context context, CharSequence summary) {
diff --git a/src/com/android/settings/vpn2/LegacyVpnPreference.java b/src/com/android/settings/vpn2/LegacyVpnPreference.java
index 8fa9680..c2d9388 100644
--- a/src/com/android/settings/vpn2/LegacyVpnPreference.java
+++ b/src/com/android/settings/vpn2/LegacyVpnPreference.java
@@ -36,7 +36,7 @@
     LegacyVpnPreference(Context context) {
         super(context, null /* attrs */);
         setIcon(R.drawable.ic_vpn_key);
-        setUseSmallIcon(true);
+        setIconSize(ICON_SIZE_SMALL);
     }
 
     public VpnProfile getProfile() {
diff --git a/src/com/android/settings/widget/AspectRatioFrameLayout.java b/src/com/android/settings/widget/AspectRatioFrameLayout.java
index bb4c28b..52dea0f 100644
--- a/src/com/android/settings/widget/AspectRatioFrameLayout.java
+++ b/src/com/android/settings/widget/AspectRatioFrameLayout.java
@@ -16,6 +16,7 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.support.annotation.VisibleForTesting;
 import android.util.AttributeSet;
 import android.widget.FrameLayout;
 
@@ -30,7 +31,8 @@
 
     private static final float ASPECT_RATIO_CHANGE_THREASHOLD = 0.01f;
 
-    private float mAspectRatio = 1.0f;
+    @VisibleForTesting
+    float mAspectRatio = 1.0f;
 
     public AspectRatioFrameLayout(Context context) {
         this(context, null);
@@ -51,6 +53,10 @@
         }
     }
 
+    public void setAspectRatio(float aspectRadio) {
+        mAspectRatio = aspectRadio;
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -65,11 +71,9 @@
             // Close enough, skip.
             return;
         }
-        if (aspectRatioDiff > 0) {
-            width = (int) (height * mAspectRatio);
-        } else {
-            height = (int) (width / mAspectRatio);
-        }
+
+        width = (int) (height * mAspectRatio);
+
         super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
     }
diff --git a/src/com/android/settings/widget/DonutView.java b/src/com/android/settings/widget/DonutView.java
index 4fb3c5b..c5ac40b 100644
--- a/src/com/android/settings/widget/DonutView.java
+++ b/src/com/android/settings/widget/DonutView.java
@@ -37,6 +37,7 @@
 import android.util.AttributeSet;
 import android.view.View;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.Utils;
 
@@ -173,19 +174,13 @@
         final float centerY = getHeight() / 2;
         final float totalHeight = getTextHeight(mTextPaint) + getTextHeight(mBigNumberPaint);
         final float startY = centerY + totalHeight / 2;
-        final float fontProportion = getResources().getDimension(
-                R.dimen.storage_donut_view_percent_sign_size) /
-                getResources().getDimension(R.dimen.storage_donut_view_percent_text_size);
         // Support from Android P
         final String localizedPercentSign = new DecimalFormatSymbols().getPercentString();
-        final int startIndex = mPercentString.indexOf(localizedPercentSign);
-        final int endIndex = startIndex + localizedPercentSign.length();
 
         // The first line y-coordinates start at (total height - all TextPaint height) / 2
         canvas.save();
-        final Spannable percentStringSpan = new SpannableString(mPercentString);
-        percentStringSpan.setSpan(new RelativeSizeSpan(fontProportion),
-                startIndex, endIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+        final Spannable percentStringSpan =
+                getPercentageStringSpannable(getResources(), mPercentString, localizedPercentSign);
         final StaticLayout percentStringLayout = new StaticLayout(percentStringSpan,
                 mBigNumberPaint, getWidth(), Layout.Alignment.ALIGN_CENTER, 1, 0, false);
         canvas.translate(0, (getHeight() - totalHeight) / 2);
@@ -235,6 +230,30 @@
         invalidate();
     }
 
+    @VisibleForTesting
+    static Spannable getPercentageStringSpannable(
+            Resources resources, String percentString, String percentageSignString) {
+        final float fontProportion =
+                resources.getDimension(R.dimen.storage_donut_view_percent_sign_size)
+                        / resources.getDimension(R.dimen.storage_donut_view_percent_text_size);
+        final Spannable percentStringSpan = new SpannableString(percentString);
+        int startIndex = percentString.indexOf(percentageSignString);
+        int endIndex = startIndex + percentageSignString.length();
+
+        // Fallback to no small string if we can't find the percentage sign.
+        if (startIndex < 0) {
+            startIndex = 0;
+            endIndex = percentString.length();
+        }
+
+        percentStringSpan.setSpan(
+                new RelativeSizeSpan(fontProportion),
+                startIndex,
+                endIndex,
+                Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
+        return percentStringSpan;
+    }
+
     private float getTextHeight(TextPaint paint) {
         // Technically, this should be the cap height, but I can live with the descent - ascent.
         return paint.descent() - paint.ascent();
diff --git a/src/com/android/settings/widget/RadioButtonPreference.java b/src/com/android/settings/widget/RadioButtonPreference.java
index d386698..2d30687 100644
--- a/src/com/android/settings/widget/RadioButtonPreference.java
+++ b/src/com/android/settings/widget/RadioButtonPreference.java
@@ -47,6 +47,8 @@
     public RadioButtonPreference(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         setWidgetLayoutResource(R.layout.preference_widget_radiobutton);
+        setLayoutResource(R.layout.preference_radio);
+        setIconSpaceReserved(false);
     }
 
     public RadioButtonPreference(Context context, AttributeSet attrs) {
diff --git a/src/com/android/settings/widget/ValidatedEditTextPreference.java b/src/com/android/settings/widget/ValidatedEditTextPreference.java
index 580eb58..a5bab1c 100644
--- a/src/com/android/settings/widget/ValidatedEditTextPreference.java
+++ b/src/com/android/settings/widget/ValidatedEditTextPreference.java
@@ -86,9 +86,14 @@
         super.onBindViewHolder(holder);
 
         final TextView textView = (TextView) holder.findViewById(android.R.id.summary);
-        if (textView != null && mIsSummaryPassword) {
+        if (textView == null) {
+            return;
+        }
+        if (mIsSummaryPassword) {
             textView.setInputType(
                     InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+        } else {
+            textView.setInputType(InputType.TYPE_CLASS_TEXT);
         }
     }
 
diff --git a/src/com/android/settings/widget/VideoPreference.java b/src/com/android/settings/widget/VideoPreference.java
index a3ac6a3..03f8f0b 100644
--- a/src/com/android/settings/widget/VideoPreference.java
+++ b/src/com/android/settings/widget/VideoPreference.java
@@ -22,6 +22,7 @@
 import android.graphics.SurfaceTexture;
 import android.media.MediaPlayer;
 import android.net.Uri;
+import android.support.annotation.VisibleForTesting;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceViewHolder;
 import android.util.AttributeSet;
@@ -42,10 +43,13 @@
     private final Context mContext;
 
     private Uri mVideoPath;
-    private MediaPlayer mMediaPlayer;
-    private boolean mAnimationAvailable;
+    @VisibleForTesting
+    MediaPlayer mMediaPlayer;
+    @VisibleForTesting
+    boolean mAnimationAvailable;
     private boolean mVideoReady;
     private boolean mVideoPaused;
+    private float mAspectRadio = 1.0f;
     private int mPreviewResource;
 
     public VideoPreference(Context context, AttributeSet attrs) {
@@ -73,6 +77,7 @@
 
                 mMediaPlayer.setOnPreparedListener(mediaPlayer -> mediaPlayer.setLooping(true));
                 mAnimationAvailable = true;
+                updateAspectRatio();
             } else {
                 setVisible(false);
             }
@@ -94,7 +99,11 @@
         final TextureView video = (TextureView) holder.findViewById(R.id.video_texture_view);
         final ImageView imageView = (ImageView) holder.findViewById(R.id.video_preview_image);
         final ImageView playButton = (ImageView) holder.findViewById(R.id.video_play_button);
+        final AspectRatioFrameLayout layout = (AspectRatioFrameLayout) holder.findViewById(
+                R.id.video_container);
+
         imageView.setImageResource(mPreviewResource);
+        layout.setAspectRatio(mAspectRadio);
 
         video.setOnClickListener(v -> {
             if (mMediaPlayer != null) {
@@ -178,4 +187,9 @@
         return mVideoPaused;
     }
 
+    @VisibleForTesting
+    void updateAspectRatio() {
+        mAspectRadio = mMediaPlayer.getVideoWidth() / (float)mMediaPlayer.getVideoHeight();
+    }
+
 }
diff --git a/src/com/android/settings/wifi/WifiScanningRequiredFragment.java b/src/com/android/settings/wifi/WifiScanningRequiredFragment.java
index 4ff023d..bf24bbc 100644
--- a/src/com/android/settings/wifi/WifiScanningRequiredFragment.java
+++ b/src/com/android/settings/wifi/WifiScanningRequiredFragment.java
@@ -92,7 +92,7 @@
     void addButtonIfNeeded(AlertDialog.Builder builder) {
         // Only show "learn more" if there is a help page to show
         if (!TextUtils.isEmpty(getContext().getString(R.string.help_uri_wifi_scanning_required))) {
-            builder.setNeutralButton(R.string.do_disclosure_learn_more, this);
+            builder.setNeutralButton(R.string.learn_more, this);
         }
     }
 
diff --git a/src/com/android/settings/wifi/WifiUtils.java b/src/com/android/settings/wifi/WifiUtils.java
index 0477280..3e797d7 100644
--- a/src/com/android/settings/wifi/WifiUtils.java
+++ b/src/com/android/settings/wifi/WifiUtils.java
@@ -50,10 +50,11 @@
         return ssid.length() < SSID_ASCII_MIN_LENGTH;
     }
 
-    public static boolean isPasswordValid(String password) {
+    public static boolean isHotspotPasswordValid(String password) {
         if (TextUtils.isEmpty(password)) {
-            return false;
+            return true;
         }
+
         final int length = password.length();
         return length >= PASSWORD_MIN_LENGTH && length <= PASSWORD_MAX_LENGTH;
     }
diff --git a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
index b8710c9..7ef10e5 100644
--- a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
+++ b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
@@ -168,6 +168,11 @@
     }
 
     @Override
+    public int getHelpResource() {
+        return R.string.help_url_wifi_p2p;
+    }
+
+    @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
         mPersistentCategoryController =
diff --git a/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java
index 0e973ae..8eab9f4 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java
@@ -20,11 +20,15 @@
 import android.net.wifi.WifiConfiguration;
 import android.support.v7.preference.EditTextPreference;
 import android.support.v7.preference.Preference;
+import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.settings.R;
 import com.android.settings.widget.ValidatedEditTextPreference;
 import com.android.settings.wifi.WifiUtils;
 
+import java.util.UUID;
+
 public class WifiTetherPasswordPreferenceController extends WifiTetherBasePreferenceController
         implements ValidatedEditTextPreference.Validator {
 
@@ -49,6 +53,8 @@
         if (config != null) {
             mPassword = config.preSharedKey;
             Log.d(TAG, "Updating password in Preference, " + mPassword);
+        } else {
+            mPassword = generateRandomPassword();
         }
         ((ValidatedEditTextPreference) mPreference).setValidator(this);
         ((ValidatedEditTextPreference) mPreference).setIsSummaryPassword(true);
@@ -67,13 +73,35 @@
         return mPassword;
     }
 
+    public int getSecuritySettingForPassword() {
+        // We should return NONE when no password is set
+        if (TextUtils.isEmpty(mPassword)) {
+            return WifiConfiguration.KeyMgmt.NONE;
+        }
+        // Only other currently supported type is WPA2 so we'll try that
+        return WifiConfiguration.KeyMgmt.WPA2_PSK;
+    }
+
     @Override
     public boolean isTextValid(String value) {
-        return WifiUtils.isPasswordValid(value);
+        return WifiUtils.isHotspotPasswordValid(value);
+    }
+
+    private static String generateRandomPassword() {
+        String randomUUID = UUID.randomUUID().toString();
+        //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
+        return randomUUID.substring(0, 8) + randomUUID.substring(9, 13);
     }
 
     private void updatePasswordDisplay(EditTextPreference preference) {
-        preference.setText(mPassword);
-        preference.setSummary(mPassword);
+        ValidatedEditTextPreference pref = (ValidatedEditTextPreference) preference;
+        pref.setText(mPassword);
+        if (!TextUtils.isEmpty(mPassword)) {
+            pref.setIsSummaryPassword(true);
+            pref.setSummary(mPassword);
+        } else {
+            pref.setIsSummaryPassword(false);
+            pref.setSummary(R.string.wifi_hotspot_no_password_subtext);
+        }
     }
 }
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
index 996c73c..de6243c 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
@@ -161,8 +161,8 @@
 
         config.SSID = mSSIDPreferenceController.getSSID();
         config.preSharedKey = mPasswordPreferenceController.getPassword();
-        ensureWifiConfigHasPassword(config);
-        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
+        config.allowedKeyManagement.set(
+                mPasswordPreferenceController.getSecuritySettingForPassword());
         config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
         config.apBand = mApBandPreferenceController.getBandIndex();
         return config;
@@ -183,15 +183,6 @@
     }
 
     @VisibleForTesting
-    static void ensureWifiConfigHasPassword(WifiConfiguration config) {
-        if (TextUtils.isEmpty(config.preSharedKey)) {
-            String randomUUID = UUID.randomUUID().toString();
-            //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
-            config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9, 13);
-        }
-    }
-
-    @VisibleForTesting
     class TetherChangeReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context content, Intent intent) {
diff --git a/tests/robotests/assets/grandfather_slice_controller_not_in_xml b/tests/robotests/assets/grandfather_slice_controller_not_in_xml
index ae1c86a..5a09997 100644
--- a/tests/robotests/assets/grandfather_slice_controller_not_in_xml
+++ b/tests/robotests/assets/grandfather_slice_controller_not_in_xml
@@ -1,2 +1,2 @@
 com.android.settings.testutils.FakeToggleController
-com.android.settings.testutils.FakeSliderController
+com.android.settings.testutils.FakeSliderController
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/SettingsDumpServiceTest.java b/tests/robotests/src/com/android/settings/SettingsDumpServiceTest.java
index 615d1e7..8178641 100644
--- a/tests/robotests/src/com/android/settings/SettingsDumpServiceTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsDumpServiceTest.java
@@ -16,13 +16,21 @@
 package com.android.settings;
 
 import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
+import android.content.Context;
+import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.support.annotation.NonNull;
 
+import com.android.settings.fuelgauge.batterytip.AnomalyConfigJobService;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.json.JSONException;
@@ -32,6 +40,7 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
 
 import java.io.OutputStream;
 import java.io.PrintWriter;
@@ -41,6 +50,7 @@
 
     private static final String PACKAGE_BROWSER = "com.android.test.browser";
     private static final String PACKAGE_NULL = "android";
+    private static final int ANOMALY_VERSION = 2;
 
     @Mock
     private PackageManager mPackageManager;
@@ -54,7 +64,7 @@
 
         when(mPackageManager.resolveActivity(TestService.BROWSER_INTENT,
                 PackageManager.MATCH_DEFAULT_ONLY)).thenReturn(mResolveInfo);
-        mTestService = new TestService();
+        mTestService = spy(new TestService());
         mTestService.setPackageManager(mPackageManager);
     }
 
@@ -75,13 +85,29 @@
     }
 
     @Test
+    public void testDumpAnomalyDetection_returnAnomalyInfo() throws JSONException {
+        final SharedPreferences sharedPreferences =
+                RuntimeEnvironment.application.getSharedPreferences(AnomalyConfigJobService.PREF_DB,
+                        Context.MODE_PRIVATE);
+        SharedPreferences.Editor editor = sharedPreferences.edit();
+        editor.putInt(AnomalyConfigJobService.KEY_ANOMALY_CONFIG_VERSION, ANOMALY_VERSION);
+        editor.commit();
+        doReturn(sharedPreferences).when(mTestService).getSharedPreferences(anyString(), anyInt());
+
+        final JSONObject jsonObject = mTestService.dumpAnomalyDetection();
+
+        assertThat(jsonObject.getInt(AnomalyConfigJobService.KEY_ANOMALY_CONFIG_VERSION)).isEqualTo(
+                ANOMALY_VERSION);
+    }
+
+    @Test
     public void testDump_ReturnJsonObject() throws JSONException {
         mResolveInfo.activityInfo = new ActivityInfo();
         mResolveInfo.activityInfo.packageName = PACKAGE_BROWSER;
         TestPrintWriter printWriter = new TestPrintWriter(System.out);
 
         mTestService.dump(null, printWriter, null);
-        JSONObject object = (JSONObject)printWriter.getPrintObject();
+        JSONObject object = (JSONObject) printWriter.getPrintObject();
 
         assertThat(object.get(TestService.KEY_SERVICE)).isNotNull();
     }
diff --git a/tests/robotests/src/com/android/settings/accounts/ProviderPreferenceTest.java b/tests/robotests/src/com/android/settings/accounts/ProviderPreferenceTest.java
index e084ada..ce1dcb2 100644
--- a/tests/robotests/src/com/android/settings/accounts/ProviderPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/ProviderPreferenceTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.accounts;
 
+import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_MEDIUM;
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
@@ -42,8 +43,8 @@
     public void shouldUseSmallIcon() {
         final ProviderPreference providerPreference = new ProviderPreference(
                 mContext, "account_type", null /* icon */, "provider_name");
-        final boolean useSmallIcon =
-                ReflectionHelpers.getField(providerPreference, "mUseSmallIcon");
-        assertThat(useSmallIcon).isTrue();
+        final int iconSize =
+                ReflectionHelpers.getField(providerPreference, "mIconSize");
+        assertThat(iconSize).isEqualTo(ICON_SIZE_MEDIUM);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
index 1c0130a..4377c4f 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
@@ -16,7 +16,6 @@
 
 package com.android.settings.applications.defaultapps;
 
-import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
@@ -31,7 +30,6 @@
 import android.util.Pair;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.widget.RadioButtonPreference;
@@ -96,12 +94,6 @@
                 any(Pair.class));
     }
 
-    @Test
-    public void shouldHaveAppPreferenceLayout() {
-        assertThat(mFragment.getRadioButtonPreferenceCustomLayoutResId())
-                .isEqualTo(R.layout.preference_app);
-    }
-
     public static class TestFragment extends DefaultAppPickerFragment {
 
         boolean setDefaultAppKeyCalled;
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceControllerTest.java
index e87d16f..e348d8c 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceControllerTest.java
@@ -17,6 +17,7 @@
 package com.android.settings.applications.defaultapps;
 
 
+import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_MEDIUM;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -27,8 +28,8 @@
 
 import com.android.settings.R;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.applications.DefaultAppInfo;
 import com.android.settingslib.TwoTargetPreference;
+import com.android.settingslib.applications.DefaultAppInfo;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -78,13 +79,13 @@
     }
 
     @Test
-    public void updateState_twoTargetPref_shouldUseSmallIcon() {
+    public void updateState_twoTargetPref_shouldUseMediumIcon() {
         final TwoTargetPreference pref = mock(TwoTargetPreference.class);
         mController = new TestPreferenceController(mContext);
 
         mController.updateState(pref);
 
-        verify(pref).setUseSmallIcon(true);
+        verify(pref).setIconSize(ICON_SIZE_MEDIUM);
     }
 
     private static class TestPreferenceController extends DefaultAppPreferenceController {
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java
index 928e1c6..ad04e7e 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java
@@ -70,7 +70,7 @@
         assertThat(mDeviceUpdater.mUsbPreference.getTitle()).isEqualTo("USB");
         assertThat(mDeviceUpdater.mUsbPreference.getIcon())
             .isEqualTo(mContext.getDrawable(R.drawable.ic_usb));
-        assertThat(mDeviceUpdater.mUsbPreference.isSelectable()).isFalse();
+        assertThat(mDeviceUpdater.mUsbPreference.isSelectable()).isTrue();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/DndConditionTest.java b/tests/robotests/src/com/android/settings/dashboard/conditional/DndConditionTest.java
index d68a675..35940ce 100644
--- a/tests/robotests/src/com/android/settings/dashboard/conditional/DndConditionTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/conditional/DndConditionTest.java
@@ -23,6 +23,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -104,4 +106,13 @@
 
         verify(mContext, never()).unregisterReceiver(any(DndCondition.Receiver.class));
     }
+
+    @Test
+    public void nullZenConfig_noCrash() {
+        DndCondition condition = new DndCondition(mConditionManager);
+        assertThat(condition.mConfig).isNull();
+
+        // should not crash, instead summary is null
+        assertThat(condition.getSummary()).isNull();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/datausage/ChartDataUsagePreferenceTest.java b/tests/robotests/src/com/android/settings/datausage/ChartDataUsagePreferenceTest.java
index 541aeae..00d02a3 100644
--- a/tests/robotests/src/com/android/settings/datausage/ChartDataUsagePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/ChartDataUsagePreferenceTest.java
@@ -39,11 +39,11 @@
 
     private static final long MILLIS_IN_ONE_HOUR = 60 * 60 * 1000;
     private static final long MILLIS_IN_ONE_DAY = 24 * MILLIS_IN_ONE_HOUR;
+    private static final long TIMESTAMP_NOW = Integer.MAX_VALUE;
 
     private NetworkStatsHistory mNetworkStatsHistory;
     private Context mContext;
     private ChartDataUsagePreference mPreference;
-    private long mNow;
 
     @Before
     public void setUp() {
@@ -51,7 +51,6 @@
 
         mContext = RuntimeEnvironment.application;
         mPreference = new ChartDataUsagePreference(mContext, null);
-        mNow = System.currentTimeMillis();
         mNetworkStatsHistory = spy(new NetworkStatsHistory(MILLIS_IN_ONE_HOUR, 10));
         addTestNetworkEntries();
         mPreference.setNetworkStats(mNetworkStatsHistory);
@@ -59,8 +58,8 @@
 
     @Test
     public void calcPoints_notStartOfData_shouldAddDataPointsOnly() {
-        final long start = mNow - 20 * MILLIS_IN_ONE_DAY;
-        final long end = mNow - 5 * MILLIS_IN_ONE_DAY;
+        final long start = TIMESTAMP_NOW - 20 * MILLIS_IN_ONE_DAY;
+        final long end = TIMESTAMP_NOW - 5 * MILLIS_IN_ONE_DAY;
         mPreference.setVisibleRange(start, end);
         when(mNetworkStatsHistory.getIndexAfter(start)).thenReturn(2);
         when(mNetworkStatsHistory.getIndexAfter(end)).thenReturn(7);
@@ -78,8 +77,8 @@
 
     @Test
     public void calcPoints_startOfData_shouldIndicateStartOfData() {
-        final long start = mNow - 20 * MILLIS_IN_ONE_DAY;
-        final long end = mNow - 5 * MILLIS_IN_ONE_DAY;
+        final long start = TIMESTAMP_NOW - 20 * MILLIS_IN_ONE_DAY;
+        final long end = TIMESTAMP_NOW - 5 * MILLIS_IN_ONE_DAY;
         mPreference.setVisibleRange(start, end);
         when(mNetworkStatsHistory.getIndexAfter(start)).thenReturn(0);
         when(mNetworkStatsHistory.getIndexAfter(end)).thenReturn(5);
@@ -104,10 +103,10 @@
         mNetworkStatsHistory.setValues(3, createEntry(1521655200000L, 83849690L, 3558238L));
         mNetworkStatsHistory.setValues(4, createEntry(1521658800000L, 1883657L, 353330L));
         mNetworkStatsHistory.setValues(5, createEntry(1521662400000L, 705259L, 279065L));
-        mNetworkStatsHistory.setValues(5, createEntry(1521666000000L, 216169L, 155302L));
-        mNetworkStatsHistory.setValues(5, createEntry(1521669600000L, 6069175L, 427581L));
-        mNetworkStatsHistory.setValues(5, createEntry(1521673200000L, 120389L, 110807L));
-        mNetworkStatsHistory.setValues(5, createEntry(1521676800000L, 29947L, 73257L));
+        mNetworkStatsHistory.setValues(6, createEntry(1521666000000L, 216169L, 155302L));
+        mNetworkStatsHistory.setValues(7, createEntry(1521669600000L, 6069175L, 427581L));
+        mNetworkStatsHistory.setValues(8, createEntry(1521673200000L, 120389L, 110807L));
+        mNetworkStatsHistory.setValues(9, createEntry(1521676800000L, 29947L, 73257L));
     }
 
     /**
diff --git a/tests/robotests/src/com/android/settings/display/AmbientDisplaySettingsTest.java b/tests/robotests/src/com/android/settings/display/AmbientDisplaySettingsTest.java
index 2f61252..4361b7c 100644
--- a/tests/robotests/src/com/android/settings/display/AmbientDisplaySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/display/AmbientDisplaySettingsTest.java
@@ -24,6 +24,8 @@
 
 import android.content.Context;
 
+import com.android.settings.gestures.DoubleTapScreenPreferenceController;
+import com.android.settings.gestures.PickupGesturePreferenceController;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.core.AbstractPreferenceController;
 
@@ -48,18 +50,48 @@
     }
 
     @Test
-    public void onAttach_shouldInvokeSetters() {
-        final AmbientDisplayAlwaysOnPreferenceController controller = mock(
-                AmbientDisplayAlwaysOnPreferenceController.class);
+    public void onAttach_alwaysOn_shouldInvokeSetters() {
+        final AmbientDisplayAlwaysOnPreferenceController controller = spy(
+                new AmbientDisplayAlwaysOnPreferenceController(mContext, "key"));
         doReturn(controller).when(mTestFragment).use(
                 AmbientDisplayAlwaysOnPreferenceController.class);
 
         mTestFragment.onAttach(mContext);
-
         verify(controller).setConfig(any());
         verify(controller).setCallback(any());
     }
 
+    @Test
+    public void onAttach_notifications_shouldInvokeSetters() {
+        final AmbientDisplayNotificationsPreferenceController controller = spy(
+                new AmbientDisplayNotificationsPreferenceController(mContext, "key"));
+        doReturn(controller).when(mTestFragment).use(
+                AmbientDisplayNotificationsPreferenceController.class);
+
+        mTestFragment.onAttach(mContext);
+        verify(controller).setConfig(any());
+    }
+
+    @Test
+    public void onAttach_doubleTap_shouldInvokeSetters() {
+        final DoubleTapScreenPreferenceController controller = spy(
+                new DoubleTapScreenPreferenceController(mContext, "key"));
+        doReturn(controller).when(mTestFragment).use(DoubleTapScreenPreferenceController.class);
+
+        mTestFragment.onAttach(mContext);
+        verify(controller).setConfig(any());
+    }
+
+    @Test
+    public void onAttach_pickUp_shouldInvokeSetters() {
+        final PickupGesturePreferenceController controller = spy(
+                new PickupGesturePreferenceController(mContext, "key"));
+        doReturn(controller).when(mTestFragment).use(PickupGesturePreferenceController.class);
+
+        mTestFragment.onAttach(mContext);
+        verify(controller).setConfig(any());
+    }
+
     public static class TestFragment extends AmbientDisplaySettings {
         @Override
         protected <T extends AbstractPreferenceController> T use(Class<T> clazz) {
diff --git a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
index 6df0c04..a9f4151 100644
--- a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
@@ -79,15 +79,13 @@
         when(mFragment.getContext()).thenReturn(RuntimeEnvironment.application);
         List<? extends CandidateInfo> candidates = mFragment.getCandidates();
 
-        assertThat(candidates.size()).isEqualTo(4);
+        assertThat(candidates.size()).isEqualTo(3);
         assertThat(candidates.get(0).getKey())
                 .isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_NATURAL);
         assertThat(candidates.get(1).getKey())
                 .isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_BOOSTED);
         assertThat(candidates.get(2).getKey())
                 .isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_SATURATED);
-        assertThat(candidates.get(3).getKey())
-                .isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_AUTOMATIC);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
index 40371d7..fb65e5d 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
@@ -126,7 +126,7 @@
         SpannableStringBuilder disclosure = new SpannableStringBuilder();
         disclosure.append(mResources.getString(R.string.do_disclosure_generic));
         disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator));
-        disclosure.append(mResources.getString(R.string.do_disclosure_learn_more),
+        disclosure.append(mResources.getString(R.string.learn_more),
                 new EnterprisePrivacyFeatureProviderImpl.EnterprisePrivacySpan(mContext), 0);
         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(OWNER);
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
@@ -136,7 +136,7 @@
         disclosure.append(mResources.getString(R.string.do_disclosure_with_name,
                 OWNER_ORGANIZATION));
         disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator));
-        disclosure.append(mResources.getString(R.string.do_disclosure_learn_more),
+        disclosure.append(mResources.getString(R.string.learn_more),
                 new EnterprisePrivacyFeatureProviderImpl.EnterprisePrivacySpan(mContext), 0);
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(OWNER_ORGANIZATION);
         assertThat(mProvider.getDeviceOwnerDisclosure()).isEqualTo(disclosure);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
index b6be9ee..b89a3f0 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
@@ -29,6 +29,7 @@
 
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatterySipper.DrainType;
+import com.android.settings.R;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -38,6 +39,7 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
 
 import java.util.Locale;
 
@@ -137,6 +139,17 @@
     }
 
     @Test
+    public void batteryEntryForAOD_containCorrectInfo() {
+        final BatterySipper batterySipper = mock(BatterySipper.class);
+        batterySipper.drainType = DrainType.AMBIENT_DISPLAY;
+        final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
+                mockUserManager, batterySipper);
+
+        assertThat(entry.iconId).isEqualTo(R.drawable.ic_settings_aod);
+        assertThat(entry.name).isEqualTo("Ambient display");
+    }
+
+    @Test
     public void extractPackageFromSipper_systemSipper_returnSystemPackage() {
         BatteryEntry entry = createBatteryEntryForSystem();
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index 8b1076d..e05ff52 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -377,6 +377,18 @@
     }
 
     @Test
+    public void testSmearScreenBatterySipper_screenSipperNull_shouldNotCrash() {
+        final BatterySipper sipperFg = createTestSmearBatterySipper(TIME_FOREGROUND,
+                BATTERY_APP_USAGE, 2 /* uid */, false /* isUidNull */);
+
+        final List<BatterySipper> sippers = new ArrayList<>();
+        sippers.add(sipperFg);
+
+        // Shouldn't crash
+        mBatteryUtils.smearScreenBatterySipper(sippers, null /* screenSipper */);
+    }
+
+    @Test
     public void testCalculateRunningTimeBasedOnStatsType() {
         assertThat(mBatteryUtils.calculateRunningTimeBasedOnStatsType(mBatteryStatsHelper,
                 BatteryStats.STATS_SINCE_CHARGED)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java
index d1a85ce..49567f6 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java
@@ -16,6 +16,10 @@
 
 package com.android.settings.fuelgauge.batterytip;
 
+import static android.os.StatsDimensionsValue.FLOAT_VALUE_TYPE;
+import static android.os.StatsDimensionsValue.INT_VALUE_TYPE;
+import static android.os.StatsDimensionsValue.TUPLE_VALUE_TYPE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Matchers.any;
@@ -24,9 +28,11 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 import static org.robolectric.RuntimeEnvironment.application;
 
 import android.app.StatsManager;
@@ -35,6 +41,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.Process;
 import android.os.StatsDimensionsValue;
 import android.os.UserManager;
@@ -149,6 +157,21 @@
     }
 
     @Test
+    public void testSaveAnomalyToDatabase_uidNull_doNotSave() {
+        doReturn(AnomalyDetectionJobService.UID_NULL).when(
+                mAnomalyDetectionJobService).extractUidFromStatsDimensionsValue(any());
+
+        mAnomalyDetectionJobService.saveAnomalyToDatabase(mContext, mBatteryStatsHelper,
+                mUserManager, mBatteryDatabaseManager, mBatteryUtils, mPolicy,
+                mPowerWhitelistBackend, mContext.getContentResolver(),
+                mFeatureFactory.powerUsageFeatureProvider, mFeatureFactory.metricsFeatureProvider,
+                mBundle);
+
+        verify(mBatteryDatabaseManager, never()).insertAnomaly(anyInt(), anyString(), anyInt(),
+                anyInt(), anyLong());
+    }
+
+    @Test
     public void testSaveAnomalyToDatabase_normalAppWithAutoRestriction_save() {
         final ArrayList<String> cookies = new ArrayList<>();
         cookies.add(SUBSCRIBER_COOKIES_AUTO_RESTRICTION);
@@ -196,4 +219,35 @@
                 SYSTEM_PACKAGE,
                 Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE, ANOMALY_TYPE));
     }
+
+    @Test
+    public void testExtractUidFromStatsDimensionsValue_extractCorrectUid() {
+        // Build an integer dimensions value.
+        final StatsDimensionsValue intValue = mock(StatsDimensionsValue.class);
+        when(intValue.isValueType(INT_VALUE_TYPE)).thenReturn(true);
+        when(intValue.getField()).thenReturn(AnomalyDetectionJobService.STATSD_UID_FILED);
+        when(intValue.getIntValue()).thenReturn(UID);
+
+        // Build a tuple dimensions value and put the previous integer dimensions value inside.
+        final StatsDimensionsValue tupleValue = mock(StatsDimensionsValue.class);
+        when(tupleValue.isValueType(TUPLE_VALUE_TYPE)).thenReturn(true);
+        final List<StatsDimensionsValue> statsDimensionsValues = new ArrayList<>();
+        statsDimensionsValues.add(intValue);
+        when(tupleValue.getTupleValueList()).thenReturn(statsDimensionsValues);
+
+        assertThat(mAnomalyDetectionJobService.extractUidFromStatsDimensionsValue(
+                tupleValue)).isEqualTo(UID);
+    }
+
+    @Test
+    public void testExtractUidFromStatsDimensionsValue_wrongFormat_returnNull() {
+        // Build a float dimensions value
+        final StatsDimensionsValue floatValue = mock(StatsDimensionsValue.class);
+        when(floatValue.isValueType(FLOAT_VALUE_TYPE)).thenReturn(true);
+        when(floatValue.getField()).thenReturn(AnomalyDetectionJobService.STATSD_UID_FILED);
+        when(floatValue.getFloatValue()).thenReturn(0f);
+
+        assertThat(mAnomalyDetectionJobService.extractUidFromStatsDimensionsValue(
+                floatValue)).isEqualTo(AnomalyDetectionJobService.UID_NULL);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsPreferenceControllerTest.java
index 3b5facd..bd96f0f 100644
--- a/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsPreferenceControllerTest.java
@@ -55,8 +55,8 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mFactory = FakeFeatureFactory.setupForTest();
-        mController =
-            new AssistGestureSettingsPreferenceController(mContext, null, KEY_ASSIST, false);
+        mController = new AssistGestureSettingsPreferenceController(mContext, KEY_ASSIST);
+        mController.setAssistOnly(false);
     }
 
     @Test
@@ -76,8 +76,8 @@
     public void testPreferenceController_ProperResultPayloadType() {
         final Context context = RuntimeEnvironment.application;
         AssistGestureSettingsPreferenceController controller =
-                new AssistGestureSettingsPreferenceController(context, null /* lifecycle */,
-                        KEY_ASSIST, false /* assistOnly */);
+                new AssistGestureSettingsPreferenceController(context, KEY_ASSIST);
+        controller.setAssistOnly(false);
         ResultPayload payload = controller.getResultPayload();
         assertThat(payload).isInstanceOf(InlineSwitchPayload.class);
     }
diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java
index e8c036e..d681bc3 100644
--- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java
@@ -56,7 +56,7 @@
     public void setUp() {
         mContext = RuntimeEnvironment.application;
         mContentResolver = mContext.getContentResolver();
-        mController = new DoubleTapPowerPreferenceController(mContext, null, KEY_DOUBLE_TAP_POWER);
+        mController = new DoubleTapPowerPreferenceController(mContext, KEY_DOUBLE_TAP_POWER);
     }
 
     @After
@@ -81,28 +81,27 @@
     }
 
     @Test
-    public void testSwitchEnabled_configIsNotSet_shouldReturnTrue() {
+    public void testIsChecked_configIsNotSet_shouldReturnTrue() {
         // Set the setting to be enabled.
         Settings.System.putInt(mContentResolver, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, ON);
-        mController = new DoubleTapPowerPreferenceController(mContext, null, KEY_DOUBLE_TAP_POWER);
+        mController = new DoubleTapPowerPreferenceController(mContext, KEY_DOUBLE_TAP_POWER);
 
-        assertThat(mController.isSwitchPrefEnabled()).isTrue();
+        assertThat(mController.isChecked()).isTrue();
     }
 
     @Test
-    public void testSwitchEnabled_configIsSet_shouldReturnFalse() {
+    public void testIsChecked_configIsSet_shouldReturnFalse() {
         // Set the setting to be disabled.
         Settings.System.putInt(mContentResolver, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, OFF);
-        mController = new DoubleTapPowerPreferenceController(mContext, null, KEY_DOUBLE_TAP_POWER);
+        mController = new DoubleTapPowerPreferenceController(mContext, KEY_DOUBLE_TAP_POWER);
 
-        assertThat(mController.isSwitchPrefEnabled()).isFalse();
+        assertThat(mController.isChecked()).isFalse();
     }
 
     @Test
     public void testPreferenceController_ProperResultPayloadType() {
         DoubleTapPowerPreferenceController controller =
-            new DoubleTapPowerPreferenceController(mContext, null /* lifecycle */,
-                KEY_DOUBLE_TAP_POWER);
+            new DoubleTapPowerPreferenceController(mContext, KEY_DOUBLE_TAP_POWER);
         ResultPayload payload = controller.getResultPayload();
         assertThat(payload).isInstanceOf(InlineSwitchPayload.class);
     }
diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java
index 344156c..cc9347d 100644
--- a/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java
@@ -56,8 +56,8 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mController = new DoubleTapScreenPreferenceController(
-                mContext, null, mAmbientDisplayConfiguration, 0, KEY_DOUBLE_TAP_SCREEN);
+        mController = new DoubleTapScreenPreferenceController(mContext, KEY_DOUBLE_TAP_SCREEN);
+        mController.setConfig(mAmbientDisplayConfiguration);
     }
 
     @Test
@@ -75,26 +75,26 @@
     }
 
     @Test
-    public void testSwitchEnabled_configIsSet_shouldReturnTrue() {
+    public void testIsChecked_configIsSet_shouldReturnTrue() {
         // Set the setting to be enabled.
         when(mAmbientDisplayConfiguration.pulseOnDoubleTapEnabled(anyInt())).thenReturn(true);
 
-        assertThat(mController.isSwitchPrefEnabled()).isTrue();
+        assertThat(mController.isChecked()).isTrue();
     }
 
     @Test
-    public void testSwitchEnabled_configIsNotSet_shouldReturnFalse() {
+    public void testIsChecked_configIsNotSet_shouldReturnFalse() {
         when(mAmbientDisplayConfiguration.pulseOnDoubleTapEnabled(anyInt())).thenReturn(false);
 
-        assertThat(mController.isSwitchPrefEnabled()).isFalse();
+        assertThat(mController.isChecked()).isFalse();
     }
 
     @Test
     public void testPreferenceController_ProperResultPayloadType() {
         final Context context = RuntimeEnvironment.application;
         DoubleTapScreenPreferenceController controller =
-                new DoubleTapScreenPreferenceController(context, null /* lifecycle */,
-                        mAmbientDisplayConfiguration, 0 /* userid */, KEY_DOUBLE_TAP_SCREEN);
+                new DoubleTapScreenPreferenceController(context, KEY_DOUBLE_TAP_SCREEN);
+        controller.setConfig(mAmbientDisplayConfiguration);
         ResultPayload payload = controller.getResultPayload();
         assertThat(payload).isInstanceOf(InlineSwitchPayload.class);
     }
diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java
index d633ebe..901da37 100644
--- a/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java
@@ -61,7 +61,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mock(UserManager.class));
-        mController = new DoubleTwistPreferenceController(mContext, null, KEY_DOUBLE_TWIST);
+        mController = new DoubleTwistPreferenceController(mContext, KEY_DOUBLE_TWIST);
     }
 
     @After
@@ -120,7 +120,7 @@
         Settings.Secure.putIntForUser(
                 null, Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 0, managedId);
         DoubleTwistPreferenceController controller =
-                spy(new DoubleTwistPreferenceController(mContext, null, KEY_DOUBLE_TWIST));
+                spy(new DoubleTwistPreferenceController(mContext, KEY_DOUBLE_TWIST));
         ShadowDoubleTwistPreferenceController.setManagedProfileId(managedId);
 
         // enable the gesture
@@ -135,24 +135,24 @@
     }
 
     @Test
-    public void testSwitchEnabled_configIsSet_shouldReturnTrue() {
+    public void testIsChecked_configIsSet_shouldReturnTrue() {
         // Set the setting to be enabled.
         final Context context = RuntimeEnvironment.application;
         Settings.System.putInt(context.getContentResolver(),
                 Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 1);
-        mController = new DoubleTwistPreferenceController(context, null, KEY_DOUBLE_TWIST);
+        mController = new DoubleTwistPreferenceController(context, KEY_DOUBLE_TWIST);
 
-        assertThat(mController.isSwitchPrefEnabled()).isTrue();
+        assertThat(mController.isChecked()).isTrue();
     }
 
     @Test
-    public void testSwitchEnabled_configIsNotSet_shouldReturnFalse() {
+    public void testIsChecked_configIsNotSet_shouldReturnFalse() {
         // Set the setting to be disabled.
         final Context context = RuntimeEnvironment.application;
         Settings.System.putInt(context.getContentResolver(),
                 Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 0);
-        mController = new DoubleTwistPreferenceController(context, null, KEY_DOUBLE_TWIST);
+        mController = new DoubleTwistPreferenceController(context, KEY_DOUBLE_TWIST);
 
-        assertThat(mController.isSwitchPrefEnabled()).isFalse();
+        assertThat(mController.isChecked()).isFalse();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java
index 361c95d..d4b7706 100644
--- a/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java
@@ -17,6 +17,9 @@
 package com.android.settings.gestures;
 
 import static com.google.common.truth.Truth.assertThat;
+
+import static junit.framework.Assert.assertEquals;
+
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -31,7 +34,6 @@
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.widget.VideoPreference;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -49,7 +51,6 @@
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private PreferenceScreen mScreen;
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Lifecycle mLifecycle;
 
     private TestPrefController mController;
     private Preference mPreference;
@@ -57,7 +58,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mController = new TestPrefController(mContext, mLifecycle);
+        mController = new TestPrefController(mContext, "testKey");
         mPreference = new Preference(RuntimeEnvironment.application);
         mPreference.setKey(mController.getPreferenceKey());
         when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
@@ -187,7 +188,8 @@
         mController.updateState(preference);
 
         // Verify summary is set to off (as setting is disabled).
-        verify(preference).setSummary(com.android.settings.R.string.gesture_setting_off);
+        assertThat(preference.getSummary()).isEqualTo(
+                mContext.getString(com.android.settings.R.string.gesture_setting_off));
     }
 
     private class TestPrefController extends GesturePreferenceController {
@@ -196,18 +198,13 @@
         boolean mIsPrefEnabled;
 
         private TestPrefController(Context context,
-                Lifecycle lifecycle) {
-            super(context, lifecycle);
+                String key) {
+            super(context, key);
         }
 
         @Override
-        public boolean isAvailable() {
-            return mIsPrefAvailable;
-        }
-
-        @Override
-        public String getPreferenceKey() {
-            return "testKey";
+        public int getAvailabilityStatus() {
+            return mIsPrefAvailable ? AVAILABLE : DISABLED_UNSUPPORTED;
         }
 
         @Override
@@ -216,12 +213,12 @@
         }
 
         @Override
-        protected boolean isSwitchPrefEnabled() {
+        public boolean isChecked() {
             return mIsPrefEnabled;
         }
 
         @Override
-        public boolean onPreferenceChange(Preference preference, Object newValue) {
+        public boolean setChecked(boolean isChecked) {
             return false;
         }
     }
diff --git a/tests/robotests/src/com/android/settings/gestures/PickupGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PickupGesturePreferenceControllerTest.java
index 09e9ff7..6aa451c 100644
--- a/tests/robotests/src/com/android/settings/gestures/PickupGesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/PickupGesturePreferenceControllerTest.java
@@ -57,8 +57,8 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mController = new PickupGesturePreferenceController(
-                mContext, null, mAmbientDisplayConfiguration, 0, KEY_PICK_UP);
+        mController = new PickupGesturePreferenceController(mContext, KEY_PICK_UP);
+        mController.setConfig(mAmbientDisplayConfiguration);
     }
 
     @Test
@@ -76,19 +76,19 @@
     }
 
     @Test
-    public void testSwitchEnabled_configIsSet_shouldReturnTrue() {
+    public void testIsChecked_configIsSet_shouldReturnTrue() {
         // Set the setting to be enabled.
         when(mAmbientDisplayConfiguration.pulseOnPickupEnabled(anyInt())).thenReturn(true);
 
-        assertThat(mController.isSwitchPrefEnabled()).isTrue();
+        assertThat(mController.isChecked()).isTrue();
     }
 
     @Test
-    public void testSwitchEnabled_configIsNotSet_shouldReturnFalse() {
+    public void testIsChecked_configIsNotSet_shouldReturnFalse() {
         // Set the setting to be disabled.
         when(mAmbientDisplayConfiguration.pulseOnPickupEnabled(anyInt())).thenReturn(false);
 
-        assertThat(mController.isSwitchPrefEnabled()).isFalse();
+        assertThat(mController.isChecked()).isFalse();
     }
 
     @Test
@@ -111,8 +111,8 @@
     public void testPreferenceController_ProperResultPayloadType() {
         final Context context = RuntimeEnvironment.application;
         PickupGesturePreferenceController controller =
-                new PickupGesturePreferenceController(
-                        context, null, mAmbientDisplayConfiguration, 0, KEY_PICK_UP);
+                new PickupGesturePreferenceController(context, KEY_PICK_UP);
+        controller.setConfig(mAmbientDisplayConfiguration);
         ResultPayload payload = controller.getResultPayload();
         assertThat(payload).isInstanceOf(InlineSwitchPayload.class);
     }
diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java
index 69226b6..c164fbf 100644
--- a/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java
@@ -53,7 +53,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mController = new SwipeToNotificationPreferenceController(mContext, null, KEY_SWIPE_DOWN);
+        mController = new SwipeToNotificationPreferenceController(mContext, KEY_SWIPE_DOWN);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mContext.getSystemService(Context.FINGERPRINT_SERVICE))
                 .thenReturn(mFingerprintManager);
@@ -93,27 +93,27 @@
     }
 
     @Test
-    public void testSwitchEnabled_configIsSet_shouldReturnTrue() {
+    public void testIsChecked_configIsSet_shouldReturnTrue() {
         stubFingerprintSupported(true);
         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
         // Set the setting to be enabled.
         final Context context = RuntimeEnvironment.application;
         Settings.System.putInt(context.getContentResolver(), SYSTEM_NAVIGATION_KEYS_ENABLED, 1);
-        mController = new SwipeToNotificationPreferenceController(context, null, KEY_SWIPE_DOWN);
+        mController = new SwipeToNotificationPreferenceController(context, KEY_SWIPE_DOWN);
 
-        assertThat(mController.isSwitchPrefEnabled()).isTrue();
+        assertThat(mController.isChecked()).isTrue();
     }
 
     @Test
-    public void testSwitchEnabled_configIsNotSet_shouldReturnFalse() {
+    public void testIsChecked_configIsNotSet_shouldReturnFalse() {
         stubFingerprintSupported(true);
         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
         // Set the setting to be disabled.
         final Context context = RuntimeEnvironment.application;
         Settings.System.putInt(context.getContentResolver(), SYSTEM_NAVIGATION_KEYS_ENABLED, 0);
-        mController = new SwipeToNotificationPreferenceController(context, null, KEY_SWIPE_DOWN);
+        mController = new SwipeToNotificationPreferenceController(context, KEY_SWIPE_DOWN);
 
-        assertThat(mController.isSwitchPrefEnabled()).isFalse();
+        assertThat(mController.isChecked()).isFalse();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationSettingsTest.java
index 78f1917..78e8603 100644
--- a/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationSettingsTest.java
@@ -54,14 +54,6 @@
     }
 
     @Test
-    public void testGetPreferenceControllers_shouldAllBeCreated() {
-        final List<AbstractPreferenceController> controllers =
-                mFragment.createPreferenceControllers(mContext);
-
-        assertThat(controllers.isEmpty()).isFalse();
-    }
-
-    @Test
     public void testSearchIndexProvider_shouldIndexResource() {
         final List<SearchIndexableResource> indexRes =
             SwipeToNotificationSettings.SEARCH_INDEX_DATA_PROVIDER
diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java
index c5521be..e9ffa8a 100644
--- a/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java
@@ -111,8 +111,10 @@
 
     @Test
     public void testOnBindDialogView_containsCorrectData() {
+        // Don't set settings to the default value ("opportunistic") as that
+        // risks masking failure to read the mode from settings.
         Settings.Global.putString(mContext.getContentResolver(),
-                PrivateDnsModeDialogPreference.MODE_KEY, PRIVATE_DNS_MODE_OPPORTUNISTIC);
+                PrivateDnsModeDialogPreference.MODE_KEY, PRIVATE_DNS_MODE_OFF);
         Settings.Global.putString(mContext.getContentResolver(),
                 PrivateDnsModeDialogPreference.HOSTNAME_KEY, HOST_NAME);
 
@@ -123,7 +125,7 @@
 
         assertThat(mPreference.mEditText.getText().toString()).isEqualTo(HOST_NAME);
         assertThat(mPreference.mRadioGroup.getCheckedRadioButtonId()).isEqualTo(
-                R.id.private_dns_mode_opportunistic);
+                R.id.private_dns_mode_off);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java
new file mode 100644
index 0000000..83d4bd5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.network;
+
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
+import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.arch.lifecycle.LifecycleOwner;
+import android.content.Context;
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+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 org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowContentResolver;
+
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class PrivateDnsPreferenceControllerTest {
+
+    private final static String HOSTNAME = "dns.example.com";
+
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private Preference mPreference;
+    private PrivateDnsPreferenceController mController;
+    private Context mContext;
+    private ContentResolver mContentResolver;
+    private ShadowContentResolver mShadowContentResolver;
+    private Lifecycle mLifecycle;
+    private LifecycleOwner mLifecycleOwner;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mContentResolver = mContext.getContentResolver();
+        mShadowContentResolver = Shadow.extract(mContentResolver);
+
+        when(mScreen.findPreference(anyString())).thenReturn(mPreference);
+
+        mController = spy(new PrivateDnsPreferenceController(mContext));
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mLifecycle.addObserver(mController);
+    }
+
+    @Test
+    public void goThroughLifecycle_shouldRegisterUnregisterSettingsObserver() {
+        mLifecycle.handleLifecycleEvent(ON_START);
+        verify(mContext, atLeastOnce()).getContentResolver();
+        assertThat(mShadowContentResolver.getContentObservers(
+                Settings.Global.getUriFor(PRIVATE_DNS_MODE))).isNotEmpty();
+        assertThat(mShadowContentResolver.getContentObservers(
+                Settings.Global.getUriFor(PRIVATE_DNS_SPECIFIER))).isNotEmpty();
+
+
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+        verify(mContext, atLeastOnce()).getContentResolver();
+        assertThat(mShadowContentResolver.getContentObservers(
+                Settings.Global.getUriFor(PRIVATE_DNS_MODE))).isEmpty();
+        assertThat(mShadowContentResolver.getContentObservers(
+                Settings.Global.getUriFor(PRIVATE_DNS_SPECIFIER))).isEmpty();
+    }
+
+    @Test
+    public void getSummary_PrivateDnsModeOff() {
+        setPrivateDnsMode(PRIVATE_DNS_MODE_OFF);
+        setPrivateDnsProviderHostname(HOSTNAME);
+        mController.updateState(mPreference);
+        verify(mController, atLeastOnce()).getSummary();
+        verify(mPreference).setSummary(getResourceString(R.string.private_dns_mode_off));
+    }
+
+    @Test
+    public void getSummary_PrivateDnsModeOpportunistic() {
+        setPrivateDnsMode(PRIVATE_DNS_MODE_OPPORTUNISTIC);
+        setPrivateDnsProviderHostname(HOSTNAME);
+        mController.updateState(mPreference);
+        verify(mController, atLeastOnce()).getSummary();
+        verify(mPreference).setSummary(getResourceString(R.string.private_dns_mode_opportunistic));
+    }
+
+    @Test
+    public void getSummary_PrivateDnsModeProviderHostname() {
+        setPrivateDnsMode(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+        setPrivateDnsProviderHostname(HOSTNAME);
+        mController.updateState(mPreference);
+        verify(mController, atLeastOnce()).getSummary();
+        verify(mPreference).setSummary(HOSTNAME);
+    }
+
+    private void setPrivateDnsMode(String mode) {
+        Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, mode);
+    }
+
+    private void setPrivateDnsProviderHostname(String name) {
+        Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, name);
+    }
+
+    private String getResourceString(int which) {
+        return mContext.getResources().getString(which);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java
index 999f83a..31b2eb1 100644
--- a/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java
@@ -43,6 +43,7 @@
 @RunWith(SettingsRobolectricTestRunner.class)
 public class AdjustVolumeRestrictedPreferenceControllerTest {
 
+    private static final String KEY = "key";
     @Mock
     private AccountRestrictionHelper mAccountHelper;
 
@@ -54,7 +55,7 @@
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
         mController =
-            new AdjustVolumeRestrictedPreferenceControllerTestable(mContext, mAccountHelper);
+            new AdjustVolumeRestrictedPreferenceControllerTestable(mContext, mAccountHelper, KEY);
     }
 
     @Test
@@ -88,13 +89,18 @@
         extends AdjustVolumeRestrictedPreferenceController {
 
         private AdjustVolumeRestrictedPreferenceControllerTestable(Context context,
-            AccountRestrictionHelper helper) {
-            super(context, helper);
+            AccountRestrictionHelper helper, String key) {
+            super(context, helper, key);
+        }
+
+        @Override
+        public int getAvailabilityStatus() {
+            return 0;
         }
 
         @Override
         public String getPreferenceKey() {
-            return null;
+            return KEY;
         }
 
         @Override
@@ -103,8 +109,18 @@
         }
 
         @Override
-        public boolean isAvailable() {
-            return true;
+        public int getSliderPosition() {
+            return 0;
+        }
+
+        @Override
+        public boolean setSliderPosition(int position) {
+            return false;
+        }
+
+        @Override
+        public int getMaxSteps() {
+            return 0;
         }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java
index 017a26a..6e8476c 100644
--- a/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java
@@ -45,7 +45,8 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
-        mController = new AlarmVolumePreferenceController(mContext, null, null, mHelper);
+        mController = new AlarmVolumePreferenceController(mContext);
+        mController.setAudioHelper(mHelper);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java
index 29773d2..9a76647 100644
--- a/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java
@@ -109,6 +109,11 @@
         NotificationChannel channel = new NotificationChannel("cid", "cname", IMPORTANCE_NONE);
         mController.onResume(appRow, channel, group, null);
         assertEquals(channel.getName(), mController.getLabel());
+
+        NotificationChannel defaultChannel = new NotificationChannel(
+                NotificationChannel.DEFAULT_CHANNEL_ID, "", IMPORTANCE_NONE);
+        mController.onResume(appRow, defaultChannel, null, null);
+        assertEquals(appRow.label, mController.getLabel());
     }
 
     @Test
@@ -130,5 +135,10 @@
         mController.onResume(appRow, channel, null, null);
         assertFalse(mController.getSummary().toString().contains(group.getName()));
         assertTrue(mController.getSummary().toString().contains(appRow.label));
+
+        NotificationChannel defaultChannel = new NotificationChannel(
+                NotificationChannel.DEFAULT_CHANNEL_ID, "", IMPORTANCE_NONE);
+        mController.onResume(appRow, defaultChannel, null, null);
+        assertEquals("", mController.getSummary());
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/MediaVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/MediaVolumePreferenceControllerTest.java
index 65680b1..3659a30 100644
--- a/tests/robotests/src/com/android/settings/notification/MediaVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/MediaVolumePreferenceControllerTest.java
@@ -35,8 +35,7 @@
 
     @Before
     public void setUp() {
-        mController =
-            new MediaVolumePreferenceController(RuntimeEnvironment.application, null, null);
+        mController = new MediaVolumePreferenceController(RuntimeEnvironment.application);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
index 3ead72a..4fe384e 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
@@ -294,6 +294,30 @@
         assertTrue(mController.isChannelGroupBlockable());
     }
 
+    @Test
+    public void testIsDefaultChannel_noChannel() {
+        mController.onResume(mock(NotificationBackend.AppRow.class), null, null, null);
+
+        assertFalse(mController.isDefaultChannel());
+    }
+
+    @Test
+    public void testIsDefaultChannel_nonDefaultChannel() {
+        NotificationChannel channel = mock(NotificationChannel.class);
+        mController.onResume(mock(NotificationBackend.AppRow.class), channel, null, null);
+
+        assertFalse(mController.isDefaultChannel());
+    }
+
+    @Test
+    public void testIsDefaultChannel() {
+        NotificationChannel channel = mock(NotificationChannel.class);
+        when(channel.getId()).thenReturn(NotificationChannel.DEFAULT_CHANNEL_ID);
+        mController.onResume(mock(NotificationBackend.AppRow.class), channel, null, null);
+
+        assertTrue(mController.isDefaultChannel());
+    }
+
     private final class TestPreferenceController extends NotificationPreferenceController {
 
         private TestPreferenceController(Context context, NotificationBackend backend) {
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java
index 1c605b9..c209c1b 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java
@@ -57,7 +57,8 @@
         when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
         when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
         when(mContext.getSystemService(Context.VIBRATOR_SERVICE)).thenReturn(mVibrator);
-        mController = new NotificationVolumePreferenceController(mContext, null, null, mHelper);
+        mController = new NotificationVolumePreferenceController(mContext);
+        mController.setAudioHelper(mHelper);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java
index f5e87e7..e006530 100644
--- a/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java
@@ -65,7 +65,8 @@
         shadowContext.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
         mContext = RuntimeEnvironment.application;
         when(mNotificationManager.getEffectsSuppressor()).thenReturn(mSuppressor);
-        mController = new RingVolumePreferenceController(mContext, null, null, mHelper);
+        mController = new RingVolumePreferenceController(mContext);
+        mController.setAudioHelper(mHelper);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
index a6addb3..675ac57 100644
--- a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.notification;
 
+import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
@@ -46,6 +47,8 @@
     private VolumeSeekBarPreference mPreference;
     @Mock
     private VolumeSeekBarPreference.Callback mCallback;
+    @Mock
+    private AudioHelper mHelper;
 
     private VolumeSeekBarPreferenceControllerTestable mController;
 
@@ -53,7 +56,10 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mScreen.findPreference(nullable(String.class))).thenReturn(mPreference);
-        mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback);
+        when(mPreference.getKey()).thenReturn("key");
+        mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback,
+                mPreference.getKey());
+        mController.setAudioHelper(mHelper);
     }
 
     @Test
@@ -67,7 +73,8 @@
 
     @Test
     public void displayPreference_notAvailable_shouldNotUpdatePreference() {
-        mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback, false);
+        mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback, false,
+                mPreference.getKey());
 
         mController.displayPreference(mScreen);
 
@@ -94,6 +101,42 @@
         verify(mPreference).onActivityPause();
     }
 
+    @Test
+    public void sliderMethods_handleNullPreference() {
+        when(mHelper.getStreamVolume(mController.getAudioStream())).thenReturn(4);
+        when(mHelper.getMaxVolume(mController.getAudioStream())).thenReturn(10);
+
+        assertThat(mController.getMaxSteps()).isEqualTo(10);
+        assertThat(mController.getSliderPosition()).isEqualTo(4);
+
+        mController.setSliderPosition(9);
+        verify(mHelper).setStreamVolume(mController.getAudioStream(), 9);
+    }
+
+    @Test
+    public void setSliderPosition_passesAlongValue() {
+        mController.displayPreference(mScreen);
+
+        mController.setSliderPosition(2);
+        verify(mPreference).setProgress(2);
+    }
+
+    @Test
+    public void getMaxSteps_passesAlongValue() {
+        when(mPreference.getMax()).thenReturn(6);
+        mController.displayPreference(mScreen);
+
+        assertThat(mController.getMaxSteps()).isEqualTo(6);
+    }
+
+    @Test
+    public void getSliderPosition_passesAlongValue() {
+        when(mPreference.getProgress()).thenReturn(7);
+        mController.displayPreference(mScreen);
+
+        assertThat(mController.getSliderPosition()).isEqualTo(7);
+    }
+
     private class VolumeSeekBarPreferenceControllerTestable
         extends VolumeSeekBarPreferenceController {
 
@@ -103,19 +146,20 @@
         private boolean mAvailable;
 
         VolumeSeekBarPreferenceControllerTestable(Context context,
-            VolumeSeekBarPreference.Callback callback) {
-            this(context, callback, true);
+            VolumeSeekBarPreference.Callback callback, String key) {
+            this(context, callback, true, key);
         }
 
         VolumeSeekBarPreferenceControllerTestable(Context context,
-            VolumeSeekBarPreference.Callback callback, boolean available) {
-            super(context, callback, null);
+            VolumeSeekBarPreference.Callback callback, boolean available, String key) {
+            super(context, key);
+            setCallback(callback);
             mAvailable = available;
         }
 
         @Override
         public String getPreferenceKey() {
-            return null;
+            return "key";
         }
 
         @Override
@@ -124,8 +168,8 @@
         }
 
         @Override
-        public boolean isAvailable() {
-            return mAvailable;
+        public int getAvailabilityStatus() {
+            return mAvailable ? AVAILABLE : DISABLED_UNSUPPORTED;
         }
 
         @Override
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeSettingsTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeSettingsTest.java
index bd94bf5..d706d12 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeSettingsTest.java
@@ -72,6 +72,35 @@
     }
 
     @Test
+    public void testBlockedEffectsSummary_none() {
+        NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0, 0);
+        assertEquals("Never", mBuilder.getBlockedEffectsSummary(policy));
+    }
+
+    @Test
+    public void testBlockedEffectsSummary_screen_on() {
+        NotificationManager.Policy policy = new NotificationManager.Policy(
+                0, 0, 0, NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK);
+        assertEquals("When screen is on", mBuilder.getBlockedEffectsSummary(policy));
+    }
+
+    @Test
+    public void testBlockedEffectsSummary_screen_off() {
+        NotificationManager.Policy policy = new NotificationManager.Policy(
+                0, 0, 0, NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT);
+        assertEquals("When screen is off", mBuilder.getBlockedEffectsSummary(policy));
+    }
+
+    @Test
+    public void testBlockedEffectsSummary_both() {
+        NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0,
+                NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST
+                        | NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS);
+        assertEquals("When screen is off, When screen is on",
+                mBuilder.getBlockedEffectsSummary(policy));
+    }
+
+    @Test
     public void searchProvider_shouldIndexDefaultXml() {
         final List<SearchIndexableResource> sir = ZenModeSettings.SEARCH_INDEX_DATA_PROVIDER
                 .getXmlResourcesToIndex(mContext, true /* enabled */);
diff --git a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
new file mode 100644
index 0000000..3fd2239
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.notification;
+
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS;
+import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.app.NotificationManager.Policy;
+import android.content.Context;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+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.mockito.Answers;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ZenOnboardingActivityTest {
+
+    @Mock
+    MetricsLogger mMetricsLogger;
+    @Mock
+    NotificationManager mNm;
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+
+    ZenOnboardingActivity mActivity;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mActivity = Robolectric.buildActivity(ZenOnboardingActivity.class)
+                .create()
+                .get();
+        mActivity.setNotificationManager(mNm);
+        mActivity.setMetricsLogger(mMetricsLogger);
+
+        mActivity.setupUI();
+    }
+
+    @Test
+    public void loadUiRecordsEvent() {
+        verify(mMetricsLogger).visible(MetricsEvent.SETTINGS_ZEN_ONBOARDING);
+    }
+
+    @Test
+    public void toggleCheckBoxRecordsEvents_screenOn() {
+        mActivity.findViewById(R.id.screen_on_option).performClick();
+
+        verify(mMetricsLogger).action(MetricsEvent.ACTION_ZEN_ONBOARDING_SCREEN_ON, false);
+
+        mActivity.findViewById(R.id.screen_on_option).performClick();
+
+        verify(mMetricsLogger).action(MetricsEvent.ACTION_ZEN_ONBOARDING_SCREEN_ON, true);
+    }
+
+    @Test
+    public void toggleCheckBoxRecordsEvents_screenOff() {
+        mActivity.findViewById(R.id.screen_off_option).performClick();
+
+        verify(mMetricsLogger).action(MetricsEvent.ACTION_ZEN_ONBOARDING_SCREEN_OFF, false);
+
+        mActivity.findViewById(R.id.screen_off_option).performClick();
+
+        verify(mMetricsLogger).action(MetricsEvent.ACTION_ZEN_ONBOARDING_SCREEN_OFF, true);
+    }
+
+    @Test
+    public void save_screenOn() {
+        Policy policy = new Policy(
+                PRIORITY_CATEGORY_ALARMS, 0, 0,
+                SUPPRESSED_EFFECT_SCREEN_ON
+                        | SUPPRESSED_EFFECT_SCREEN_OFF
+                        | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
+                        | SUPPRESSED_EFFECT_LIGHTS
+                        | SUPPRESSED_EFFECT_PEEK
+                        | SUPPRESSED_EFFECT_STATUS_BAR
+                        | SUPPRESSED_EFFECT_BADGE
+                        | SUPPRESSED_EFFECT_AMBIENT
+                        | SUPPRESSED_EFFECT_NOTIFICATION_LIST);
+        when(mNm.getNotificationPolicy()).thenReturn(policy);
+
+        mActivity.findViewById(R.id.screen_off_option).performClick();
+
+        mActivity.save(null);
+
+        verify(mMetricsLogger).action(MetricsEvent.ACTION_ZEN_ONBOARDING_OK);
+
+        ArgumentCaptor<Policy> captor = ArgumentCaptor.forClass(Policy.class);
+        verify(mNm).setNotificationPolicy(captor.capture());
+
+        Policy actual = captor.getValue();
+        assertThat(actual.priorityCategories).isEqualTo(PRIORITY_CATEGORY_ALARMS);
+        assertThat(actual.suppressedVisualEffects).isEqualTo(
+                SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_NOTIFICATION_LIST
+                        | SUPPRESSED_EFFECT_BADGE | SUPPRESSED_EFFECT_STATUS_BAR
+                        | SUPPRESSED_EFFECT_PEEK);
+    }
+
+    @Test
+    public void save_screenOff() {
+        Policy policy = new Policy(
+                PRIORITY_CATEGORY_ALARMS, PRIORITY_SENDERS_ANY, 0,
+                SUPPRESSED_EFFECT_SCREEN_ON
+                        | SUPPRESSED_EFFECT_SCREEN_OFF
+                        | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
+                        | SUPPRESSED_EFFECT_LIGHTS
+                        | SUPPRESSED_EFFECT_PEEK
+                        | SUPPRESSED_EFFECT_STATUS_BAR
+                        | SUPPRESSED_EFFECT_BADGE
+                        | SUPPRESSED_EFFECT_AMBIENT
+                        | SUPPRESSED_EFFECT_NOTIFICATION_LIST);
+        when(mNm.getNotificationPolicy()).thenReturn(policy);
+
+        mActivity.findViewById(R.id.screen_on_option).performClick();
+
+        mActivity.save(null);
+
+        verify(mMetricsLogger).action(MetricsEvent.ACTION_ZEN_ONBOARDING_OK);
+
+        ArgumentCaptor<Policy> captor = ArgumentCaptor.forClass(Policy.class);
+        verify(mNm).setNotificationPolicy(captor.capture());
+
+        Policy actual = captor.getValue();
+        assertThat(actual.priorityCallSenders).isEqualTo(PRIORITY_SENDERS_ANY);
+        assertThat(actual.suppressedVisualEffects).isEqualTo(
+                SUPPRESSED_EFFECT_SCREEN_OFF | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
+                        | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_AMBIENT);
+    }
+
+    @Test
+    public void save_none() {
+        Policy policy = new Policy(0, 0, 0,
+                SUPPRESSED_EFFECT_SCREEN_ON
+                        | SUPPRESSED_EFFECT_SCREEN_OFF
+                        | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
+                        | SUPPRESSED_EFFECT_LIGHTS
+                        | SUPPRESSED_EFFECT_PEEK
+                        | SUPPRESSED_EFFECT_STATUS_BAR
+                        | SUPPRESSED_EFFECT_BADGE
+                        | SUPPRESSED_EFFECT_AMBIENT
+                        | SUPPRESSED_EFFECT_NOTIFICATION_LIST);
+        when(mNm.getNotificationPolicy()).thenReturn(policy);
+
+        mActivity.findViewById(R.id.screen_on_option).performClick();
+        mActivity.findViewById(R.id.screen_off_option).performClick();
+
+        mActivity.save(null);
+
+        verify(mMetricsLogger).action(MetricsEvent.ACTION_ZEN_ONBOARDING_OK);
+
+        ArgumentCaptor<Policy> captor = ArgumentCaptor.forClass(Policy.class);
+        verify(mNm).setNotificationPolicy(captor.capture());
+
+        Policy actual = captor.getValue();
+        assertThat(actual.suppressedVisualEffects).isEqualTo(0);
+    }
+
+    @Test
+    public void save_all() {
+        Policy policy = new Policy(0, 0, 0, 0);
+        when(mNm.getNotificationPolicy()).thenReturn(policy);
+
+        mActivity.save(null);
+
+        verify(mMetricsLogger).action(MetricsEvent.ACTION_ZEN_ONBOARDING_OK);
+
+        ArgumentCaptor<Policy> captor = ArgumentCaptor.forClass(Policy.class);
+        verify(mNm).setNotificationPolicy(captor.capture());
+
+        Policy actual = captor.getValue();
+        assertThat(actual.suppressedVisualEffects).isEqualTo(
+                SUPPRESSED_EFFECT_SCREEN_ON
+                        | SUPPRESSED_EFFECT_SCREEN_OFF
+                        | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
+                        | SUPPRESSED_EFFECT_LIGHTS
+                        | SUPPRESSED_EFFECT_PEEK
+                        | SUPPRESSED_EFFECT_STATUS_BAR
+                        | SUPPRESSED_EFFECT_BADGE
+                        | SUPPRESSED_EFFECT_AMBIENT
+                        | SUPPRESSED_EFFECT_NOTIFICATION_LIST);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
index fdd77e8..0cdb2f4 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 
+import android.app.slice.Slice;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -44,8 +45,6 @@
 import org.mockito.ArgumentCaptor;
 import org.robolectric.RuntimeEnvironment;
 
-import androidx.slice.core.SliceHints;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 public class SliceBroadcastReceiverTest {
 
@@ -129,7 +128,7 @@
         fakeSliderController.setSliderPosition(oldPosition);
         // Build action
         Intent intent = new Intent(SettingsSliceProvider.ACTION_SLIDER_CHANGED);
-        intent.putExtra(SliceHints.EXTRA_RANGE_VALUE, position);
+        intent.putExtra(Slice.EXTRA_RANGE_VALUE, position);
         intent.putExtra(SettingsSliceProvider.EXTRA_SLICE_KEY, key);
 
         assertThat(fakeSliderController.getSliderPosition()).isEqualTo(oldPosition);
@@ -163,7 +162,7 @@
 
         // Build action
         Intent intent = new Intent(SettingsSliceProvider.ACTION_SLIDER_CHANGED);
-        intent.putExtra(SliceHints.EXTRA_RANGE_VALUE, position);
+        intent.putExtra(Slice.EXTRA_RANGE_VALUE, position);
         intent.putExtra(SettingsSliceProvider.EXTRA_SLICE_KEY, key);
 
         // Trigger the exception.
@@ -174,7 +173,7 @@
     public void sliderOnReceive_noKey_throwsException() {
         // Build action
         final Intent intent = new Intent(SettingsSliceProvider.ACTION_SLIDER_CHANGED)
-                .putExtra(SliceHints.EXTRA_RANGE_VALUE, 0);
+                .putExtra(Slice.EXTRA_RANGE_VALUE, 0);
 
         // Trigger the exception.
         mReceiver.onReceive(mContext, intent);
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
index df6be44..1f3f40f 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
@@ -188,26 +188,25 @@
     }
 
     @Test
-    public void testDynamicSummary_returnsSliceScreenTitle() {
+    public void testDynamicSummary_returnsSliceEmptyString() {
         final SliceData data = getDummyData((String) null);
         final FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
-
         final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
 
-        assertThat(summary).isEqualTo(data.getScreenTitle());
+        assertThat(summary).isEqualTo("");
     }
 
     @Test
-    public void testDynamicSummary_placeHolderString_returnsScreenTitle() {
+    public void testDynamicSummary_placeHolderString_returnsEmptyString() {
         final SliceData data = getDummyData(mContext.getString(R.string.summary_placeholder));
         final FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
         final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
 
-        assertThat(summary).isEqualTo(data.getScreenTitle());
+        assertThat(summary).isEqualTo("");
     }
 
     @Test
-    public void testDynamicSummary_sliceDataAndFragmentPlaceholder_returnsSliceScreenTitle() {
+    public void testDynamicSummary_sliceDataAndFragmentPlaceholder_returnsSliceEmptyString() {
         final String summaryPlaceholder = mContext.getString(R.string.summary_placeholder);
         final SliceData data = getDummyData(summaryPlaceholder);
         final FakePreferenceController controller = spy(
@@ -216,7 +215,19 @@
 
         CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
 
-        assertThat(summary).isEqualTo(data.getScreenTitle());
+        assertThat(summary).isEqualTo("");
+    }
+
+    @Test
+    public void summaryText_bothDynamicAndStaticSummary_dynamicSummaryReturned() {
+        SliceData data = getDummyData("bad_summary");
+        FakePreferenceController controller = spy(new FakePreferenceController(mContext, KEY));
+        String controllerSummary = "new_Summary";
+        doReturn(controllerSummary).when(controller).getSummary();
+
+        CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
+
+        assertThat(summary).isEqualTo(controllerSummary);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/widget/AspectRatioFrameLayoutTest.java b/tests/robotests/src/com/android/settings/widget/AspectRatioFrameLayoutTest.java
index bb55692..59a90c5 100644
--- a/tests/robotests/src/com/android/settings/widget/AspectRatioFrameLayoutTest.java
+++ b/tests/robotests/src/com/android/settings/widget/AspectRatioFrameLayoutTest.java
@@ -41,7 +41,7 @@
     }
 
     @Test
-    public void measure_squareAspectRatio_stretchHeight() {
+    public void measure_squareAspectRatio_squeezeWidth() {
         mLayout = new AspectRatioFrameLayout(mContext);
 
         int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
@@ -49,8 +49,8 @@
 
         mLayout.measure(widthMeasureSpec, heightMeasureSpec);
 
-        assertThat(mLayout.getMeasuredWidth()).isEqualTo(100);
-        assertThat(mLayout.getMeasuredHeight()).isEqualTo(100);
+        assertThat(mLayout.getMeasuredWidth()).isEqualTo(50);
+        assertThat(mLayout.getMeasuredHeight()).isEqualTo(50);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/widget/DonutViewTest.java b/tests/robotests/src/com/android/settings/widget/DonutViewTest.java
new file mode 100644
index 0000000..3b8bdce
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/widget/DonutViewTest.java
@@ -0,0 +1,19 @@
+package com.android.settings.widget;
+
+import android.content.Context;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class DonutViewTest {
+    @Test
+    public void getPercentageStringSpannable_doesntCrashForMissingPercentage() {
+        Context context = RuntimeEnvironment.application;
+
+        DonutView.getPercentageStringSpannable(context.getResources(), "50%", "h");
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceTest.java
index e8a705c..878bae4 100644
--- a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.widget;
 
+import static com.google.common.truth.Truth.assertThat;
 import static junit.framework.Assert.assertEquals;
 
 import static org.mockito.Mockito.mock;
@@ -46,6 +47,16 @@
     }
 
     @Test
+    public void shouldHaveRadioPreferenceLayout() {
+        assertThat(mPreference.getLayoutResource()).isEqualTo(R.layout.preference_radio);
+    }
+
+    @Test
+    public void iconSpaceReservedShouldBeFalse() {
+        assertThat(mPreference.isIconSpaceReserved()).isFalse();
+    }
+
+    @Test
     public void summary_containerShouldBeVisible() {
         mPreference.setSummary("some summary");
         View summaryContainer = new View(mContext);
diff --git a/tests/robotests/src/com/android/settings/widget/VideoPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/VideoPreferenceTest.java
new file mode 100644
index 0000000..fee7bcc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/widget/VideoPreferenceTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.widget;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.view.LayoutInflater;
+
+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.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class VideoPreferenceTest {
+    private static final int VIDEO_WIDTH = 100;
+    private static final int VIDEO_HEIGHT = 150;
+    @Mock
+    private MediaPlayer mMediaPlayer;
+    private Context mContext;
+    private VideoPreference mVideoPreference;
+    private PreferenceViewHolder mPreferenceViewHolder;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = RuntimeEnvironment.application;
+        mVideoPreference = new VideoPreference(mContext, null /* attrs */);
+        mVideoPreference.mMediaPlayer = mMediaPlayer;
+        when(mMediaPlayer.getVideoWidth()).thenReturn(VIDEO_WIDTH);
+        when(mMediaPlayer.getVideoHeight()).thenReturn(VIDEO_HEIGHT);
+
+        mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(
+                LayoutInflater.from(mContext).inflate(R.layout.video_preference, null));
+    }
+
+    @Test
+    public void onBindViewHolder_hasCorrectRatio() {
+        mVideoPreference.mAnimationAvailable = true;
+
+        mVideoPreference.updateAspectRatio();
+        mVideoPreference.onBindViewHolder(mPreferenceViewHolder);
+
+        final AspectRatioFrameLayout layout =
+                (AspectRatioFrameLayout) mPreferenceViewHolder.findViewById(R.id.video_container);
+        assertThat(layout.mAspectRatio).isWithin(0.01f).of(VIDEO_WIDTH / (float) VIDEO_HEIGHT);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
index 69cfb10..3f8ee5a 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
@@ -26,8 +26,11 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.NetworkRequest;
 import android.net.NetworkScoreManager;
 import android.net.wifi.WifiManager;
+import android.os.Handler;
 import android.support.v7.preference.Preference.OnPreferenceChangeListener;
 import android.support.v7.preference.PreferenceScreen;
 
@@ -54,6 +57,8 @@
     @Mock
     private MasterSwitchPreference mPreference;
     @Mock
+    private ConnectivityManager mConnectivityManager;
+    @Mock
     private NetworkScoreManager mNetworkScoreManager;
 
     private Context mContext;
@@ -65,6 +70,7 @@
         MockitoAnnotations.initMocks(this);
         mMetricsFeatureProvider = FakeFeatureFactory.setupForTest().getMetricsFeatureProvider();
         mContext = spy(RuntimeEnvironment.application.getApplicationContext());
+        when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
         when(mContext.getSystemService(NetworkScoreManager.class)).thenReturn(mNetworkScoreManager);
         mController = new WifiMasterSwitchPreferenceController(mContext, mMetricsFeatureProvider);
         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
@@ -89,6 +95,10 @@
         mController.onResume();
 
         verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
+        verify(mConnectivityManager).registerNetworkCallback(
+                any(NetworkRequest.class),
+                any(ConnectivityManager.NetworkCallback.class),
+                any(Handler.class));
     }
 
     @Test
@@ -97,6 +107,8 @@
         mController.onPause();
 
         verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
+        verify(mConnectivityManager).unregisterNetworkCallback(
+                any(ConnectivityManager.NetworkCallback.class));
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java b/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java
index 197fd40..198517a 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java
@@ -39,9 +39,10 @@
     public void testPassword() {
         final String longPassword = "123456789012345678901234567890"
                 + "1234567890123456789012345678901234567890";
-        assertThat(WifiUtils.isPasswordValid("123")).isFalse();
-        assertThat(WifiUtils.isPasswordValid("12345678")).isTrue();
-        assertThat(WifiUtils.isPasswordValid("1234567890")).isTrue();
-        assertThat(WifiUtils.isPasswordValid(longPassword)).isFalse();
+        assertThat(WifiUtils.isHotspotPasswordValid("123")).isFalse();
+        assertThat(WifiUtils.isHotspotPasswordValid("12345678")).isTrue();
+        assertThat(WifiUtils.isHotspotPasswordValid("1234567890")).isTrue();
+        assertThat(WifiUtils.isHotspotPasswordValid(longPassword)).isFalse();
+        assertThat(WifiUtils.isHotspotPasswordValid("")).isTrue();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
index 58f31b1..60faa2e 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
@@ -113,4 +113,36 @@
         assertThat(mController.getPassword()).isEqualTo(config.preSharedKey);
         assertThat(mPreference.getSummary()).isEqualTo(config.preSharedKey);
     }
+
+    @Test
+    public void getSecuritySettingForPassword_returnCorrectType() {
+        // valid wpa2 password
+        mController.displayPreference(mScreen);
+        assertThat(mController.getSecuritySettingForPassword())
+                .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
+
+        // password which is empty returns NONE
+        mConfig = new WifiConfiguration();
+        mConfig.SSID = "test_1234";
+        mConfig.preSharedKey = "";
+        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
+        when(mWifiManager.getWifiApConfiguration()).thenReturn(mConfig);
+        mController = new WifiTetherPasswordPreferenceController(mContext, mListener);
+
+        mController.displayPreference(mScreen);
+        assertThat(mController.getSecuritySettingForPassword())
+                .isEqualTo(WifiConfiguration.KeyMgmt.NONE);
+
+        // default for unsupported types is wpa2
+        mConfig = new WifiConfiguration();
+        mConfig.SSID = "test_1234";
+        mConfig.preSharedKey = "short";
+        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
+        when(mWifiManager.getWifiApConfiguration()).thenReturn(mConfig);
+        mController = new WifiTetherPasswordPreferenceController(mContext, mListener);
+
+        mController.displayPreference(mScreen);
+        assertThat(mController.getSecuritySettingForPassword())
+                .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java
deleted file mode 100644
index 8c84575..0000000
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java
+++ /dev/null
@@ -1,38 +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.wifi.tether;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.net.wifi.WifiConfiguration;
-
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-public class WifiTetherSettingsTest {
-
-    @Test
-    public void ensureWifiConfigHasPassword_shouldGeneratePassword() {
-        WifiConfiguration config = new WifiConfiguration();
-        WifiTetherSettings.ensureWifiConfigHasPassword(config);
-
-        assertThat(config.preSharedKey).isNotEmpty();
-    }
-}
diff --git a/tests/uitests/Android.mk b/tests/uitests/Android.mk
index 6f03b3f..89f9133 100644
--- a/tests/uitests/Android.mk
+++ b/tests/uitests/Android.mk
@@ -17,6 +17,7 @@
 
 LOCAL_PACKAGE_NAME := SettingsUITests
 LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_CERTIFICATE := platform
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_MODULE_TAGS := tests
diff --git a/tests/uitests/AndroidManifest.xml b/tests/uitests/AndroidManifest.xml
index 06d74c6..91e15b8 100644
--- a/tests/uitests/AndroidManifest.xml
+++ b/tests/uitests/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.settings.ui">
+    package="com.android.settings.ui"
+    android:sharedUserId="android.uid.systemui">
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -26,6 +27,7 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
 
     <instrumentation
             android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/uitests/AndroidTest.xml b/tests/uitests/AndroidTest.xml
index 4f9e377..4162207 100644
--- a/tests/uitests/AndroidTest.xml
+++ b/tests/uitests/AndroidTest.xml
@@ -25,5 +25,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.settings.ui" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/tests/uitests/src/com/android/settings/ui/StorageWizardTest.java b/tests/uitests/src/com/android/settings/ui/StorageWizardTest.java
new file mode 100644
index 0000000..4b923f5
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/StorageWizardTest.java
@@ -0,0 +1,191 @@
+/*
+ * 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.ui;
+
+import android.content.Intent;
+import android.os.SystemClock;
+import android.os.storage.DiskInfo;
+import android.os.storage.VolumeInfo;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.Until;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+/**
+ * Verify storage wizard flows. Temporarily enables a virtual disk which enables
+ * testing on all devices, regardless of physical SD card support.
+ */
+@RunWith(AndroidJUnit4.class)
+public class StorageWizardTest {
+    private static final String ANDROID_PACKAGE = "android";
+    private static final String PACKAGE = "com.android.settings";
+    private static final int TIMEOUT = 5000;
+    private static final int TIMEOUT_LONG = 30000;
+
+    private UiDevice mDevice;
+
+    private String mDisk;
+    private String mVolume;
+
+    @Before
+    public void setUp() throws Exception {
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        mDevice.executeShellCommand("setprop sys.debug.storage_slow 1");
+        mDevice.executeShellCommand("sm set-virtual-disk true");
+
+        mDisk = getAdoptableDisk();
+        mDevice.executeShellCommand("sm partition " + mDisk + " public");
+        mVolume = getPublicVolume();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // Go back to home for next test.
+        mDevice.pressBack();
+        mDevice.pressBack();
+        mDevice.pressHome();
+        mDevice.waitForIdle(TIMEOUT);
+
+        mDevice.executeShellCommand("setprop sys.debug.storage_slow 0");
+        mDevice.executeShellCommand("sm set-virtual-disk false");
+        mDevice.executeShellCommand("sm forget all");
+    }
+
+    /**
+     * Test flow for adopting a storage device as internal/adopted.
+     */
+    @Test
+    public void testInternal() throws Exception {
+        InstrumentationRegistry.getContext().startActivity(buildInitIntent());
+
+        // Activity: pick option to use as internal
+        waitFor(By.res(PACKAGE, "suw_layout_title").text(containsIgnoringCase("How will you use")));
+        waitFor(By.res(PACKAGE, "storage_wizard_init_internal")).click();
+
+        // Dialog: acknowledge that we're formatting the card
+        waitFor(By.res(ANDROID_PACKAGE, "alertTitle").textContains("Format"));
+        waitFor(By.clickable(true).text(containsIgnoringCase("Format"))).click();
+
+        // Activity: ack storage device is slow
+        waitForLong(By.res(PACKAGE, "suw_layout_title").textContains("Slow"));
+        waitFor(By.res(PACKAGE, "storage_next_button")).click();
+
+        // Activity: choose to move content
+        waitForLong(By.res(PACKAGE, "suw_layout_title").textContains("Move content"));
+        waitFor(By.res(PACKAGE, "storage_next_button")).click();
+
+        // Activity: yay, we're done!
+        waitForLong(By.res(PACKAGE, "suw_layout_title").textContains("ready to use"));
+        waitFor(By.res(PACKAGE, "storage_next_button")).click();
+    }
+
+    /**
+     * Test flow for adopting a storage device as external/portable.
+     */
+    @Test
+    public void testExternal() throws Exception {
+        InstrumentationRegistry.getContext().startActivity(buildInitIntent());
+
+        // Activity: pick option to use as external
+        waitFor(By.res(PACKAGE, "suw_layout_title").textContains("How will you use"));
+        waitFor(By.res(PACKAGE, "storage_wizard_init_external")).click();
+
+        // Activity: yay, we're done!
+        waitFor(By.res(PACKAGE, "suw_layout_title").textContains("ready to use"));
+        waitFor(By.res(PACKAGE, "storage_next_button")).click();
+    }
+
+    private UiObject2 waitFor(BySelector selector) throws UiObjectNotFoundException {
+        return waitFor(selector, TIMEOUT);
+    }
+
+    private UiObject2 waitForLong(BySelector selector) throws UiObjectNotFoundException {
+        return waitFor(selector, TIMEOUT_LONG);
+    }
+
+    private UiObject2 waitFor(BySelector selector, long timeout) throws UiObjectNotFoundException {
+        final UiObject2 item = mDevice.wait(Until.findObject(selector), timeout);
+        if (item != null) {
+            return item;
+        } else {
+            throw new UiObjectNotFoundException(selector.toString());
+        }
+    }
+
+    /**
+     * Shamelessly borrowed from AdoptableHostTest in CTS.
+     */
+    private String getAdoptableDisk() throws IOException {
+        // In the case where we run multiple test we cleanup the state of the device. This
+        // results in the execution of sm forget all which causes the MountService to "reset"
+        // all its knowledge about available drives. This can cause the adoptable drive to
+        // become temporarily unavailable.
+        int attempt = 0;
+        String disks = mDevice.executeShellCommand("sm list-disks adoptable");
+        while ((disks == null || disks.isEmpty()) && attempt++ < 15) {
+            SystemClock.sleep(1000);
+            disks = mDevice.executeShellCommand("sm list-disks adoptable");
+        }
+
+        if (disks == null || disks.isEmpty()) {
+            throw new AssertionError("Devices that claim to support adoptable storage must have "
+                    + "adoptable media inserted during CTS to verify correct behavior");
+        }
+        return disks.split("\n")[0].trim();
+    }
+
+    private String getPublicVolume() throws IOException {
+        int attempt = 0;
+        String volumes = mDevice.executeShellCommand("sm list-volumes public");
+        while ((volumes == null || volumes.isEmpty() || !volumes.contains("mounted"))
+                && attempt++ < 15) {
+            SystemClock.sleep(1000);
+            volumes = mDevice.executeShellCommand("sm list-volumes public");
+        }
+
+        if (volumes == null || volumes.isEmpty()) {
+            throw new AssertionError("Devices that claim to support adoptable storage must have "
+                    + "adoptable media inserted during CTS to verify correct behavior");
+        }
+        return volumes.split("[\n ]")[0].trim();
+    }
+
+    private Intent buildInitIntent() {
+        final Intent intent = new Intent().setClassName(PACKAGE,
+                PACKAGE + ".deviceinfo.StorageWizardInit");
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk);
+        intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, mVolume);
+        return intent;
+    }
+
+    private Pattern containsIgnoringCase(String text) {
+        return Pattern.compile("(?i)^.*" + text + ".*$");
+    }
+}
diff --git a/tests/unit/AndroidTest.xml b/tests/unit/AndroidTest.xml
index 34be41f..0c4b1dd 100644
--- a/tests/unit/AndroidTest.xml
+++ b/tests/unit/AndroidTest.xml
@@ -25,5 +25,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.settings.tests.unit" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>