Merge "Add battery percentage switch to display settings"
diff --git a/res/layout/app_details.xml b/res/layout/app_details.xml
index 00d4cca..15cb38a 100644
--- a/res/layout/app_details.xml
+++ b/res/layout/app_details.xml
@@ -18,7 +18,7 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/app_snippet"
-    style="@style/EntityHeader"
+    style="@style/AppInfoHeader"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_gravity="center_horizontal|top"
@@ -79,7 +79,7 @@
 
             <TextView
                 android:id="@+id/app_detail_title"
-                style="@style/TextAppearance.EntityHeaderTitle"
+                style="@style/TextAppearance.AppInfoTitle"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:singleLine="false"
@@ -89,24 +89,22 @@
 
             <TextView
                 android:id="@+id/install_type"
+                style="@style/TextAppearance.AppInfoSummary"
                 android:visibility="gone"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:gravity="start"
                 android:singleLine="true"
-                android:ellipsize="marquee"
-                android:textAppearance="@android:style/TextAppearance.Material.Body1"
-                android:textColor="?android:attr/textColorSecondary"/>
+                android:ellipsize="marquee"/>
 
             <TextView
                 android:id="@+id/app_detail_summary"
+                style="@style/TextAppearance.AppInfoSummary"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:gravity="start"
                 android:singleLine="true"
-                android:ellipsize="marquee"
-                android:textAppearance="@android:style/TextAppearance.Material.Body1"
-                android:textColor="?android:attr/textColorSecondary"/>
+                android:ellipsize="marquee"/>
 
         </LinearLayout>
 
diff --git a/res/layout/storage_summary_donut.xml b/res/layout/storage_summary_donut.xml
index eadb6e5..9fd4860 100644
--- a/res/layout/storage_summary_donut.xml
+++ b/res/layout/storage_summary_donut.xml
@@ -56,15 +56,6 @@
             android:textAlignment="viewStart"
             android:textAppearance="@android:style/TextAppearance.Material.Body1" />
 
-        <TextView
-            android:id="@+id/storage_manager_indicator"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="4dp"
-            android:layout_marginEnd="4dp"
-            android:textAlignment="viewStart"
-            android:textAppearance="@android:style/TextAppearance.Material.Body1"/>
-
         <Button
             android:id="@+id/deletion_helper_button"
             android:layout_width="wrap_content"
diff --git a/res/values/config.xml b/res/values/config.xml
index f81bf9b..0fa2b71 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -67,36 +67,4 @@
     <!-- If the support features are enabled. -->
     <bool name="config_support_enabled">false</bool>
 
-    <!-- List containing the component names of pre-installed screen reader services. -->
-    <string-array name="config_preinstalled_screen_reader_services" translatable="false">
-        <!--
-        <item>com.example.package.first/com.example.class.FirstService</item>
-        <item>com.example.package.second/com.example.class.SecondService</item>
-        -->
-    </string-array>
-
-    <!-- List containing the component names of pre-installed audio and captioning services. -->
-    <string-array name="config_preinstalled_audio_and_caption_services" translatable="false">
-        <!--
-        <item>com.example.package.first/com.example.class.FirstService</item>
-        <item>com.example.package.second/com.example.class.SecondService</item>
-        -->
-    </string-array>
-
-    <!-- List containing the component names of pre-installed display services. -->
-    <string-array name="config_preinstalled_display_services" translatable="false">
-        <!--
-        <item>com.example.package.first/com.example.class.FirstService</item>
-        <item>com.example.package.second/com.example.class.SecondService</item>
-        -->
-    </string-array>
-
-    <!-- List containing the component names of pre-installed interaction control services. -->
-    <string-array name="config_preinstalled_interaction_control_services" translatable="false">
-        <!--
-        <item>com.example.package.first/com.example.class.FirstService</item>
-        <item>com.example.package.second/com.example.class.SecondService</item>
-        -->
-    </string-array>
-
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index dccd0c7..d2e3915 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3984,22 +3984,18 @@
     <string name="vision_settings_title">Vision Settings</string>
     <!-- Settings description for a brief version of Vision-Related Accessibility Settings. Tells the user that they can adjust these settings now to help them through the remainder of the Setup Wizard and that they can later be changed in Settings. Displayed in Setup Wizard only. [CHAR LIMIT=none] -->
     <string name="vision_settings_description">You can customize this device to fit your needs. These accessibility features can be changed later in Settings.</string>
-    <!-- Title for the accessibility preference category of screen reader services and settings. [CHAR LIMIT=50] -->
-    <string name="screen_reader_category_title">Screen readers</string>
-    <!-- Title for the accessibility preference category of audio services and settings. [CHAR LIMIT=50] -->
-    <string name="audio_and_captions_category_title">Audio &amp; on-screen text</string>
-    <!-- Title for the accessibility preference category of display services and settings. [CHAR LIMIT=50] -->
-    <string name="display_category_title">Display</string>
-    <!-- Title for the accessibility preference category of interaction control services and settings. [CHAR LIMIT=50] -->
-    <string name="interaction_control_category_title">Interaction controls</string>
-    <!-- Title for the accessibility preference category of services downloaded by the user. [CHAR LIMIT=50] -->
-    <string name="user_installed_services_category_title">Downloaded services</string>
+    <!-- Title for the accessibility preference category of accessibility services. [CHAR LIMIT=25] -->
+    <string name="accessibility_services_title">Services</string>
     <!-- Title for the Talkback Accessibility Service. Displayed on the Accessibility Settings screen in Setup Wizard. [CHAR_LIMIT=25] -->
     <string name="talkback_title">Talkback</string>
     <!-- Summary for the Talkback Accessibility Service. Lets the user know that Talkback is a screenreader and that it is usually most helpful to blind and low vision users and whether the service is on. [CHAR_LIMIT=none] -->
     <string name="talkback_summary">Screen reader primarily for people with blindness and low vision</string>
     <!-- Summary for the Select to Speak Accessibility Service. [CHAR_LIMIT=none] -->
     <string name="select_to_speak_summary">Tap items on your screen to hear them read aloud</string>
+    <!-- Title for the accessibility preference category of system related preferences. [CHAR LIMIT=25] -->
+    <string name="accessibility_system_title">System</string>
+    <!-- Title for the accessibility preference category of display related preferences. [CHAR LIMIT=25] -->
+    <string name="accessibility_display_title">Display</string>
     <!-- Title for the accessibility preference screen to enable video captioning. [CHAR LIMIT=35] -->
     <string name="accessibility_captioning_title">Captions</string>
     <!-- Title for the accessibility preference screen to enable screen magnification. [CHAR LIMIT=35] -->
@@ -4190,10 +4186,10 @@
     <string name="disable_service_message">Tapping OK will
         stop <xliff:g id="service" example="TalkBack">%1$s</xliff:g>.</string>
 
-    <!-- Title for the prompt shown as a placeholder if no accessibility services are installed. [CHAR LIMIT=50] -->
+    <!-- Title for the prompt shown as a placeholder if no accessibility serivices are installed. [CHAR LIMIT=50] -->
     <string name="accessibility_no_services_installed">No services installed</string>
 
-    <!-- Default description for an accessibility service if the latter doesn't provide one. [CHAR LIMIT=NONE] -->
+    <!-- Default description for an accessibility serivice if the latter doesn't provide one. [CHAR LIMIT=NONE] -->
     <string name="accessibility_service_default_description">No description provided.</string>
 
     <!-- Accessibility settings: button for lauching settings for an accessibility service -->
@@ -4214,7 +4210,7 @@
     <!-- Title for print service settings screen [CHAR LIMIT=25] -->
     <string name="print_settings_title">Print services</string>
 
-    <!-- Title for the prompt shown as a placeholder if no print services are installed. [CHAR LIMIT=50] -->
+    <!-- Title for the prompt shown as a placeholder if no print serivices are installed. [CHAR LIMIT=50] -->
     <string name="print_no_services_installed">No services installed</string>
 
     <!-- Title for the prompt shown as a placeholder if no printers are found while searching. [CHAR LIMIT=50] -->
@@ -8076,6 +8072,9 @@
     <!-- Summary text for the assist gesture [CHAR LIMIT=160]-->
     <string name="assist_gesture_summary"></string>
 
+    <!-- Title text for the assist gesture sensitivity setting [CHAR LIMIT=NONE]-->
+    <string name="assist_gesture_sensitivity_title">Sensitivity</string>
+
     <!-- Switch text for each gesture setting state -->
     <string name="gesture_setting_on">On</string>
     <string name="gesture_setting_off">Off</string>
@@ -8247,7 +8246,7 @@
     <string name="storage_files">Files</string>
 
     <!-- Main settings screen item's title to go into the storage settings screen [CHAR LIMIT=25] -->
-    <string name="storage_settings_2" >Phone Storage</string>
+    <string name="storage_settings_2">Phone storage</string>
 
     <!-- Summary of a single storage volume used space. [CHAR LIMIT=24] -->
     <string name="storage_size_large_alternate"><xliff:g id="number" example="128">^1</xliff:g><small> <xliff:g id="unit" example="KB">^2</xliff:g></small></string>
@@ -8256,18 +8255,6 @@
     <!-- The percent of storage used by a storage volume. Exposed inside of a donut graph. [CHAR LIMIT=4]-->
     <string name="storage_percent_used"><xliff:g id="percent" example="50%">%1$s</xliff:g>%%</string>
 
-    <!-- Indicates if the automatic storage manager is enabled or not. [CHAR_LIMIT=40] -->
-    <string name="storage_manager_indicator">Storage Manager: <xliff:g id="status" example="on">^1</xliff:g></string>
-
-    <!-- Off status for the automatic storage manager. [CHAR_LIMIT=10] -->
-    <string name="storage_manager_indicator_off">Off</string>
-
-    <!-- On status for the automatic storage manager. [CHAR_LIMIT=10] -->
-    <string name="storage_manager_indicator_on">On</string>
-
-    <!-- Added as the value of a header field indicating this is an instant app (as opposed to installed normally) -->
-    <string name="install_type_instant">Instant app</string>
-
     <!-- Title of games app storage screen [CHAR LIMIT=30] -->
     <string name="game_storage_settings">Games</string>
 
@@ -8296,4 +8283,16 @@
     <!-- Temporary reboot string, will be removed -->
     <string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string>
 
+    <!-- Indicates if the automatic storage manager is enabled or not. [CHAR_LIMIT=40] -->
+    <string name="storage_manager_indicator">Storage Manager: <xliff:g id="status" example="on">^1</xliff:g></string>
+
+    <!-- Off status for the automatic storage manager. [CHAR_LIMIT=10] -->
+    <string name="storage_manager_indicator_off">Off</string>
+
+    <!-- On status for the automatic storage manager. [CHAR_LIMIT=10] -->
+    <string name="storage_manager_indicator_on">On</string>
+
+    <!-- Added as the value of a header field indicating this is an instant app (as opposed to installed normally) -->
+    <string name="install_type_instant">Instant app</string>
+
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 2692508..d193c30 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -428,6 +428,19 @@
         <item name="android:textSize">24sp</item>
     </style>
 
+    <style name="AppInfoHeader" parent="EntityHeader">
+        <item name="android:background">?android:attr/colorAccent</item>
+    </style>
+
+    <style name="TextAppearance.AppInfoTitle" parent="TextAppearance.EntityHeaderTitle">
+        <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+    </style>
+
+    <style name="TextAppearance.AppInfoSummary"
+           parent="@android:style/TextAppearance.Material.Body1">
+        <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+    </style>
+
     <style name="AppActionPrimaryButton" parent="android:Widget.Material.Button.Colored"/>
 
     <style name="LockPatternStyle">
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 478dfe5..ee21017 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -18,42 +18,38 @@
         android:title="@string/accessibility_settings"
         android:persistent="true">
 
-    <ListPreference
-            android:key="accessibility_shortcut_preference"
-            android:title="@string/accessibility_global_gesture_preference_title"/>
-
     <PreferenceCategory
-            android:key="user_installed_services_category"
-            android:title="@string/user_installed_services_category_title">
+            android:key="services_category"
+            android:title="@string/accessibility_services_title">
     </PreferenceCategory>
 
     <PreferenceCategory
-            android:key="screen_reader_category"
-            android:title="@string/screen_reader_category_title">
+            android:key="system_category"
+            android:title="@string/accessibility_system_title">
 
         <Preference
-                android:key="tts_settings_preference"
-                android:fragment="com.android.settings.tts.TextToSpeechSettings"
-                android:title="@string/tts_settings_title"/>
-    </PreferenceCategory>
-
-    <PreferenceCategory
-            android:key="display_category"
-            android:title="@string/display_category_title">
+            android:fragment="com.android.settings.accessibility.CaptionPropertiesFragment"
+            android:key="captioning_preference_screen"
+            android:title="@string/accessibility_captioning_title" />
 
         <Preference
-                android:fragment="com.android.settings.accessibility.ToggleFontSizePreferenceFragment"
-                android:key="font_size_preference_screen"
-                android:title="@string/title_font_size"/>
+            android:fragment="com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragment"
+            android:key="screen_magnification_preference_screen"
+            android:title="@string/accessibility_screen_magnification_title"/>
+
+        <Preference
+            android:fragment="com.android.settings.accessibility.ToggleFontSizePreferenceFragment"
+            android:key="font_size_preference_screen"
+            android:title="@string/title_font_size"/>
 
         <com.android.settings.display.ScreenZoomPreference
