Merge "WebView implementation Dev setting: Show the version number after name"
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/strings.xml b/res/values/strings.xml
index e7a0535..d64018d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8071,6 +8071,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>
@@ -8242,7 +8245,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>
@@ -8251,18 +8254,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>
 
@@ -8291,4 +8282,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/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/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/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/system/FactoryResetPreferenceController.java b/src/com/android/settings/system/FactoryResetPreferenceController.java
new file mode 100644
index 0000000..95a9e54
--- /dev/null
+++ b/src/com/android/settings/system/FactoryResetPreferenceController.java
@@ -0,0 +1,46 @@
+/*
+ * 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.system;
+
+import android.content.Context;
+
+import android.os.UserManager;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceController;
+
+public class FactoryResetPreferenceController extends PreferenceController {
+    /** Key of the "Factory reset" preference in {@link R.xml.system_dashboard_fragment}.*/
+    private static final String KEY_FACTORY_RESET = "factory_reset";
+
+    private final UserManager mUm;
+
+    public FactoryResetPreferenceController(Context context, UserManager um) {
+        super(context);
+        mUm = um;
+    }
+
+    /** Hide "Factory reset" settings for secondary users. */
+    @Override
+    public boolean isAvailable() {
+        return mUm.isAdminUser();
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_FACTORY_RESET;
+    }
+}
diff --git a/src/com/android/settings/system/SystemDashboardFragment.java b/src/com/android/settings/system/SystemDashboardFragment.java
index 76ac4a6..d4c63c2 100644
--- a/src/com/android/settings/system/SystemDashboardFragment.java
+++ b/src/com/android/settings/system/SystemDashboardFragment.java
@@ -60,6 +60,7 @@
         final List<PreferenceController> controllers = new ArrayList<>();
         controllers.add(new SystemUpdatePreferenceController(context, UserManager.get(context)));
         controllers.add(new AdditionalSystemUpdatePreferenceController(context));
+        controllers.add(new FactoryResetPreferenceController(context, UserManager.get(context)));
         return controllers;
     }
 
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/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/system/FactoryResetPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java
new file mode 100644
index 0000000..f41870e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.system;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+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;
+
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class FactoryResetPreferenceControllerTest {
+
+    private static final String FACTORY_RESET_KEY = "factory_reset";
+
+    @Mock(answer = RETURNS_DEEP_STUBS)
+    private Context mContext;
+    @Mock
+    private UserManager mUserManager;
+
+    private FactoryResetPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mController = new FactoryResetPreferenceController(mContext, mUserManager);
+    }
+
+    @Test
+    public void isAvailable_systemUser() {
+        when(mUserManager.isAdminUser()).thenReturn(true);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_nonSystemUser() {
+        when(mUserManager.isAdminUser()).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test public void getPreferenceKey() {
+        assertThat(mController.getPreferenceKey()).isEqualTo(FACTORY_RESET_KEY);
+    }
+}
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();
+    }
+
 }
diff --git a/tests/unit/src/com/android/settings/vpn2/PreferenceListTest.java b/tests/unit/src/com/android/settings/vpn2/PreferenceListTest.java
index 40958ba..4a62011 100644
--- a/tests/unit/src/com/android/settings/vpn2/PreferenceListTest.java
+++ b/tests/unit/src/com/android/settings/vpn2/PreferenceListTest.java
@@ -37,9 +37,9 @@
 import java.util.Map;
 
 import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.compat.ArgumentMatcher;
 
 public class PreferenceListTest extends AndroidTestCase {
     private static final String TAG = "PreferenceListTest";
@@ -138,7 +138,7 @@
 
         final ArgumentMatcher<VpnProfile> equalsFake = new ArgumentMatcher<VpnProfile>() {
             @Override
-            public boolean matches(final Object arg) {
+            public boolean matchesObject(final Object arg) {
                 if (arg == vpnProfile) return true;
                 if (arg == null) return false;
                 return TextUtils.equals(((VpnProfile) arg).key, vpnProfile.key);