-                android:key="screen_zoom"
-                android:title="@string/screen_zoom_title"/>
+            android:key="screen_zoom"
+            android:title="@string/screen_zoom_title"/>
 
         <Preference
-                android:fragment="com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragment"
-                android:key="screen_magnification_preference_screen"
-                android:title="@string/accessibility_screen_magnification_title"/>
+            android:fragment="com.android.settings.accessibility.ToggleAutoclickPreferenceFragment"
+            android:key="autoclick_preference_screen"
+            android:title="@string/accessibility_autoclick_preference_title"/>
 
         <SwitchPreference
                 android:key="toggle_high_text_contrast_preference"
@@ -61,31 +57,6 @@
                 android:summary="@string/experimental_preference"/>
 
         <SwitchPreference
-                android:key="toggle_inversion_preference"
-                android:title="@string/accessibility_display_inversion_preference_title"
-                android:summary="@string/accessibility_display_inversion_preference_subtitle"
-                android:persistent="false" />
-
-        <Preference
-                android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
-                android:key="daltonizer_preference_screen"
-                android:title="@string/accessibility_display_daltonizer_preference_title" />
-
-        <SwitchPreference
-                android:key="toggle_large_pointer_icon"
-                android:title="@string/accessibility_toggle_large_pointer_icon_title" />
-    </PreferenceCategory>
-
-    <PreferenceCategory
-            android:key="interaction_control_category"
-            android:title="@string/interaction_control_category_title">
-
-        <Preference
-                android:fragment="com.android.settings.accessibility.ToggleAutoclickPreferenceFragment"
-                android:key="autoclick_preference_screen"
-                android:title="@string/accessibility_autoclick_preference_title"/>
-
-        <SwitchPreference
                 android:key="toggle_power_button_ends_call_preference"
                 android:title="@string/accessibility_power_button_ends_call_prerefence_title"
                 android:persistent="false"/>
@@ -95,17 +66,9 @@
                 android:title="@string/accelerometer_title"
                 android:persistent="false"/>
 
-        <ListPreference
-                android:key="select_long_press_timeout_preference"
-                android:title="@string/accessibility_long_press_timeout_preference_title"
-                android:entries="@array/long_press_timeout_selector_titles"
-                android:entryValues="@array/long_press_timeout_selector_values"
-                android:persistent="false"/>
-    </PreferenceCategory>
-
-    <PreferenceCategory
-            android:key="audio_and_captions_category"
-            android:title="@string/audio_and_captions_category_title">
+        <SwitchPreference
+                android:key="toggle_large_pointer_icon"
+                android:title="@string/accessibility_toggle_large_pointer_icon_title" />
 
         <SwitchPreference
                 android:key="toggle_master_mono"
@@ -113,9 +76,35 @@
                 android:summary="@string/accessibility_toggle_master_mono_summary"
                 android:persistent="false"/>
 
+        <ListPreference
+                android:key="accessibility_shortcut_preference"
+                android:title="@string/accessibility_global_gesture_preference_title"/>
+
         <Preference
-                android:fragment="com.android.settings.accessibility.CaptionPropertiesFragment"
-                android:key="captioning_preference_screen"
-                android:title="@string/accessibility_captioning_title" />
+                android:key="tts_settings_preference"
+                android:fragment="com.android.settings.tts.TextToSpeechSettings"
+                android:title="@string/tts_settings_title"/>
+
+        <ListPreference android:key="select_long_press_timeout_preference"
+                android:title="@string/accessibility_long_press_timeout_preference_title"
+                android:entries="@array/long_press_timeout_selector_titles"
+                android:entryValues="@array/long_press_timeout_selector_values"
+                android:persistent="false"/>
+
     </PreferenceCategory>
+
+    <PreferenceCategory
+        android:key="display_category"
+        android:title="@string/accessibility_display_title" >
+        <SwitchPreference
+            android:key="toggle_inversion_preference"
+            android:title="@string/accessibility_display_inversion_preference_title"
+            android:summary="@string/accessibility_display_inversion_preference_subtitle"
+            android:persistent="false" />
+        <Preference
+            android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
+            android:key="daltonizer_preference_screen"
+            android:title="@string/accessibility_display_daltonizer_preference_title" />
+    </PreferenceCategory>
+
 </PreferenceScreen>
diff --git a/res/xml/assist_gesture_settings.xml b/res/xml/assist_gesture_settings.xml
index c0a3810..52ee247 100644
--- a/res/xml/assist_gesture_settings.xml
+++ b/res/xml/assist_gesture_settings.xml
@@ -29,4 +29,10 @@
         android:title="@string/assist_gesture_title"
         android:summary="@string/assist_gesture_summary" />
 
+    <com.android.settings.SeekBarPreference
+        android:key="gesture_assist_sensitivity"
+        android:title="@string/assist_gesture_sensitivity_title"
+        android:defaultValue="2"
+        android:max="4" />
+
 </PreferenceScreen>
diff --git a/res/xml/ia_sound_settings.xml b/res/xml/ia_sound_settings.xml
index 27fcdda..a34d875 100644
--- a/res/xml/ia_sound_settings.xml
+++ b/res/xml/ia_sound_settings.xml
@@ -151,4 +151,41 @@
                   android:targetClass="com.android.cellbroadcastreceiver.CellBroadcastSettings" />
         </com.android.settingslib.RestrictedPreference>
 
+        <com.android.settings.WorkOnlyCategory
+            android:key="sound_work_settings_section"
+            android:title="@string/sound_work_settings">
+
+                <!-- Use the same sounds of the work profile -->
+                <SwitchPreference
+                    android:key="work_use_personal_sounds"
+                    android:title="@string/work_use_personal_sounds_title"
+                    android:summary="@string/work_use_personal_sounds_summary"
+                    android:disableDependentsState="true" />
+
+                <!-- Work phone ringtone -->
+                <com.android.settings.DefaultRingtonePreference
+                    android:key="work_ringtone"
+                    android:title="@string/work_ringtone_title"
+                    android:dialogTitle="@string/work_alarm_ringtone_title"
+                    android:ringtoneType="ringtone"
+                    android:dependency="work_use_personal_sounds" />
+
+                <!-- Default work notification ringtone -->
+                <com.android.settings.DefaultRingtonePreference
+                    android:key="work_notification_ringtone"
+                    android:title="@string/work_notification_ringtone_title"
+                    android:dialogTitle="@string/work_alarm_ringtone_title"
+                    android:ringtoneType="notification"
+                    android:dependency="work_use_personal_sounds" />
+
+                <!-- Default work alarm ringtone -->
+                <com.android.settings.DefaultRingtonePreference
+                    android:key="work_alarm_ringtone"
+                    android:title="@string/work_alarm_ringtone_title"
+                    android:dialogTitle="@string/work_alarm_ringtone_title"
+                    android:persistent="false"
+                    android:ringtoneType="alarm"
+                    android:dependency="work_use_personal_sounds" />
+
+        </com.android.settings.WorkOnlyCategory>
 </PreferenceScreen>
diff --git a/res/xml/sound_work_settings.xml b/res/xml/sound_work_settings.xml
deleted file mode 100644
index b63ec75..0000000
--- a/res/xml/sound_work_settings.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-                  xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
-        android:title="@string/sound_work_settings"
-        android:key="sound_work_settings">
-
-        <PreferenceCategory
-            android:key="sound_work_settings_section"
-            android:title="@string/sound_work_settings">
-
-            <!-- Use the same sounds of the work profile -->
-            <SwitchPreference
-                    android:key="work_use_personal_sounds"
-                    android:title="@string/work_use_personal_sounds_title"
-                    android:summary="@string/work_use_personal_sounds_summary"
-                    android:disableDependentsState="true" />
-
-            <!-- Work phone ringtone -->
-            <com.android.settings.DefaultRingtonePreference
-                    android:key="work_ringtone"
-                    android:title="@string/work_ringtone_title"
-                    android:dialogTitle="@string/work_alarm_ringtone_title"
-                    android:ringtoneType="ringtone"
-                    android:dependency="work_use_personal_sounds" />
-
-            <!-- Default work notification ringtone -->
-            <com.android.settings.DefaultRingtonePreference
-                    android:key="work_notification_ringtone"
-                    android:title="@string/work_notification_ringtone_title"
-                    android:dialogTitle="@string/work_alarm_ringtone_title"
-                    android:ringtoneType="notification"
-                    android:dependency="work_use_personal_sounds" />
-
-            <!-- Default work alarm ringtone -->
-            <com.android.settings.DefaultRingtonePreference
-                    android:key="work_alarm_ringtone"
-                    android:title="@string/work_alarm_ringtone_title"
-                    android:dialogTitle="@string/work_alarm_ringtone_title"
-                    android:persistent="false"
-                    android:ringtoneType="alarm"
-                    android:dependency="work_use_personal_sounds" />
-
-        </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml
index fedc77f..78ccbbf 100644
--- a/res/xml/storage_dashboard_fragment.xml
+++ b/res/xml/storage_dashboard_fragment.xml
@@ -21,45 +21,38 @@
     <com.android.settings.deviceinfo.storage.StorageSummaryDonutPreference
         android:key="pref_summary"
         android:order="0" />
+    <com.android.settings.widget.MasterSwitchPreference
+        android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings"
+        android:key="toggle_asm"
+        android:title="@string/automatic_storage_manager_preference_title"
+        android:icon="@drawable/ic_settings_storage"
+        android:order="1" />
     <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
         android:key="pref_photos_videos"
         android:title="@string/storage_photos_videos"
-        android:order="1" >
-    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+        android:order="2" />
     <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
         android:key="pref_music_audio"
         android:title="@string/storage_music_audio"
-        android:order="2" >
-    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+        android:order="3" />
     <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
         android:key="pref_games"
         android:title="@string/storage_games"
-        android:order="3" >
-    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+        android:order="4" />
     <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
         android:key="pref_other_apps"
         android:title="@string/storage_other_apps"
-        android:order="4" >
-    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+        android:order="5" />
     <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
         android:key="pref_files"
         android:title="@string/storage_files"
-        android:order="5" >
-    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+        android:order="6" />
     <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
         android:key="pref_system"
         android:title="@string/storage_detail_system"
-        android:order="100" >
-    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+        android:order="100" />
     <PreferenceCategory
         android:key="pref_secondary_users"
         android:title="@string/storage_other_users"
         android:order="200" />
-    <Preference
-        android:key="manage_storage"
-        android:title="@string/storage_menu_manage"
-        android:icon="@drawable/ic_settings_storage"
-        android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings"
-        android:order="300" >
-    </Preference>
 </PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 7d6cf77..7a4d5f8 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -67,6 +67,7 @@
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DynamicIndexableContentMonitor;
 import com.android.settings.search2.SearchFeatureProvider;
+import com.android.settings.wfd.WifiDisplaySettings;
 import com.android.settings.widget.SwitchBar;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.SettingsDrawerActivity;
@@ -947,6 +948,10 @@
                 FeatureFactory.getFactory(this).getEnterprisePrivacyFeatureProvider(this)
                         .hasDeviceOwner(), isAdmin);
 
+        setTileEnabled(new ComponentName(packageName,
+                        Settings.WifiDisplaySettingsActivity.class.getName()),
+                WifiDisplaySettings.isAvailable(this), isAdmin);
+
         if (UserHandle.MU_ENABLED && !isAdmin) {
 
             // When on restricted users, disable all extra categories (but only the settings ones).
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 672f4ed..807371e 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -25,7 +25,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -36,9 +35,7 @@
 import android.support.v7.preference.ListPreference;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceScreen;
 import android.text.TextUtils;
-import android.util.ArrayMap;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -49,17 +46,18 @@
 import com.android.internal.view.RotationPolicy.RotationPolicyListener;
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.SingleLineSummaryPreference;
 import com.android.settings.Utils;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.accessibility.AccessibilityUtils;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -70,20 +68,9 @@
 public class AccessibilitySettings extends SettingsPreferenceFragment implements
         Preference.OnPreferenceChangeListener, Indexable {
 
-    // Index of the first preference in a preference category.
-    private static final int FIRST_PREFERENCE_IN_CATEGORY_INDEX = 0;
-
     // Preference categories
-    private static final String CATEGORY_SCREEN_READER = "screen_reader_category";
-    private static final String CATEGORY_AUDIO_AND_CAPTIONS = "audio_and_captions_category";
-    private static final String CATEGORY_DISPLAY = "display_category";
-    private static final String CATEGORY_INTERACTION_CONTROL = "interaction_control_category";
-    private static final String CATEGORY_DOWNLOADED_SERVICES = "user_installed_services_category";
-
-    private static final String[] CATEGORIES = new String[] {
-        CATEGORY_SCREEN_READER, CATEGORY_AUDIO_AND_CAPTIONS, CATEGORY_DISPLAY,
-        CATEGORY_INTERACTION_CONTROL, CATEGORY_DOWNLOADED_SERVICES
-    };
+    private static final String SERVICES_CATEGORY = "services_category";
+    private static final String SYSTEM_CATEGORY = "system_category";
 
     // Preferences
     private static final String TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE =
@@ -131,7 +118,10 @@
     // ID for dialog that confirms shortcut capabilities
     private static final int DIALOG_ID_ADD_SHORTCUT_WARNING = 1;
 
-    private final Map<String, String> mLongPressTimeoutValueToTitleMap = new HashMap<>();
+    // Auxiliary members.
+    static final Set<ComponentName> sInstalledServices = new HashSet<>();
+
+    private final Map<String, String> mLongPressTimeoutValuetoTitleMap = new HashMap<>();
 
     private final Handler mHandler = new Handler();
 
@@ -139,7 +129,7 @@
         @Override
         public void run() {
             if (getActivity() != null) {
-                updateServicePreferences();
+                updateServicesPreferences();
             }
         }
     };
@@ -174,7 +164,7 @@
             new SettingsContentObserver(mHandler) {
                 @Override
                 public void onChange(boolean selfChange, Uri uri) {
-                    updateServicePreferences();
+                    updateServicesPreferences();
                 }
             };
 
@@ -185,12 +175,9 @@
         }
     };
 
-    private final Map<String, PreferenceCategory> mCategoryToPrefCategoryMap =
-            new ArrayMap<>();
-    private final Map<Preference, PreferenceCategory> mServicePreferenceToPreferenceCategoryMap =
-            new ArrayMap<>();
-    private final Map<ComponentName, PreferenceCategory> mPreBundledServiceComponentToCategoryMap =
-            new ArrayMap<>();
+    // Preference controls.
+    private PreferenceCategory mServicesCategory;
+    private PreferenceCategory mSystemsCategory;
 
     private SwitchPreference mToggleHighTextContrastPreference;
     private SwitchPreference mTogglePowerButtonEndsCallPreference;
@@ -273,7 +260,7 @@
         Settings.Secure.putInt(getContentResolver(),
                 Settings.Secure.LONG_PRESS_TIMEOUT, Integer.parseInt(stringValue));
         mSelectLongPressTimeoutPreference.setSummary(
-                mLongPressTimeoutValueToTitleMap.get(stringValue));
+                mLongPressTimeoutValuetoTitleMap.get(stringValue));
     }
 
     private void handleToggleInversionPreferenceChange(boolean checked) {
@@ -399,10 +386,8 @@
     }
 
     private void initializeAllPreferences() {
-        for (int i = 0; i < CATEGORIES.length; i++) {
-            PreferenceCategory prefCategory = (PreferenceCategory) findPreference(CATEGORIES[i]);
-            mCategoryToPrefCategoryMap.put(CATEGORIES[i], prefCategory);
-        }
+        mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY);
+        mSystemsCategory = (PreferenceCategory) findPreference(SYSTEM_CATEGORY);
 
         // Text contrast.
         mToggleHighTextContrastPreference =
@@ -417,16 +402,14 @@
                 (SwitchPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
         if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
                 || !Utils.isVoiceCapable(getActivity())) {
-            mCategoryToPrefCategoryMap.get(CATEGORY_INTERACTION_CONTROL)
-                    .removePreference(mTogglePowerButtonEndsCallPreference);
+            mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference);
         }
 
         // Lock screen rotation.
         mToggleLockScreenRotationPreference =
                 (SwitchPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE);
         if (!RotationPolicy.isRotationSupported(getActivity())) {
-            mCategoryToPrefCategoryMap.get(CATEGORY_INTERACTION_CONTROL)
-                    .removePreference(mToggleLockScreenRotationPreference);
+            mSystemsCategory.removePreference(mToggleLockScreenRotationPreference);
         }
 
         // Large pointer icon.
@@ -441,7 +424,7 @@
         mSelectLongPressTimeoutPreference =
                 (ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
         mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this);
-        if (mLongPressTimeoutValueToTitleMap.size() == 0) {
+        if (mLongPressTimeoutValuetoTitleMap.size() == 0) {
             String[] timeoutValues = getResources().getStringArray(
                     R.array.long_press_timeout_selector_values);
             mLongPressTimeoutDefault = Integer.parseInt(timeoutValues[0]);
@@ -449,7 +432,7 @@
                     R.array.long_press_timeout_selector_titles);
             final int timeoutValueCount = timeoutValues.length;
             for (int i = 0; i < timeoutValueCount; i++) {
-                mLongPressTimeoutValueToTitleMap.put(timeoutValues[i], timeoutTitles[i]);
+                mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i], timeoutTitles[i]);
             }
         }
 
@@ -476,32 +459,17 @@
     }
 
     private void updateAllPreferences() {
+        updateServicesPreferences();
         updateSystemPreferences();
-        updateServicePreferences();
     }
 
-    private void updateServicePreferences() {
+    private void updateServicesPreferences() {
         // Since services category is auto generated we have to do a pass
         // to generate it since services can come and go and then based on
         // the global accessibility state to decided whether it is enabled.
 
         // Generate.
-        ArrayList<Preference> servicePreferences =
-                new ArrayList<>(mServicePreferenceToPreferenceCategoryMap.keySet());
-        for (int i = 0; i < servicePreferences.size(); i++) {
-            Preference service = servicePreferences.get(i);
-            PreferenceCategory category = mServicePreferenceToPreferenceCategoryMap.get(service);
-            category.removePreference(service);
-        }
-
-        initializePreBundledServicesMapFromArray(CATEGORY_SCREEN_READER,
-                R.array.config_preinstalled_screen_reader_services);
-        initializePreBundledServicesMapFromArray(CATEGORY_AUDIO_AND_CAPTIONS,
-                R.array.config_preinstalled_audio_and_caption_services);
-        initializePreBundledServicesMapFromArray(CATEGORY_DISPLAY,
-                R.array.config_preinstalled_display_services);
-        initializePreBundledServicesMapFromArray(CATEGORY_INTERACTION_CONTROL,
-                R.array.config_preinstalled_interaction_control_services);
+        mServicesCategory.removeAll();
 
         AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity());
 
@@ -514,49 +482,36 @@
         final boolean accessibilityEnabled = Settings.Secure.getInt(getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
 
-        PreferenceCategory downloadedServicesCategory =
-                mCategoryToPrefCategoryMap.get(CATEGORY_DOWNLOADED_SERVICES);
-        // Temporarily add the downloaded services category back if it was previously removed.
-        if (findPreference(CATEGORY_DOWNLOADED_SERVICES) == null) {
-            getPreferenceScreen().addPreference(downloadedServicesCategory);
-        }
-
         for (int i = 0, count = installedServices.size(); i < count; ++i) {
             AccessibilityServiceInfo info = installedServices.get(i);
 
-            SingleLineSummaryPreference preference =
-                    new SingleLineSummaryPreference(downloadedServicesCategory.getContext(), null);
+            RestrictedPreference preference =
+                    new RestrictedPreference(mServicesCategory.getContext());
             String title = info.getResolveInfo().loadLabel(getPackageManager()).toString();
 
-            Drawable icon = info.getResolveInfo().loadIcon(getPackageManager());
-            if (icon == null) {
-                // todo (saigem): add a default
-            }
-
             ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
-            String packageName = serviceInfo.packageName;
-            ComponentName componentName = new ComponentName(packageName, serviceInfo.name);
-            String componentNameKey = componentName.flattenToString();
+            ComponentName componentName = new ComponentName(serviceInfo.packageName,
+                    serviceInfo.name);
 
             preference.setKey(componentName.flattenToString());
 
             preference.setTitle(title);
-            preference.setIcon(icon);
             final boolean serviceEnabled = accessibilityEnabled
                     && enabledServices.contains(componentName);
-            String serviceState = serviceEnabled ?
-                    getString(R.string.accessibility_feature_state_on) :
-                    getString(R.string.accessibility_feature_state_off);
-            String serviceSummary = info.loadSummary(getPackageManager());
-            serviceSummary = (TextUtils.isEmpty(serviceSummary)) ? serviceState.toUpperCase() :
-                    serviceState.toUpperCase() + " / " + serviceSummary;
+            String serviceEnabledString;
+            if (serviceEnabled) {
+                serviceEnabledString = getString(R.string.accessibility_feature_state_on);
+            } else {
+                serviceEnabledString = getString(R.string.accessibility_feature_state_off);
+            }
 
             // Disable all accessibility services that are not permitted.
+            String packageName = serviceInfo.packageName;
             boolean serviceAllowed =
                     permittedServices == null || permittedServices.contains(packageName);
             if (!serviceAllowed && !serviceEnabled) {
                 EnforcedAdmin admin = RestrictedLockUtils.checkIfAccessibilityServiceDisallowed(
-                        getActivity(), packageName, UserHandle.myUserId());
+                        getActivity(), serviceInfo.packageName, UserHandle.myUserId());
                 if (admin != null) {
                     preference.setDisabledByAdmin(admin);
                 } else {
@@ -566,7 +521,9 @@
                 preference.setEnabled(true);
             }
 
-            preference.setSummary(serviceSummary);
+            preference.setSummary(serviceEnabledString);
+
+            preference.setOrder(i);
             preference.setFragment(ToggleAccessibilityServicePreferenceFragment.class.getName());
             preference.setPersistent(true);
 
@@ -586,33 +543,26 @@
                 extras.putString(EXTRA_SETTINGS_TITLE,
                         getString(R.string.accessibility_menu_item_settings));
                 extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
-                        new ComponentName(packageName, settingsClassName).flattenToString());
+                        new ComponentName(info.getResolveInfo().serviceInfo.packageName,
+                                settingsClassName).flattenToString());
             }
+
             extras.putParcelable(EXTRA_COMPONENT_NAME, componentName);
 
-            PreferenceCategory prefCategory = downloadedServicesCategory;
-            // Set the appropriate category if the service comes pre-installed.
-            if (mPreBundledServiceComponentToCategoryMap.containsKey(componentName)) {
-                prefCategory = mPreBundledServiceComponentToCategoryMap.get(componentName);
+            mServicesCategory.addPreference(preference);
+        }
+
+        if (mServicesCategory.getPreferenceCount() == 0) {
+            if (mNoServicesMessagePreference == null) {
+                mNoServicesMessagePreference = new Preference(getPrefContext());
+                mNoServicesMessagePreference.setPersistent(false);
+                mNoServicesMessagePreference.setLayoutResource(
+                        R.layout.text_description_preference);
+                mNoServicesMessagePreference.setSelectable(false);
+                mNoServicesMessagePreference.setSummary(
+                        getString(R.string.accessibility_no_services_installed));
             }
-            preference.setOrder(FIRST_PREFERENCE_IN_CATEGORY_INDEX);
-            prefCategory.addPreference(preference);
-            mServicePreferenceToPreferenceCategoryMap.put(preference, prefCategory);
-        }
-
-        // If the user has not installed any additional services, hide the category.
-        if (downloadedServicesCategory.getPreferenceCount() == 0) {
-            PreferenceScreen screen = getPreferenceScreen();
-            screen.removePreference(downloadedServicesCategory);
-        }
-    }
-
-    private void initializePreBundledServicesMapFromArray(String categoryKey, int key) {
-        String[] services = getResources().getStringArray(key);
-        PreferenceCategory category = mCategoryToPrefCategoryMap.get(categoryKey);
-        for (int i = 0; i < services.length; i++) {
-            ComponentName component = ComponentName.unflattenFromString(services[i]);
-            mPreBundledServiceComponentToCategoryMap.put(component, category);
+            mServicesCategory.addPreference(mNoServicesMessagePreference);
         }
     }
 
@@ -652,7 +602,7 @@
                 Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault);
         String value = String.valueOf(longPressTimeout);
         mSelectLongPressTimeoutPreference.setValue(value);
-        mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValueToTitleMap.get(value));
+        mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
 
         updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
                 mCaptioningPreferenceScreen);
diff --git a/src/com/android/settings/applications/assist/GestureAssistPreferenceController.java b/src/com/android/settings/applications/assist/GestureAssistPreferenceController.java
deleted file mode 100644
index bd85a03..0000000
--- a/src/com/android/settings/applications/assist/GestureAssistPreferenceController.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.applications.assist;
-
-import android.content.Context;
-
-import com.android.settings.core.PreferenceController;
-import com.android.settings.gestures.AssistGestureFeatureProvider;
-import com.android.settings.overlay.FeatureFactory;
-
-public class GestureAssistPreferenceController extends PreferenceController {
-
-    private static final String KEY_ASSIST_GESTURE = "gesture_assist";
-
-    private AssistGestureFeatureProvider mFeatureProvider;
-
-    public GestureAssistPreferenceController(Context context) {
-        super(context);
-        mFeatureProvider = FeatureFactory.getFactory(context)
-                .getAssistGestureFeatureProvider();
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return mFeatureProvider.isSupported(mContext);
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_ASSIST_GESTURE;
-    }
-}
diff --git a/src/com/android/settings/applications/assist/ManageAssist.java b/src/com/android/settings/applications/assist/ManageAssist.java
index a54f0ff..824c0b1 100644
--- a/src/com/android/settings/applications/assist/ManageAssist.java
+++ b/src/com/android/settings/applications/assist/ManageAssist.java
@@ -24,6 +24,7 @@
 import com.android.settings.core.PreferenceController;
 import com.android.settings.core.lifecycle.Lifecycle;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.gestures.AssistGesturePreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 
@@ -70,7 +71,7 @@
             Lifecycle lifecycle) {
         final List<PreferenceController> controllers = new ArrayList<>();
         controllers.add(new DefaultAssistPreferenceController(context));
-        controllers.add(new GestureAssistPreferenceController(context));
+        controllers.add(new AssistGesturePreferenceController(context, lifecycle));
         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/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index 3fc0abf..e438cbf 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -34,7 +34,10 @@
 import android.view.View.OnClickListener;
 import android.widget.ImageView;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.Index;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -205,11 +208,20 @@
     void onClicked() {
         int bondState = mCachedDevice.getBondState();
 
+        final MetricsFeatureProvider metricsFeatureProvider =
+            FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider();
+
         if (mCachedDevice.isConnected()) {
+            metricsFeatureProvider.action(getContext(),
+                MetricsEvent.ACTION_SETTINGS_BLUETOOTH_DISCONNECT);
             askDisconnect();
         } else if (bondState == BluetoothDevice.BOND_BONDED) {
+            metricsFeatureProvider.action(getContext(),
+                MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT);
             mCachedDevice.connect(true);
         } else if (bondState == BluetoothDevice.BOND_NONE) {
+            metricsFeatureProvider.action(getContext(),
+                MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR);
             pair();
         }
     }
diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java
index 83c0560..6db51df 100644
--- a/src/com/android/settings/bluetooth/BluetoothEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java
@@ -27,7 +27,6 @@
 import android.widget.Switch;
 import android.widget.Toast;
 
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.search.Index;
@@ -52,6 +51,7 @@
 
     private static final String EVENT_DATA_IS_BT_ON = "is_bluetooth_on";
     private static final int EVENT_UPDATE_INDEX = 0;
+    private final int mMetricsEvent;
 
     private Handler mHandler = new Handler() {
         @Override
@@ -77,13 +77,15 @@
     };
 
     public BluetoothEnabler(Context context, SwitchWidgetController switchWidget,
-            MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager) {
+            MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager,
+            int metricsEvent) {
         mContext = context;
         mMetricsFeatureProvider = metricsFeatureProvider;
         mSwitchWidget = switchWidget;
         mSwitch = mSwitchWidget.getSwitch();
         mSwitchWidget.setListener(this);
         mValidListener = false;
+        mMetricsEvent = metricsEvent;
 
         if (manager == null) {
             // Bluetooth is not supported
@@ -191,7 +193,7 @@
             return false;
         }
 
-        mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_BLUETOOTH_TOGGLE, isChecked);
+        mMetricsFeatureProvider.action(mContext, mMetricsEvent, isChecked);
 
         if (mLocalAdapter != null) {
             boolean status = mLocalAdapter.setBluetoothEnabled(isChecked);
diff --git a/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceController.java
index d9b1bea..f98a209 100644
--- a/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceController.java
@@ -18,6 +18,7 @@
 import android.content.Context;
 import android.support.v7.preference.PreferenceScreen;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.core.PreferenceController;
 import com.android.settings.core.lifecycle.LifecycleObserver;
 import com.android.settings.core.lifecycle.events.OnPause;
@@ -54,7 +55,8 @@
         mBtPreference = (MasterSwitchPreference) screen.findPreference(KEY_TOGGLE_BLUETOOTH);
         mBluetoothEnabler = new BluetoothEnabler(mContext,
             new MasterSwitchController(mBtPreference),
-            FeatureFactory.getFactory(mContext).getMetricsFeatureProvider(), mBluetoothManager);
+            FeatureFactory.getFactory(mContext).getMetricsFeatureProvider(), mBluetoothManager,
+            MetricsEvent.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE);
     }
 
     @Override
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index acb99a6..5679f90 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -153,7 +153,8 @@
         mSwitchBar = activity.getSwitchBar();
 
         mBluetoothEnabler = new BluetoothEnabler(activity, new SwitchBarController(mSwitchBar),
-            mMetricsFeatureProvider, Utils.getLocalBtManager(activity));
+            mMetricsFeatureProvider, Utils.getLocalBtManager(activity),
+            MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
         mBluetoothEnabler.setupSwitchController();
     }
 
diff --git a/src/com/android/settings/bluetooth/Utils.java b/src/com/android/settings/bluetooth/Utils.java
index 4fa44b4..037b381 100755
--- a/src/com/android/settings/bluetooth/Utils.java
+++ b/src/com/android/settings/bluetooth/Utils.java
@@ -21,9 +21,12 @@
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.support.annotation.VisibleForTesting;
 import android.widget.Toast;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.Index;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -84,14 +87,25 @@
 
     // TODO: wire this up to show connection errors...
     static void showConnectingError(Context context, String name) {
-        showError(context, name, R.string.bluetooth_connecting_error_message);
+        showConnectingError(context, name, getLocalBtManager(context));
+    }
+
+    @VisibleForTesting
+    static void showConnectingError(Context context, String name, LocalBluetoothManager manager) {
+        FeatureFactory.getFactory(context).getMetricsFeatureProvider().visible(context,
+            MetricsEvent.VIEW_UNKNOWN, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT_ERROR);
+        showError(context, name, R.string.bluetooth_connecting_error_message, manager);
     }
 
     static void showError(Context context, String name, int messageResId) {
+        showError(context, name, messageResId, getLocalBtManager(context));
+    }
+
+    private static void showError(Context context, String name, int messageResId,
+            LocalBluetoothManager manager) {
         String message = context.getString(messageResId, name);
-        LocalBluetoothManager manager = getLocalBtManager(context);
         Context activity = manager.getForegroundActivity();
-        if(manager.isForegroundActivity()) {
+        if (manager.isForegroundActivity()) {
             new AlertDialog.Builder(activity)
                 .setTitle(R.string.bluetooth_error_title)
                 .setMessage(message)
diff --git a/src/com/android/settings/core/DynamicAvailabilityPreferenceController.java b/src/com/android/settings/core/DynamicAvailabilityPreferenceController.java
new file mode 100644
index 0000000..9323aa3
--- /dev/null
+++ b/src/com/android/settings/core/DynamicAvailabilityPreferenceController.java
@@ -0,0 +1,59 @@
+/*
+ * 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.core;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnResume;
+
+public abstract class DynamicAvailabilityPreferenceController extends PreferenceController
+        implements LifecycleObserver, OnResume {
+
+    private Preference mPreference;
+    private PreferenceScreen mScreen;
+
+    public DynamicAvailabilityPreferenceController(Context context, Lifecycle lifecycle) {
+        super(context);
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        mScreen = screen;
+        mPreference = screen.findPreference(getPreferenceKey());
+        super.displayPreference(screen);
+    }
+
+    @Override
+    public void onResume() {
+        if (!isAvailable()) {
+            removePreference(mScreen, getPreferenceKey());
+            return;
+        }
+
+        updateState(mPreference);
+        if (mScreen.findPreference(getPreferenceKey()) == null) {
+            mScreen.addPreference(mPreference);
+        }
+    }
+}
diff --git a/src/com/android/settings/datausage/DataUsageMeteredSettings.java b/src/com/android/settings/datausage/DataUsageMeteredSettings.java
index 1982887..ce2bc8d 100644
--- a/src/com/android/settings/datausage/DataUsageMeteredSettings.java
+++ b/src/com/android/settings/datausage/DataUsageMeteredSettings.java
@@ -114,7 +114,8 @@
     }
 
     private Preference buildWifiPref(WifiConfiguration config) {
-        final String networkId = config.SSID;
+        final String networkId = config.isPasspoint() ?
+                config.providerFriendlyName : config.SSID;
         final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(networkId);
         final MeteredPreference pref = new MeteredPreference(getPrefContext(), template);
         pref.setTitle(removeDoubleQuotes(networkId));
diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
index bff0882..4d4cfe8 100644
--- a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
+++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.app.FragmentManager;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.os.Bundle;
diff --git a/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java b/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
deleted file mode 100644
index 769b69b..0000000
--- a/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.deviceinfo;
-
-import android.content.Context;
-
-import com.android.settings.R;
-import com.android.settings.core.PreferenceController;
-
-public class ManageStoragePreferenceController extends PreferenceController {
-
-    public static final String KEY_MANAGE_STORAGE = "manage_storage";
-
-    public ManageStoragePreferenceController(Context context) {
-        super(context);
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_MANAGE_STORAGE;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return mContext.getResources().getBoolean(R.bool.config_storage_manager_settings_enabled);
-    }
-}
-
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 92703e3..133c56c 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -35,6 +35,7 @@
 import com.android.settings.applications.UserManagerWrapperImpl;
 import com.android.settings.core.PreferenceController;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController;
 import com.android.settings.deviceinfo.storage.SecondaryUserController;
 import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
 import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
@@ -146,7 +147,11 @@
         mSecondaryUsers = SecondaryUserController.getSecondaryUserControllers(context, userManager);
         controllers.addAll(mSecondaryUsers);
 
-        controllers.add(new ManageStoragePreferenceController(context));
+        final AutomaticStorageManagementSwitchPreferenceController asmController =
+                new AutomaticStorageManagementSwitchPreferenceController(
+                        context, mMetricsFeatureProvider, getFragmentManager());
+        getLifecycle().addObserver(asmController);
+        controllers.add(asmController);
         return controllers;
     }
 
@@ -189,7 +194,6 @@
                             null /* volume */, new StorageManagerVolumeProvider(sm)));
                     controllers.addAll(SecondaryUserController.getSecondaryUserControllers(
                             context, userManager));
-                    controllers.add(new ManageStoragePreferenceController(context));
                     return controllers;
                 }
 
diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java
index c062a56..b2bad3a 100644
--- a/src/com/android/settings/deviceinfo/StorageSettings.java
+++ b/src/com/android/settings/deviceinfo/StorageSettings.java
@@ -234,8 +234,8 @@
             final Bundle args = new Bundle();
             args.putString(VolumeInfo.EXTRA_VOLUME_ID, VolumeInfo.ID_PRIVATE_INTERNAL);
             Intent intent = Utils.onBuildStartFragmentIntent(getActivity(),
-                    StorageDashboardFragment.class.getName(), args, null, R.string.apps_storage,
-                    null, false, getMetricsCategory());
+                    StorageDashboardFragment.class.getName(), args, null,
+                    R.string.storage_settings_2, null, false, getMetricsCategory());
             intent.putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true);
             getActivity().startActivity(intent);
             finish();
@@ -280,7 +280,7 @@
 
                 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
                     startFragment(this, StorageDashboardFragment.class.getCanonicalName(),
-                            -1, 0, args);
+                            R.string.storage_settings_2, 0, args);
                 } else {
                     // TODO: Go to the StorageDashboardFragment once it fully handles all of the
                     //       SD card cases and other private internal storage cases.
diff --git a/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
new file mode 100644
index 0000000..a8ca5b9
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
@@ -0,0 +1,100 @@
+/**
+ * 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.deviceinfo.storage;
+
+import android.app.FragmentManager;
+import android.content.Context;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnResume;
+import com.android.settings.deletionhelper.ActivationWarningFragment;
+import com.android.settings.widget.MasterSwitchController;
+import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settings.widget.SwitchWidgetController;
+
+public class AutomaticStorageManagementSwitchPreferenceController extends PreferenceController
+        implements LifecycleObserver, OnResume, SwitchWidgetController.OnSwitchChangeListener {
+    private static final String KEY_TOGGLE_ASM = "toggle_asm";
+    @VisibleForTesting
+    static final String STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY = "ro.storage_manager.enabled";
+
+    private MasterSwitchPreference mSwitch;
+    private MasterSwitchController mSwitchController;
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
+    private final FragmentManager mFragmentManager;
+
+    public AutomaticStorageManagementSwitchPreferenceController(Context context,
+            MetricsFeatureProvider metricsFeatureProvider, FragmentManager fragmentManager) {
+        super(context);
+        mMetricsFeatureProvider = metricsFeatureProvider;
+        mFragmentManager = fragmentManager;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mSwitch = (MasterSwitchPreference) screen.findPreference(KEY_TOGGLE_ASM);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_TOGGLE_ASM;
+    }
+
+    @Override
+    public void onResume() {
+        boolean isStorageManagerEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0) != 0;
+        mSwitch.setChecked(isStorageManagerEnabled);
+
+        if (mSwitch != null) {
+            mSwitchController = new MasterSwitchController(mSwitch);
+            mSwitchController.setListener(this);
+            mSwitchController.startListening();
+        }
+    }
+
+    @Override
+    public boolean onSwitchToggled(boolean isChecked) {
+        mMetricsFeatureProvider.action(mContext,
+                MetricsEvent.ACTION_TOGGLE_STORAGE_MANAGER, isChecked);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
+                isChecked ? 1 : 0);
+
+        boolean storageManagerEnabledByDefault = SystemProperties.getBoolean(
+                STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY, false);
+        if (isChecked && !storageManagerEnabledByDefault) {
+            ActivationWarningFragment fragment = ActivationWarningFragment.newInstance();
+            fragment.show(mFragmentManager, ActivationWarningFragment.TAG);
+        }
+
+        return true;
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java
index 8b6bac0..44d3d44 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java
@@ -80,23 +80,6 @@
         if (deletionHelperButton != null) {
             deletionHelperButton.setOnClickListener(this);
         }
-
-        final TextView storageManagerText =
-                (TextView) view.findViewById(R.id.storage_manager_indicator);
-        if (storageManagerText != null) {
-            Context context = getContext();
-            final SpannableString templateSs = new SpannableString(
-                    context.getString(R.string.storage_manager_indicator));
-            boolean isStorageManagerEnabled = Settings.Secure.getInt(context.getContentResolver(),
-                    Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0) != 0;
-            String value = isStorageManagerEnabled ?
-                    context.getString(R.string.storage_manager_indicator_on) :
-                    context.getString(R.string.storage_manager_indicator_off);
-            Locale locale = storageManagerText.getTextLocale();
-            final SpannableString ss = new SpannableString(value.toUpperCase(locale));
-            ss.setSpan(new BoldLinkSpan(), 0, value.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-            storageManagerText.setText(TextUtils.expandTemplate(templateSs, ss));
-        }
     }
 
     @Override
diff --git a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
index a962669..c4613ed 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
@@ -17,7 +17,6 @@
 package com.android.settings.deviceinfo.storage;
 
 import android.content.Context;
-import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
@@ -26,7 +25,6 @@
 
 import com.android.settings.R;
 import com.android.settings.core.PreferenceController;
-import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
 /**
diff --git a/src/com/android/settings/gestures/AssistGesturePreferenceController.java b/src/com/android/settings/gestures/AssistGesturePreferenceController.java
index 99d38b6..f0ba888 100644
--- a/src/com/android/settings/gestures/AssistGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/AssistGesturePreferenceController.java
@@ -17,29 +17,90 @@
 package com.android.settings.gestures;
 
 import android.content.Context;
+import android.net.Uri;
 import android.provider.Settings;
 import android.support.v7.preference.Preference;
-import android.util.ArrayMap;
+import android.support.v7.preference.PreferenceScreen;
 
+import com.android.settings.applications.assist.AssistSettingObserver;
 import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.search2.InlineSwitchPayload;
-import com.android.settings.search2.ResultPayload;
 
-public class AssistGesturePreferenceController extends GesturePreferenceController {
+import java.util.Arrays;
+import java.util.List;
+
+public class AssistGesturePreferenceController extends GesturePreferenceController
+        implements OnPause, OnResume {
 
     private static final String PREF_KEY_VIDEO = "gesture_assist_video";
     private static final String PREF_KEY_ASSIST_GESTURE = "gesture_assist";
 
+    private final AssistGestureFeatureProvider mFeatureProvider;
+    private final SettingObserver mSettingObserver;
+    private boolean mWasAvailable;
+
+    private PreferenceScreen mScreen;
+    private Preference mPreference;
+
     public AssistGesturePreferenceController(Context context, Lifecycle lifecycle) {
         super(context, lifecycle);
+        mFeatureProvider = FeatureFactory.getFactory(context).getAssistGestureFeatureProvider();
+        mSettingObserver = new SettingObserver();
+        mWasAvailable = isAvailable();
     }
 
     @Override
     public boolean isAvailable() {
-        AssistGestureFeatureProvider provider =
-                FeatureFactory.getFactory(mContext).getAssistGestureFeatureProvider();
-        return provider.isSupported(mContext);
+        return mFeatureProvider.isSupported(mContext);
+    }
+
+    @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);
+    }
+
+    @Override
+    public void onResume() {
+        mSettingObserver.register(mContext.getContentResolver(), true /* register */);
+        if (mWasAvailable != isAvailable()) {
+            // Only update the preference visibility if the availability has changed -- otherwise
+            // the preference may be incorrectly added to screens with collapsed sections.
+            updatePreference();
+            mWasAvailable = isAvailable();
+        }
+    }
+
+    @Override
+    public void onPause() {
+        mSettingObserver.register(mContext.getContentResolver(), false /* register */);
+    }
+
+    private void updatePreference() {
+        if (mPreference == null) {
+            return;
+        }
+
+        if (isAvailable()) {
+            if (mScreen.findPreference(getPreferenceKey()) == null) {
+                mScreen.addPreference(mPreference);
+            }
+        } else {
+            mScreen.removePreference(mPreference);
+        }
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        final boolean enabled = (boolean) newValue;
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ASSIST_GESTURE_ENABLED, enabled ? 1 : 0);
+        return true;
     }
 
     @Override
@@ -53,17 +114,28 @@
     }
 
     @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final boolean enabled = (boolean) newValue;
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.ASSIST_GESTURE_ENABLED, enabled ? 1 : 0);
-        return true;
-    }
-
-    @Override
     protected boolean isSwitchPrefEnabled() {
         final int assistGestureEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.ASSIST_GESTURE_ENABLED, 1);
         return assistGestureEnabled != 0;
     }
+
+    class SettingObserver extends AssistSettingObserver {
+
+        private final Uri ASSIST_GESTURE_ENABLED_URI =
+                Settings.Secure.getUriFor(Settings.Secure.ASSIST_GESTURE_ENABLED);
+
+        @Override
+        protected List<Uri> getSettingUris() {
+            return Arrays.asList(ASSIST_GESTURE_ENABLED_URI);
+        }
+
+        @Override
+        public void onSettingChange() {
+            if (mWasAvailable != isAvailable()) {
+                updatePreference();
+                mWasAvailable = isAvailable();
+            }
+        }
+    }
 }
diff --git a/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceController.java b/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceController.java
new file mode 100644
index 0000000..5334e62
--- /dev/null
+++ b/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceController.java
@@ -0,0 +1,151 @@
+/*
+ * 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.gestures;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.SeekBarPreference;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
+import com.android.settings.overlay.FeatureFactory;
+
+public class AssistGestureSensitivityPreferenceController extends PreferenceController
+        implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnPause, OnResume {
+
+    private static final String PREF_KEY_ASSIST_GESTURE_SENSITIVITY = "gesture_assist_sensitivity";
+
+    private final AssistGestureFeatureProvider mFeatureProvider;
+    private final SettingObserver mSettingObserver;
+
+    private PreferenceScreen mScreen;
+    private SeekBarPreference mPreference;
+
+    public AssistGestureSensitivityPreferenceController(Context context, Lifecycle lifecycle) {
+        super(context);
+        mFeatureProvider = FeatureFactory.getFactory(context).getAssistGestureFeatureProvider();
+        mSettingObserver = new SettingObserver();
+
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        mSettingObserver.register(mContext.getContentResolver(), true /* register */);
+        updatePreference();
+    }
+
+    @Override
+    public void onPause() {
+        mSettingObserver.register(mContext.getContentResolver(), false /* register */);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        // The sensitivity control is contingent on the assist gesture being supported and the
+        // gesture being enabled.
+        final int gestureEnabled = Settings.Secure.getInt(
+                mContext.getContentResolver(),
+                Settings.Secure.ASSIST_GESTURE_ENABLED,
+                1);
+        return (gestureEnabled == 1) && mFeatureProvider.isSupported(mContext);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        mScreen = screen;
+        mPreference = (SeekBarPreference) 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);
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        updatePreference();
+    }
+
+    private void updatePreference() {
+        if (mPreference == null) {
+            return;
+        }
+
+        if (isAvailable()) {
+            if (mScreen.findPreference(getPreferenceKey()) == null) {
+                mScreen.addPreference(mPreference);
+            }
+        } else {
+            mScreen.removePreference(mPreference);
+        }
+
+        final int sensitivity = Settings.Secure.getInt(
+                mContext.getContentResolver(),
+                Settings.Secure.ASSIST_GESTURE_SENSITIVITY,
+                mPreference.getProgress());
+        mPreference.setProgress(sensitivity);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        final int sensitivity = (int) newValue;
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ASSIST_GESTURE_SENSITIVITY, sensitivity);
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return PREF_KEY_ASSIST_GESTURE_SENSITIVITY;
+    }
+
+    class SettingObserver extends ContentObserver {
+
+        private final Uri ASSIST_GESTURE_ENABLED_URI =
+                Settings.Secure.getUriFor(Settings.Secure.ASSIST_GESTURE_ENABLED);
+        private final Uri ASSIST_GESTURE_SENSITIVITY_URI =
+                Settings.Secure.getUriFor(Settings.Secure.ASSIST_GESTURE_SENSITIVITY);
+
+        public SettingObserver() {
+            super(null /* handler */);
+        }
+
+        public void register(ContentResolver cr, boolean register) {
+            if (register) {
+                cr.registerContentObserver(ASSIST_GESTURE_ENABLED_URI, false, this);
+                cr.registerContentObserver(ASSIST_GESTURE_SENSITIVITY_URI, false, this);
+            } else {
+                cr.unregisterContentObserver(this);
+            }
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            updatePreference();
+        }
+    }
+}
diff --git a/src/com/android/settings/gestures/AssistGestureSettings.java b/src/com/android/settings/gestures/AssistGestureSettings.java
index 7778720..238b8b6 100644
--- a/src/com/android/settings/gestures/AssistGestureSettings.java
+++ b/src/com/android/settings/gestures/AssistGestureSettings.java
@@ -58,6 +58,7 @@
             Lifecycle lifecycle) {
         final List<PreferenceController> controllers = new ArrayList<>();
         controllers.add(new AssistGesturePreferenceController(context, lifecycle));
+        controllers.add(new AssistGestureSensitivityPreferenceController(context, lifecycle));
         return controllers;
     }
 
diff --git a/src/com/android/settings/notification/WorkSoundPreferenceController.java b/src/com/android/settings/notification/WorkSoundPreferenceController.java
index 5ffb30b..a4d7b8d 100644
--- a/src/com/android/settings/notification/WorkSoundPreferenceController.java
+++ b/src/com/android/settings/notification/WorkSoundPreferenceController.java
@@ -25,7 +25,6 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.media.AudioSystem;
 import android.media.Ringtone;
 import android.media.RingtoneManager;
 import android.net.Uri;
@@ -38,7 +37,6 @@
 import android.support.v7.preference.PreferenceGroup;
 import android.support.v7.preference.PreferenceScreen;
 import android.support.v7.preference.TwoStatePreference;
-import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -53,7 +51,7 @@
 import com.android.settings.core.lifecycle.events.OnResume;
 
 public class WorkSoundPreferenceController extends PreferenceController implements
-    OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
+        OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
 
     private static final String TAG = "WorkSoundPrefController";
     private static final String KEY_WORK_CATEGORY = "sound_work_settings_section";
@@ -62,27 +60,28 @@
     private static final String KEY_WORK_NOTIFICATION_RINGTONE = "work_notification_ringtone";
     private static final String KEY_WORK_ALARM_RINGTONE = "work_alarm_ringtone";
 
+    private final boolean mVoiceCapable;
+    private final UserManager mUserManager;
+    private final SoundSettings mParent;
+    private final AudioHelper mHelper;
+
     private PreferenceGroup mWorkPreferenceCategory;
     private TwoStatePreference mWorkUsePersonalSounds;
     private Preference mWorkPhoneRingtonePreference;
     private Preference mWorkNotificationRingtonePreference;
     private Preference mWorkAlarmRingtonePreference;
-    private boolean mVoiceCapable;
-    private UserManager mUserManager;
-    private SoundSettings mParent;
-    private AudioHelper mHelper;
 
-    private @UserIdInt
-    int mManagedProfileId;
+    @UserIdInt
+    private int mManagedProfileId;
 
     public WorkSoundPreferenceController(Context context, SoundSettings parent,
-        Lifecycle lifecycle) {
+            Lifecycle lifecycle) {
         this(context, parent, lifecycle, new AudioHelper(context));
     }
 
     @VisibleForTesting
     WorkSoundPreferenceController(Context context, SoundSettings parent, Lifecycle lifecycle,
-        AudioHelper helper) {
+            AudioHelper helper) {
         super(context);
         mUserManager = UserManager.get(context);
         mVoiceCapable = Utils.isVoiceCapable(mContext);
@@ -95,7 +94,10 @@
 
     @Override
     public void displayPreference(PreferenceScreen screen) {
-        // do nothing
+        mWorkPreferenceCategory = (PreferenceGroup) screen.findPreference(KEY_WORK_CATEGORY);
+        if (mWorkPreferenceCategory != null) {
+            mWorkPreferenceCategory.setVisible(isAvailable());
+        }
     }
 
     @Override
@@ -106,7 +108,7 @@
         mContext.registerReceiver(mManagedProfileReceiver, managedProfileFilter);
 
         mManagedProfileId = mHelper.getManagedProfileId(mUserManager);
-        initWorkPreferences();
+        updateWorkPreferences();
     }
 
     @Override
@@ -165,7 +167,7 @@
         }
         Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(context, type);
         return Ringtone.getTitle(context, ringtoneUri, false /* followSettingsUri */,
-            true /* allowRemote */);
+                true /* allowRemote */);
     }
 
     private Context getManagedProfileContext() {
@@ -175,9 +177,9 @@
         return mHelper.createPackageContextAsUser(mManagedProfileId);
     }
 
-    private DefaultRingtonePreference initWorkPreference(String key) {
+    private DefaultRingtonePreference initWorkPreference(PreferenceGroup root, String key) {
         DefaultRingtonePreference pref =
-            (DefaultRingtonePreference) mParent.getPreferenceScreen().findPreference(key);
+                (DefaultRingtonePreference) root.findPreference(key);
         pref.setOnPreferenceChangeListener(this);
 
         // Required so that RingtonePickerActivity lists the work profile ringtones
@@ -185,24 +187,18 @@
         return pref;
     }
 
-    private void initWorkPreferences() {
-        if (mManagedProfileId == UserHandle.USER_NULL || !isAvailable()) {
-            maybeRemoveWorkPreferences();
+    private void updateWorkPreferences() {
+        if (mWorkPreferenceCategory == null) {
             return;
         }
-
-        if (mWorkPreferenceCategory == null) {
-            mParent.addPreferencesFromResource(R.xml.sound_work_settings);
-            final PreferenceScreen screen = mParent.getPreferenceScreen();
-
-            mWorkPreferenceCategory = (PreferenceGroup) screen.findPreference(KEY_WORK_CATEGORY);
+        final boolean isAvailable = isAvailable();
+        mWorkPreferenceCategory.setVisible(isAvailable);
+        if (!isAvailable) {
+            return;
+        }
+        if (mWorkUsePersonalSounds == null) {
             mWorkUsePersonalSounds = (TwoStatePreference)
-                    screen.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS);
-            mWorkPhoneRingtonePreference = initWorkPreference(KEY_WORK_PHONE_RINGTONE);
-            mWorkNotificationRingtonePreference = initWorkPreference(
-                    KEY_WORK_NOTIFICATION_RINGTONE);
-            mWorkAlarmRingtonePreference = initWorkPreference(KEY_WORK_ALARM_RINGTONE);
-
+                    mWorkPreferenceCategory.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS);
             mWorkUsePersonalSounds.setOnPreferenceChangeListener((Preference p, Object value) -> {
                 if ((boolean) value) {
                     UnifyWorkDialogFragment.show(mParent);
@@ -212,16 +208,27 @@
                     return true;
                 }
             });
-
-            if (!mVoiceCapable) {
-                mWorkPreferenceCategory.removePreference(mWorkPhoneRingtonePreference);
-                mWorkPhoneRingtonePreference = null;
-            }
+        }
+        if (mWorkPhoneRingtonePreference == null) {
+            mWorkPhoneRingtonePreference = initWorkPreference(mWorkPreferenceCategory,
+                    KEY_WORK_PHONE_RINGTONE);
+        }
+        if (mWorkNotificationRingtonePreference == null) {
+            mWorkNotificationRingtonePreference = initWorkPreference(mWorkPreferenceCategory,
+                    KEY_WORK_NOTIFICATION_RINGTONE);
+        }
+        if (mWorkAlarmRingtonePreference == null) {
+            mWorkAlarmRingtonePreference = initWorkPreference(mWorkPreferenceCategory,
+                    KEY_WORK_ALARM_RINGTONE);
+        }
+        if (!mVoiceCapable) {
+            mWorkPreferenceCategory.removePreference(mWorkPhoneRingtonePreference);
+            mWorkPhoneRingtonePreference = null;
         }
 
-        Context managedProfileContext = getManagedProfileContext();
+        final Context managedProfileContext = getManagedProfileContext();
         if (Settings.Secure.getIntForUser(managedProfileContext.getContentResolver(),
-            Settings.Secure.SYNC_PARENT_SOUNDS, 0, mManagedProfileId) == 1) {
+                Settings.Secure.SYNC_PARENT_SOUNDS, 0, mManagedProfileId) == 1) {
             enableWorkSyncSettings();
         } else {
             disableWorkSyncSettings();
@@ -237,13 +244,10 @@
         mWorkUsePersonalSounds.setChecked(true);
 
         if (mWorkPhoneRingtonePreference != null) {
-            mWorkPhoneRingtonePreference.setSummary(
-                com.android.settings.R.string.work_sound_same_as_personal);
+            mWorkPhoneRingtonePreference.setSummary(R.string.work_sound_same_as_personal);
         }
-        mWorkNotificationRingtonePreference.setSummary(
-            com.android.settings.R.string.work_sound_same_as_personal);
-        mWorkAlarmRingtonePreference.setSummary(
-            com.android.settings.R.string.work_sound_same_as_personal);
+        mWorkNotificationRingtonePreference.setSummary(R.string.work_sound_same_as_personal);
+        mWorkAlarmRingtonePreference.setSummary(R.string.work_sound_same_as_personal);
     }
 
     private void disableWorkSync() {
@@ -266,36 +270,25 @@
 
         if (mWorkPhoneRingtonePreference != null) {
             mWorkPhoneRingtonePreference.setSummary(
-                updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_RINGTONE));
+                    updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_RINGTONE));
         }
         mWorkNotificationRingtonePreference.setSummary(
-            updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_NOTIFICATION));
+                updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_NOTIFICATION));
         mWorkAlarmRingtonePreference.setSummary(
-            updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_ALARM));
-    }
-
-    private void maybeRemoveWorkPreferences() {
-        if (mWorkPreferenceCategory == null) {
-            return;
-        }
-        mParent.getPreferenceScreen().removePreference(mWorkPreferenceCategory);
-        mWorkPreferenceCategory = null;
-        mWorkPhoneRingtonePreference = null;
-        mWorkNotificationRingtonePreference = null;
-        mWorkAlarmRingtonePreference = null;
+                updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_ALARM));
     }
 
     public void onManagedProfileAdded(@UserIdInt int profileId) {
         if (mManagedProfileId == UserHandle.USER_NULL) {
             mManagedProfileId = profileId;
-            initWorkPreferences();
+            updateWorkPreferences();
         }
     }
 
     public void onManagedProfileRemoved(@UserIdInt int profileId) {
         if (mManagedProfileId == profileId) {
             mManagedProfileId = mHelper.getManagedProfileId(mUserManager);
-            initWorkPreferences();
+            updateWorkPreferences();
         }
     }
 
@@ -317,7 +310,7 @@
     };
 
     public static class UnifyWorkDialogFragment extends InstrumentedDialogFragment
-        implements DialogInterface.OnClickListener {
+            implements DialogInterface.OnClickListener {
         private static final String TAG = "UnifyWorkDialogFragment";
         private static final int REQUEST_CODE = 200;
 
@@ -329,12 +322,11 @@
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             return new AlertDialog.Builder(getActivity())
-                .setTitle(com.android.settings.R.string.work_sync_dialog_title)
-                .setMessage(com.android.settings.R.string.work_sync_dialog_message)
-                .setPositiveButton(com.android.settings.R.string.work_sync_dialog_yes,
-                    UnifyWorkDialogFragment.this)
-                .setNegativeButton(android.R.string.no, null)
-                .create();
+                    .setTitle(R.string.work_sync_dialog_title)
+                    .setMessage(R.string.work_sync_dialog_message)
+                    .setPositiveButton(R.string.work_sync_dialog_yes, UnifyWorkDialogFragment.this)
+                    .setNegativeButton(android.R.string.no, null)
+                    .create();
         }
 
         public static void show(SoundSettings parent) {
diff --git a/src/com/android/settings/webview/WebViewAppPicker.java b/src/com/android/settings/webview/WebViewAppPicker.java
index 586ee36..f1faf9b 100644
--- a/src/com/android/settings/webview/WebViewAppPicker.java
+++ b/src/com/android/settings/webview/WebViewAppPicker.java
@@ -21,7 +21,9 @@
 import android.app.Activity;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.content.Context;
 import android.support.annotation.VisibleForTesting;
 import android.text.TextUtils;
@@ -60,8 +62,8 @@
                 getWebViewUpdateServiceWrapper().getValidWebViewApplicationInfos(getContext());
         for (ApplicationInfo ai : pkgs) {
             packageInfoList.add(createDefaultAppInfo(ai,
-                      getDisabledReason(getWebViewUpdateServiceWrapper(),
-                              getContext(), ai.packageName)));
+                    getDisabledReason(getWebViewUpdateServiceWrapper(),
+                            getContext(), ai.packageName)));
         }
         return packageInfoList;
     }
@@ -107,10 +109,26 @@
         return MetricsEvent.WEBVIEW_IMPLEMENTATION;
     }
 
+    private static class WebViewAppInfo extends DefaultAppInfo {
+        public WebViewAppInfo(PackageItemInfo packageItemInfo, String summary, boolean enabled) {
+          super(packageItemInfo, summary, enabled);
+        }
+
+        @Override
+        public CharSequence loadLabel(PackageManager pm) {
+            String versionName = "";
+            try {
+                versionName = pm.getPackageInfo(packageItemInfo.packageName, 0).versionName;
+            } catch (PackageManager.NameNotFoundException e) {
+            }
+            return String.format("%s %s", super.loadLabel(pm), versionName);
+        }
+    }
+
+
     @VisibleForTesting
-    DefaultAppInfo createDefaultAppInfo(
-            ApplicationInfo applicationInfo, String disabledReason) {
-        return new DefaultAppInfo(applicationInfo, disabledReason,
+    DefaultAppInfo createDefaultAppInfo(PackageItemInfo packageItemInfo, String disabledReason) {
+        return new WebViewAppInfo(packageItemInfo, disabledReason,
                 TextUtils.isEmpty(disabledReason) /* enabled */);
     }
 
diff --git a/src/com/android/settings/wfd/WifiDisplaySettings.java b/src/com/android/settings/wfd/WifiDisplaySettings.java
index f7c2f6e..0d6b4dc 100755
--- a/src/com/android/settings/wfd/WifiDisplaySettings.java
+++ b/src/com/android/settings/wfd/WifiDisplaySettings.java
@@ -125,9 +125,9 @@
         super.onCreate(icicle);
 
         final Context context = getActivity();
-        mRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
-        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
-        mWifiP2pManager = (WifiP2pManager)context.getSystemService(Context.WIFI_P2P_SERVICE);
+        mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+        mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+        mWifiP2pManager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE);
         mWifiP2pChannel = mWifiP2pManager.initialize(context, Looper.getMainLooper(), null);
 
         addPreferencesFromResource(R.xml.wifi_display_settings);
@@ -211,6 +211,11 @@
         return super.onOptionsItemSelected(item);
     }
 
+    public static boolean isAvailable(Context context) {
+        return context.getSystemService(Context.DISPLAY_SERVICE) != null
+                && context.getSystemService(Context.WIFI_P2P_SERVICE) != null;
+    }
+
     private void scheduleUpdate(int changes) {
         if (mStarted) {
             if (mPendingChanges == 0) {
@@ -237,7 +242,7 @@
             mWifiDisplayCertificationOn = Settings.Global.getInt(getContentResolver(),
                     Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0;
             mWpsConfig = Settings.Global.getInt(getContentResolver(),
-                Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
+                    Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
 
             // The wifi display enabled setting may have changed.
             invalidateOptions = true;
@@ -402,12 +407,12 @@
         });
         mWpsConfig = Settings.Global.getInt(getActivity().getContentResolver(),
                 Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
-        String[] wpsEntries = { "Default", "PBC", "KEYPAD", "DISPLAY" };
+        String[] wpsEntries = {"Default", "PBC", "KEYPAD", "DISPLAY"};
         String[] wpsValues = {
-            "" + WpsInfo.INVALID,
-            "" + WpsInfo.PBC,
-            "" + WpsInfo.KEYPAD,
-            "" + WpsInfo.DISPLAY };
+                "" + WpsInfo.INVALID,
+                "" + WpsInfo.PBC,
+                "" + WpsInfo.KEYPAD,
+                "" + WpsInfo.DISPLAY};
         lp.setKey("wps");
         lp.setTitle(R.string.wifi_display_wps_config);
         lp.setEntries(wpsEntries);
@@ -430,8 +435,8 @@
                 return true;
             }
         });
-        String[] lcEntries = { "Auto", "1", "6", "11" };
-        String[] lcValues = { "0", "1", "6", "11" };
+        String[] lcEntries = {"Auto", "1", "6", "11"};
+        String[] lcValues = {"0", "1", "6", "11"};
         lp.setKey("listening_channel");
         lp.setTitle(R.string.wifi_display_listen_channel);
         lp.setEntries(lcEntries);
@@ -454,8 +459,8 @@
                 return true;
             }
         });
-        String[] ocEntries = { "Auto", "1", "6", "11", "36" };
-        String[] ocValues = { "0", "1", "6", "11", "36" };
+        String[] ocEntries = {"Auto", "1", "6", "11", "36"};
+        String[] ocValues = {"0", "1", "6", "11", "36"};
         lp.setKey("operating_channel");
         lp.setTitle(R.string.wifi_display_operating_channel);
         lp.setEntries(ocEntries);
@@ -512,14 +517,14 @@
             public void onSuccess() {
                 if (DEBUG) {
                     Slog.d(TAG, "Successfully " + (enable ? "entered" : "exited")
-                            +" listen mode.");
+                            + " listen mode.");
                 }
             }
 
             @Override
             public void onFailure(int reason) {
                 Slog.e(TAG, "Failed to " + (enable ? "entered" : "exited")
-                        +" listen mode with reason " + reason + ".");
+                        + " listen mode with reason " + reason + ".");
             }
         });
     }
@@ -530,18 +535,18 @@
         }
         mWifiP2pManager.setWifiP2pChannels(mWifiP2pChannel,
                 lc, oc, new ActionListener() {
-            @Override
-            public void onSuccess() {
-                if (DEBUG) {
-                    Slog.d(TAG, "Successfully set wifi p2p channels.");
-                }
-            }
+                    @Override
+                    public void onSuccess() {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Successfully set wifi p2p channels.");
+                        }
+                    }
 
-            @Override
-            public void onFailure(int reason) {
-                Slog.e(TAG, "Failed to set wifi p2p channels with reason " + reason + ".");
-            }
-        });
+                    @Override
+                    public void onFailure(int reason) {
+                        Slog.e(TAG, "Failed to set wifi p2p channels with reason " + reason + ".");
+                    }
+                });
     }
 
     private void toggleRoute(MediaRouter.RouteInfo route) {
@@ -561,7 +566,7 @@
 
     private void showWifiDisplayOptionsDialog(final WifiDisplay display) {
         View view = getActivity().getLayoutInflater().inflate(R.layout.wifi_display_options, null);
-        final EditText nameEditText = (EditText)view.findViewById(R.id.name);
+        final EditText nameEditText = (EditText) view.findViewById(R.id.name);
         nameEditText.setText(display.getFriendlyDisplayName());
 
         DialogInterface.OnClickListener done = new DialogInterface.OnClickListener() {
@@ -707,7 +712,7 @@
                     TypedValue value = new TypedValue();
                     getContext().getTheme().resolveAttribute(android.R.attr.disabledAlpha,
                             value, true);
-                    deviceDetails.setImageAlpha((int)(value.getFloat() * 255));
+                    deviceDetails.setImageAlpha((int) (value.getFloat() * 255));
                     deviceDetails.setEnabled(true); // always allow button to be pressed
                 }
             }
diff --git a/tests/robotests/src/com/android/settings/applications/assist/GestureAssistPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/assist/GestureAssistPreferenceControllerTest.java
deleted file mode 100644
index 624a01f..0000000
--- a/tests/robotests/src/com/android/settings/applications/assist/GestureAssistPreferenceControllerTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.applications.assist;
-
-import android.content.Context;
-
-import com.android.settings.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.FakeFeatureFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.when;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class GestureAssistPreferenceControllerTest {
-
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Context mContext;
-    private FakeFeatureFactory mFeatureFactory;
-    private GestureAssistPreferenceController mController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        FakeFeatureFactory.setupForTest(mContext);
-        mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
-        mController = new GestureAssistPreferenceController(mContext);
-    }
-
-    @Test
-    public void isAvailable_shouldReturnFeatureProviderValue() {
-        when(mFeatureFactory.assistGestureFeatureProvider.isSupported(any(Context.class)))
-                .thenReturn(true);
-        assertThat(mController.isAvailable()).isTrue();
-
-        when(mFeatureFactory.assistGestureFeatureProvider.isSupported(any(Context.class)))
-                .thenReturn(false);
-        assertThat(mController.isAvailable()).isFalse();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
new file mode 100644
index 0000000..5915118
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+
+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.annotation.Config;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BluetoothDevicePreferenceTest {
+
+    private Context mContext;
+    @Mock
+    private CachedBluetoothDevice mCachedBluetoothDevice;
+
+    private FakeFeatureFactory mFakeFeatureFactory;
+    private MetricsFeatureProvider mMetricsFeatureProvider;
+    private BluetoothDevicePreference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application.getApplicationContext());
+        FakeFeatureFactory.setupForTest(mContext);
+        mFakeFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+        mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
+        mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice);
+    }
+
+    @Test
+    public void onClicked_deviceConnected_shouldLogBluetoothDisconnectEvent() {
+        when(mCachedBluetoothDevice.isConnected()).thenReturn(true);
+
+        mPreference.onClicked();
+
+        verify(mMetricsFeatureProvider).action(
+            mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_DISCONNECT);
+    }
+
+    @Test
+    public void onClicked_deviceBonded_shouldLogBluetoothConnectEvent() {
+        when(mCachedBluetoothDevice.isConnected()).thenReturn(false);
+        when(mCachedBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+
+        mPreference.onClicked();
+
+        verify(mMetricsFeatureProvider).action(
+            mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT);
+    }
+
+    @Test
+    public void onClicked_deviceNotBonded_shouldLogBluetoothPairEvent() {
+        when(mCachedBluetoothDevice.isConnected()).thenReturn(false);
+        when(mCachedBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+        when(mCachedBluetoothDevice.startPairing()).thenReturn(true);
+
+        mPreference.onClicked();
+
+        verify(mMetricsFeatureProvider).action(
+            mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
new file mode 100644
index 0000000..7761afc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.bluetooth;
+
+import android.content.Context;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.widget.MasterSwitchController;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BluetoothEnablerTest {
+
+    @Mock
+    private MetricsFeatureProvider mMetricsFeatureProvider;
+    @Mock
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void onSwitchToggled_shouldLogActionWithSuppliedEvent() {
+        BluetoothEnabler bluetoothEnabler = new BluetoothEnabler(mContext,
+            mock(MasterSwitchController.class), mMetricsFeatureProvider,
+            mock(LocalBluetoothManager.class), 123);
+        bluetoothEnabler.onSwitchToggled(false);
+
+        verify(mMetricsFeatureProvider).action(mContext, 123, false);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
new file mode 100644
index 0000000..5f4b101
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.bluetooth;
+
+import android.content.Context;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class UtilsTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+    @Mock
+    private LocalBluetoothManager mLocalBluetoothManager;
+
+    private FakeFeatureFactory mFakeFeatureFactory;
+    private MetricsFeatureProvider mMetricsFeatureProvider;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        FakeFeatureFactory.setupForTest(mContext);
+        mFakeFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+        mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
+    }
+
+    @Test
+    public void showConnectingError_shouldLogBluetoothConnectError() {
+        when(mContext.getString(anyInt(), anyString())).thenReturn("testMessage");
+        Utils.showConnectingError(mContext, "testName", mock(LocalBluetoothManager.class));
+
+        verify(mMetricsFeatureProvider).visible(eq(mContext), anyInt(),
+            eq(MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT_ERROR));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/core/DynamicAvailabilityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/DynamicAvailabilityPreferenceControllerTest.java
new file mode 100644
index 0000000..38a8356
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/core/DynamicAvailabilityPreferenceControllerTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.core;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.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.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for {@link DynamicAvailabilityPreferenceController}.
+ */
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public final class DynamicAvailabilityPreferenceControllerTest {
+
+    private final String PREFERENCE_KEY = "preference_key";
+
+    private @Mock Context mContext;
+    private @Mock Preference mPreference;
+    private @Mock PreferenceScreen mScreen;
+    private @Mock Lifecycle mLifecycle;
+
+    private boolean mIsAvailable;
+    private Preference mUpdatedPreference = null;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mPreference.getKey()).thenReturn(PREFERENCE_KEY);
+        when(mScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);
+        when(mScreen.getPreferenceCount()).thenReturn(1);
+        when(mScreen.getPreference(0)).thenReturn(mPreference);
+    }
+
+    @Test
+    public void testAvailableToUnavailable() {
+        mIsAvailable = true;
+
+        final DynamicAvailabilityPreferenceController controller
+                = new DynamicAvailabilityPreferenceControllerTestable(mLifecycle);
+        verify(mLifecycle).addObserver(controller);
+
+        controller.displayPreference(mScreen);
+        verify(mScreen, never()).removePreference(mPreference);
+        verify(mScreen, never()).addPreference(mPreference);
+        assertThat(mUpdatedPreference).isNull();
+
+        controller.onResume();
+        verify(mScreen, never()).removePreference(mPreference);
+        verify(mScreen, never()).addPreference(mPreference);
+        assertThat(mUpdatedPreference).isEqualTo(mPreference);
+
+        mUpdatedPreference = null;
+        mIsAvailable = false;
+        controller.onResume();
+        verify(mScreen).removePreference(mPreference);
+        verify(mScreen, never()).addPreference(mPreference);
+        assertThat(mUpdatedPreference).isNull();
+    }
+
+    @Test
+    public void testUnavailableToAvailable() {
+        mIsAvailable = false;
+
+        final DynamicAvailabilityPreferenceController controller
+                = new DynamicAvailabilityPreferenceControllerTestable(mLifecycle);
+        verify(mLifecycle).addObserver(controller);
+
+        controller.displayPreference(mScreen);
+        verify(mScreen).removePreference(mPreference);
+        verify(mScreen, never()).addPreference(mPreference);
+        assertThat(mUpdatedPreference).isNull();
+
+        reset(mScreen);
+        controller.onResume();
+        verify(mScreen, never()).removePreference(mPreference);
+        verify(mScreen, never()).addPreference(mPreference);
+        assertThat(mUpdatedPreference).isNull();
+
+        mIsAvailable = true;
+        controller.onResume();
+        verify(mScreen, never()).removePreference(mPreference);
+        verify(mScreen).addPreference(mPreference);
+        assertThat(mUpdatedPreference).isEqualTo(mPreference);
+    }
+
+
+    private class DynamicAvailabilityPreferenceControllerTestable
+            extends DynamicAvailabilityPreferenceController {
+        public DynamicAvailabilityPreferenceControllerTestable(Lifecycle lifecycle) {
+            super(DynamicAvailabilityPreferenceControllerTest.this.mContext, lifecycle);
+        }
+
+        @Override
+        public boolean isAvailable() {
+            return mIsAvailable;
+        }
+
+        @Override
+        public void updateState(Preference preference) {
+            mUpdatedPreference = preference;
+        }
+
+        @Override
+        public String getPreferenceKey() {
+            return PREFERENCE_KEY;
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java
deleted file mode 100644
index 14c6d72..0000000
--- a/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.deviceinfo;
-
-
-import android.content.Context;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class ManageStoragePreferenceControllerTest {
-
-
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Context mContext;
-    @Mock(answer = RETURNS_DEEP_STUBS)
-    private PreferenceScreen mScreen;
-
-    private ManageStoragePreferenceController mController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mController = new ManageStoragePreferenceController(mContext);
-    }
-
-    @Test
-    public void updateNonIndexableKey_prefUnavaiable_shouldUpdate() {
-        final List<String> keys = new ArrayList<>();
-        mController.updateNonIndexableKeys(keys);
-
-        assertThat(keys).isNotEmpty();
-    }
-
-    @Test
-    public void updateNonIndexableKey_prefAvaiable_shouldNotUpdate() {
-        final List<String> keys = new ArrayList<>();
-        when(mContext.getResources().getBoolean(
-                com.android.settings.R.bool.config_storage_manager_settings_enabled))
-                .thenReturn(true);
-
-        mController.updateNonIndexableKeys(keys);
-
-        assertThat(keys).isEmpty();
-    }
-
-    @Test
-    public void displayPref_prefAvaiable_shouldDisplay() {
-        when(mContext.getResources().getBoolean(
-                com.android.settings.R.bool.config_storage_manager_settings_enabled))
-                .thenReturn(true);
-
-        mController.displayPreference(mScreen);
-
-        verify(mScreen, never()).removePreference(any(Preference.class));
-    }
-
-    @Test
-    public void displayPref_prefNotAvaiable_shouldNotDisplay() {
-        final Preference preference = mock(Preference.class);
-        when(mScreen.getPreferenceCount()).thenReturn(1);
-        when(mScreen.getPreference(0)).thenReturn(preference);
-        when(preference.getKey()).thenReturn(mController.getPreferenceKey());
-
-        mController.displayPreference(mScreen);
-
-        verify(mScreen).removePreference(any(Preference.class));
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
new file mode 100644
index 0000000..ee8e7d1
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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.deviceinfo.storage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.deletionhelper.ActivationWarningFragment;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
+import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settings.overlay.FeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AutomaticStorageManagementSwitchPreferenceControllerTest {
+
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private MasterSwitchPreference mPreference;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mMockContext;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private FragmentManager mFragmentManager;
+
+    private Context mContext;
+    private AutomaticStorageManagementSwitchPreferenceController mController;
+    private MetricsFeatureProvider mMetricsFeature;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application.getApplicationContext();
+        FeatureFactory factory = FeatureFactory.getFactory(mContext);
+        mMetricsFeature = factory.getMetricsFeatureProvider();
+
+        mController = new AutomaticStorageManagementSwitchPreferenceController(
+                mContext, mMetricsFeature, mFragmentManager);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+    }
+
+    @Test
+    public void isAvailable_shouldAlwaysReturnTrue() {
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void onResume_shouldReflectEnabledStatus() {
+        mController.displayPreference(mScreen);
+        ContentResolver resolver = mContext.getContentResolver();
+        Settings.Secure.putInt(resolver, Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 1);
+
+        mController.onResume();
+
+        verify(mPreference).setChecked(eq(true));
+    }
+
+    @Test
+    public void onResume_shouldRegisterCallback() {
+        mController.displayPreference(mScreen);
+        mController.onResume();
+
+        verify(mPreference).setOnPreferenceChangeListener(
+                any(Preference.OnPreferenceChangeListener.class));
+    }
+
+    @Test
+    public void togglingShouldCauseMetricsEvent() {
+        // FakeFeatureFactory uses mock contexts, so this test scaffolds itself rather than using
+        // the instance variables.
+        FakeFeatureFactory.setupForTest(mMockContext);
+        FakeFeatureFactory factory =
+                (FakeFeatureFactory) FakeFeatureFactory.getFactory(mMockContext);
+        AutomaticStorageManagementSwitchPreferenceController controller =
+                new AutomaticStorageManagementSwitchPreferenceController(
+                        mMockContext, factory.metricsFeatureProvider, mFragmentManager);
+
+        controller.onSwitchToggled(true);
+
+        verify(factory.metricsFeatureProvider, times(1)).action(
+                any(Context.class), eq(MetricsEvent.ACTION_TOGGLE_STORAGE_MANAGER), eq(true));
+    }
+
+    @Test
+    public void togglingShouldUpdateSettingsSecure() {
+        mController.onSwitchToggled(true);
+
+        ContentResolver resolver = mContext.getContentResolver();
+        assertThat(Settings.Secure.getInt(
+                resolver, Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0)).isNotEqualTo(0);
+    }
+
+    @Test
+    public void togglingOnShouldTriggerWarningFragment() {
+        FragmentTransaction transaction = mock(FragmentTransaction.class);
+        when (mFragmentManager.beginTransaction()).thenReturn(transaction);
+
+        mController.onSwitchToggled(true);
+
+        verify(transaction).add(any(), eq(ActivationWarningFragment.TAG));
+    }
+
+    @Test
+    public void togglingOffShouldTriggerWarningFragment() {
+        FragmentTransaction transaction = mock(FragmentTransaction.class);
+        when (mFragmentManager.beginTransaction()).thenReturn(transaction);
+
+        mController.onSwitchToggled(false);
+
+        verify(transaction, never()).add(any(), eq(ActivationWarningFragment.TAG));
+    }
+
+
+    @Config(shadows = {SettingsShadowSystemProperties.class})
+    @Test
+    public void togglingOnShouldNotTriggerWarningFragmentIfEnabledByDefault() {
+        FragmentTransaction transaction = mock(FragmentTransaction.class);
+        when (mFragmentManager.beginTransaction()).thenReturn(transaction);
+        SettingsShadowSystemProperties.set(
+                AutomaticStorageManagementSwitchPreferenceController
+                        .STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY, "true");
+
+        mController.onSwitchToggled(true);
+
+        verify(transaction, never()).add(any(), eq(ActivationWarningFragment.TAG));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
index c12e515..cbf3414 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
@@ -114,13 +114,6 @@
     }
 
     @Test
-    public void testAutomaticStorageManagerLabelOff() throws Exception {
-        mPreference.onBindViewHolder(mHolder);
-        TextView asmTextView = (TextView) mHolder.findViewById(R.id.storage_manager_indicator);
-        assertThat(asmTextView.getText().toString()).isEqualTo("Storage Manager: OFF");
-    }
-
-    @Test
     public void testFreeUpSpaceMetricIsTriggered() throws Exception {
         mPreference.onBindViewHolder(mHolder);
         Button button = (Button) mHolder.findViewById(R.id.deletion_helper_button);
@@ -130,15 +123,4 @@
         verify(mMetricsFeatureProvider, times(1)).action(
                 any(Context.class), eq(MetricsEvent.STORAGE_FREE_UP_SPACE_NOW));
     }
-
-    @Test
-    public void testAutomaticStorageManagerLabelOn() throws Exception {
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 1);
-
-        mPreference.onBindViewHolder(mHolder);
-
-        TextView asmTextView = (TextView) mHolder.findViewById(R.id.storage_manager_indicator);
-        assertThat(asmTextView.getText().toString()).isEqualTo("Storage Manager: ON");
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceControllerTest.java
new file mode 100644
index 0000000..229ef49
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceControllerTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.gestures;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import com.android.settings.search2.InlineSwitchPayload;
+import com.android.settings.search2.ResultPayload;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.provider.Settings.Secure.ASSIST_GESTURE_ENABLED;
+import static android.provider.Settings.Secure.ASSIST_GESTURE_SENSITIVITY;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AssistGestureSensitivityPreferenceControllerTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+    private FakeFeatureFactory mFactory;
+    private AssistGestureSensitivityPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        FakeFeatureFactory.setupForTest(mContext);
+        mFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+        mController = new AssistGestureSensitivityPreferenceController(mContext, null);
+    }
+
+    @Test
+    public void isAvailable_whenSupportedAndEnabled_shouldReturnTrue() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ASSIST_GESTURE_ENABLED, 1);
+        when(mFactory.assistGestureFeatureProvider.isSupported(mContext)).thenReturn(true);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_whenSupportedAndDisabled_shouldReturnFalse() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ASSIST_GESTURE_ENABLED, 0);
+        when(mFactory.assistGestureFeatureProvider.isSupported(mContext)).thenReturn(true);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_whenUnsupportedAndEnabled_shouldReturnFalse() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ASSIST_GESTURE_ENABLED, 1);
+        when(mFactory.assistGestureFeatureProvider.isSupported(mContext)).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_whenUnsupportedAndDisabled_shouldReturnFalse() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ASSIST_GESTURE_ENABLED, 0);
+        when(mFactory.assistGestureFeatureProvider.isSupported(mContext)).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+}
+
diff --git a/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java
index acfd400..13abd97 100644
--- a/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java
@@ -17,11 +17,10 @@
 package com.android.settings.notification;
 
 import android.content.Context;
-import android.os.Build.VERSION_CODES;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
+import android.support.v7.preference.PreferenceCategory;
 import android.support.v7.preference.PreferenceScreen;
 import android.support.v7.preference.TwoStatePreference;
 import android.telephony.TelephonyManager;
@@ -36,17 +35,15 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
 import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -65,6 +62,8 @@
     @Mock
     private PreferenceScreen mScreen;
     @Mock
+    private PreferenceCategory mWorkCategory;
+    @Mock
     private TelephonyManager mTelephonyManager;
     @Mock
     private AudioHelper mAudioHelper;
@@ -78,6 +77,17 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
         when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+        when(mScreen.findPreference(KEY_WORK_CATEGORY))
+                .thenReturn(mWorkCategory);
+        when(mWorkCategory.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS))
+                .thenReturn(mock(TwoStatePreference.class));
+        when(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE))
+                .thenReturn(mock(DefaultRingtonePreference.class));
+        when(mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
+                .thenReturn(mock(DefaultRingtonePreference.class));
+        when(mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE))
+                .thenReturn(mock(DefaultRingtonePreference.class));
+
         mController = new WorkSoundPreferenceController(mContext, mFragment, null, mAudioHelper);
     }
 
@@ -112,45 +122,30 @@
     }
 
     @Test
-    public void onResume_available_shouldAddPreferenceCategory() {
-        when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
-                .thenReturn(UserHandle.myUserId());
-        when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(true);
-        when(mAudioHelper.isSingleVolume()).thenReturn(false);
-        when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
-        when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
-        mockWorkCategory();
-
-        mController.onResume();
-
-        verify(mFragment).addPreferencesFromResource(R.xml.sound_work_settings);
-    }
-
-    @Test
-    public void onManagedProfileAdded_shouldAddPreferenceCategory() {
+    public void onManagedProfileAdded_shouldDisplayPreferenceCategory() {
         // Given a device without any managed profiles:
         when(mAudioHelper.isSingleVolume()).thenReturn(false);
         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
         when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
                 .thenReturn(UserHandle.USER_NULL);
-        mockWorkCategory();
 
-        // When the fragment first resumes, the category should not appear.
+        // When the fragment first displays, the category should not appear.
+        mController.displayPreference(mScreen);
+        verify(mWorkCategory).setVisible(false);
+
+
+        // However, when a managed profile is added later, the category should appear.
         mController.onResume();
-
-        verify(mFragment, never()).addPreferencesFromResource(R.xml.sound_work_settings);
-
-        // However, when a managed profile is added after resuming, the category should appear.
         when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
                 .thenReturn(UserHandle.myUserId());
         mController.onManagedProfileAdded(UserHandle.myUserId());
 
-        verify(mFragment).addPreferencesFromResource(R.xml.sound_work_settings);
+        verify(mWorkCategory).setVisible(true);
     }
 
     @Test
-    public void onManagedProfileRemoved_shouldRemovePreferenceCategory() {
+    public void onManagedProfileRemoved_shouldHidePreferenceCategory() {
         // Given a device with a managed profile:
         when(mAudioHelper.isSingleVolume()).thenReturn(false);
         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
@@ -158,29 +153,44 @@
         when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
                 .thenReturn(UserHandle.myUserId());
         when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(true);
-        mockWorkCategory();
 
         // Which is in resumed state:
+        mController.displayPreference(mScreen);
         mController.onResume();
 
-        // When a managed profile is removed, the category should be removed.
+        verify(mWorkCategory, times(2)).setVisible(true);
+
+        // When a managed profile is removed, the category should be hidden.
         when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
                 .thenReturn(UserHandle.USER_NULL);
         mController.onManagedProfileRemoved(UserHandle.myUserId());
 
-        verify(mScreen).removePreference(mScreen.findPreference(KEY_WORK_CATEGORY));
+        verify(mWorkCategory).setVisible(false);
+    }
+
+
+    @Test
+    public void displayPreference_isAvailable_shouldShowPreferenceCategory() {
+        when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
+                .thenReturn(UserHandle.myUserId());
+        when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(true);
+        when(mAudioHelper.isSingleVolume()).thenReturn(false);
+        when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
+        when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
+
+        mController.displayPreference(mScreen);
+        verify(mWorkCategory).setVisible(true);
     }
 
     @Test
-    public void onResume_notAvailable_shouldNotAddPreferenceCategory() {
+    public void displayPreference_notAvailable_shouldHidePreferenceCategory() {
         when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
-            .thenReturn(UserHandle.USER_NULL);
+                .thenReturn(UserHandle.USER_NULL);
         when(mAudioHelper.isSingleVolume()).thenReturn(true);
         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
 
-        mController.onResume();
-
-        verify(mFragment, never()).addPreferencesFromResource(anyInt());
+        mController.displayPreference(mScreen);
+        verify(mWorkCategory).setVisible(false);
     }
 
     @Test
@@ -206,27 +216,19 @@
         when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
                 .thenReturn(UserHandle.myUserId());
         when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(false);
-        mockWorkCategory();
 
         // When resumed:
+        mController.displayPreference(mScreen);
         mController.onResume();
 
-        // Sound preferences should explain that the profile isn't available yet.
-        verify(mScreen.findPreference(KEY_WORK_PHONE_RINGTONE)).setSummary(eq(notAvailable));
-        verify(mScreen.findPreference(KEY_WORK_NOTIFICATION_RINGTONE)).setSummary(eq(notAvailable));
-        verify(mScreen.findPreference(KEY_WORK_ALARM_RINGTONE)).setSummary(eq(notAvailable));
-    }
+        verify(mWorkCategory, times(2)).setVisible(true);
 
-    private void mockWorkCategory() {
-        when(mScreen.findPreference(KEY_WORK_CATEGORY))
-            .thenReturn(mock(PreferenceGroup.class));
-        when(mScreen.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS))
-            .thenReturn(mock(TwoStatePreference.class));
-        when(mScreen.findPreference(KEY_WORK_PHONE_RINGTONE))
-            .thenReturn(mock(DefaultRingtonePreference.class));
-        when(mScreen.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
-            .thenReturn(mock(DefaultRingtonePreference.class));
-        when(mScreen.findPreference(KEY_WORK_ALARM_RINGTONE))
-            .thenReturn(mock(DefaultRingtonePreference.class));
+        // Sound preferences should explain that the profile isn't available yet.
+        verify(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE))
+                .setSummary(eq(notAvailable));
+        verify(mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
+                .setSummary(eq(notAvailable));
+        verify(mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE))
+                .setSummary(eq(notAvailable));
     }
 }
diff --git a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
index c58ce37..728e357 100644
--- a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
+++ b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
@@ -19,6 +19,7 @@
 import static android.provider.Settings.ACTION_WEBVIEW_SETTINGS;
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -33,9 +34,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.os.UserManager;
-import android.support.v7.preference.PreferenceManager;
 
 import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
@@ -325,4 +328,30 @@
         assertThat(mPicker.getDisabledReason(wvusWrapper, mContext,
                 DEFAULT_PACKAGE_NAME)).isEqualTo(EXPECTED_DISABLED_REASON);
     }
+
+    /**
+     * Ensure that the version name of a WebView package is displayed after its name in the
+     * preference title.
+     */
+    @Test
+    public void testWebViewVersionAddedAfterLabel() throws PackageManager.NameNotFoundException {
+        PackageItemInfo mockPackageItemInfo = mock(PackageItemInfo.class);
+        mockPackageItemInfo.packageName = DEFAULT_PACKAGE_NAME;
+        when(mockPackageItemInfo.loadLabel(any())).thenReturn("myPackage");
+        DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(
+                mockPackageItemInfo, "" /* disabledReason */);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.versionName = "myVersionName";
+        PackageManager pm = mock(PackageManager.class);
+        when(pm.getPackageInfo(eq(DEFAULT_PACKAGE_NAME), anyInt())).thenReturn(packageInfo);
+        when(mPackageManager.getPackageManager()).thenReturn(pm);
+
+        RadioButtonPreference mockPreference = mock(RadioButtonPreference.class);
+        mPicker.configurePreferenceFromAppInfo(mockPreference,
+                DEFAULT_PACKAGE_NAME, webviewAppInfo, null, null);
+
+        verify(mockPreference, times(1)).setTitle(eq("myPackage myVersionName"));
+        verify(mockPreference, times(1)).setTitle(any());
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java b/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java
index c412d55..de097fc 100644
--- a/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java
@@ -18,7 +18,9 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.hardware.display.DisplayManager;
 import android.media.MediaRouter;
+import android.net.wifi.p2p.WifiP2pManager;
 
 import com.android.settings.R;
 import com.android.settings.SettingsRobolectricTestRunner;
@@ -32,6 +34,7 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.annotation.Config;
 
+import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -82,4 +85,22 @@
         verify(mActivity).getString(R.string.wifi_display_status_connected);
     }
 
+    @Test
+    public void isAvailable_noService_shouldReturnFalse() {
+        assertThat(WifiDisplaySettings.isAvailable(mActivity))
+                .isFalse();
+
+    }
+
+    @Test
+    public void isAvailable_hasService_shouldReturnTrue() {
+        when(mActivity.getSystemService(Context.DISPLAY_SERVICE))
+                .thenReturn(mock(DisplayManager.class));
+        when(mActivity.getSystemService(Context.WIFI_P2P_SERVICE))
+                .thenReturn(mock(WifiP2pManager.class));
+
+        assertThat(WifiDisplaySettings.isAvailable(mActivity))
+                .isTrue();
+    }
+
 }