Merge "Add a new widget MasterCheckBoxPreference."
diff --git a/res/layout/preference_category_no_title.xml b/res/layout/preference_category_no_title.xml
index 136ec6d..d4704bd 100644
--- a/res/layout/preference_category_no_title.xml
+++ b/res/layout/preference_category_no_title.xml
@@ -18,7 +18,7 @@
      set height to 0. This will be used in preference category without title in order to remove
      extra 32dp blank -->
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+android:id/title"
+    android:id="@android:id/title"
     android:layout_width="match_parent"
     android:layout_height="0dp"
     android:textAppearance="@android:style/TextAppearance.Material.Body2"
diff --git a/res/values/bools.xml b/res/values/bools.xml
index c28b968..6df9d6c 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -57,9 +57,27 @@
     <!-- Whether location mode is available or not. -->
     <bool name="config_location_mode_available">true</bool>
 
+    <!-- Whether high_power_apps should be shown or not. -->
+    <bool name="config_show_high_power_apps">true</bool>
+
+    <!-- Whether device_administrators should be shown or not. -->
+    <bool name="config_show_device_administrators">true</bool>
+
+    <!-- Whether premium_sms should be shown or not. -->
+    <bool name="config_show_premium_sms">true</bool>
+
+    <!-- Whether data_saver should be shown or not. -->
+    <bool name="config_show_data_saver">true</bool>
+
+    <!-- Whether enabled_vr_listeners should be shown or not. -->
+    <bool name="config_show_enabled_vr_listeners">true</bool>
+
     <!-- Whether wallpaper attribution should be shown or not. -->
     <bool name="config_show_wallpaper_attribution">true</bool>
 
     <!-- Whether default_home should be shown or not. -->
     <bool name="config_show_default_home">true</bool>
+
+    <!-- Whether accessibility shortcut preference should be shown or not. -->
+    <bool name="config_show_accessibility_shortcut_preference">true</bool>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3dc342b..5c1fd98 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -396,6 +396,11 @@
     <!-- Summary for bluetooth item in connection detail page -->
     <string name="bluetooth_pref_summary">Allow device to pair and connect to bluetooth devices</string>
 
+    <!-- Setting Checkbox title for disabling Bluetooth inband ringing in Development Settings -->
+    <string name="bluetooth_disable_inband_ringing">Disable in-band ringing</string>
+    <!-- Summary of checkbox for disabling Bluetooth inband ringing in Development Settings -->
+    <string name="bluetooth_disable_inband_ringing_summary">Don’t play custom phone ringtones on Bluetooth headsets</string>
+
     <!-- Title for connected device group [CHAR LIMIT=none]-->
     <string name="connected_device_connected_title">Currently connected</string>
     <!-- Title for connected device group [CHAR LIMIT=none]-->
@@ -3064,6 +3069,9 @@
 \n\nDon\u2019t remove the <xliff:g id="name" example="SD card">^2</xliff:g> during the move.
     </string>
 
+    <!-- Body of lock screen challenge message explaining that the given user must be unlocked before data can be moved [CHAR LIMIT=64] -->
+    <string name="storage_wizard_move_unlock">To move data you need to unlock user <xliff:g id="app" example="Joey">^1</xliff:g>.</string>
+
     <!-- Title of wizard step showing app move progress [CHAR LIMIT=32] -->
     <string name="storage_wizard_move_progress_title">Moving <xliff:g id="app" example="Calculator">^1</xliff:g>\u2026</string>
     <!-- Body of wizard step showing app move progress [CHAR LIMIT=NONE] -->
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 60efcab..18aeeef 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -240,9 +240,9 @@
             android:summary="@string/bluetooth_disable_absolute_volume_summary"/>
 
         <SwitchPreference
-            android:key="bluetooth_enable_inband_ringing"
-            android:title="@string/bluetooth_enable_inband_ringing"
-            android:summary="@string/bluetooth_enable_inband_ringing_summary"/>
+            android:key="bluetooth_disable_inband_ringing"
+            android:title="@string/bluetooth_disable_inband_ringing"
+            android:summary="@string/bluetooth_disable_inband_ringing_summary"/>
 
         <ListPreference
             android:key="bluetooth_select_avrcp_version"
diff --git a/res/xml/security_settings_v2.xml b/res/xml/security_settings_v2.xml
index 30e829d..86f542c 100644
--- a/res/xml/security_settings_v2.xml
+++ b/res/xml/security_settings_v2.xml
@@ -24,29 +24,71 @@
 
     <!-- security_settings_status.xml -->
     <PreferenceCategory
+        android:order="-10"
         android:key="security_status"
         android:title="@string/security_status_title" />
 
-    <!-- TODO Need security section -->
     <PreferenceCategory
+        android:order="1"
+        android:key="dashboard_tile_placeholder" />
+
+    <!-- security section -->
+    <PreferenceCategory
+        android:order="10"
         android:key="security_category"
         android:title="@string/lock_settings_title">
 
-        <!-- security_settings_chooser -->
         <com.android.settings.widget.GearPreference
             android:key="unlock_set_or_change"
             android:title="@string/unlock_set_unlock_launch_picker_title"
             android:summary="@string/unlock_set_unlock_mode_none"
             settings:keywords="@string/keywords_lockscreen" />
 
-        <Preference android:key="lockscreen_preferences"
-                    android:title="@string/lockscreen_settings_title"
-                    android:fragment="com.android.settings.security.LockscreenDashboardFragment"/>
+        <Preference
+            android:key="lockscreen_preferences"
+            android:title="@string/lockscreen_settings_title"
+            android:fragment="com.android.settings.security.LockscreenDashboardFragment" />
+
+        <Preference
+            android:key="fingerprint_settings"
+            android:title="@string/security_settings_fingerprint_preference_title"
+            android:summary="@string/summary_placeholder" />
+
+    </PreferenceCategory>
+
+    <!-- work profile security section -->
+    <PreferenceCategory
+        android:order="20"
+        android:key="security_category_profile"
+        android:title="@string/lock_settings_profile_title">
+
+        <!-- security_settings_unification -->
+        <com.android.settingslib.RestrictedSwitchPreference
+            android:key="unification"
+            android:title="@string/lock_settings_profile_unification_title"
+            android:summary="@string/lock_settings_profile_unification_summary"
+            settings:keywords="@string/keywords_unification" />
+
+        <com.android.settingslib.RestrictedPreference
+            android:key="unlock_set_or_change_profile"
+            android:title="@string/unlock_set_unlock_launch_picker_title_profile"
+            android:summary="@string/unlock_set_unlock_mode_pattern"
+            settings:keywords="@string/keywords_lockscreen" />
+
+        <SwitchPreference
+            android:key="visiblepattern_profile"
+            android:title="@string/lockpattern_settings_enable_visible_pattern_title_profile" />
+
+        <Preference
+            android:key="fingerprint_settings_profile"
+            android:title="@string/security_settings_fingerprint_preference_title"
+            android:summary="@string/summary_placeholder" />
 
     </PreferenceCategory>
 
     <!-- security_settings_misc.xml -->
     <PreferenceCategory
+        android:order="30"
         android:key="security_settings_misc_category"
         android:title="@string/security_passwords_title">
 
@@ -59,54 +101,64 @@
         <SwitchPreference
             android:key="show_password"
             android:title="@string/show_password"
-            android:summary="@string/show_password_summary"/>
+            android:summary="@string/show_password_summary" />
 
     </PreferenceCategory>
 
     <PreferenceCategory
+        android:order="40"
         android:key="security_settings_device_admin_category">
 
         <Preference android:key="manage_device_admin"
                     android:title="@string/manage_device_admin"
                     android:persistent="false"
-                    android:fragment="com.android.settings.DeviceAdminSettings"/>
+                    android:fragment="com.android.settings.DeviceAdminSettings" />
 
         <Preference android:key="enterprise_privacy"
                     android:title="@string/enterprise_privacy_settings"
                     android:persistent="false"
-                    android:fragment="com.android.settings.enterprise.EnterprisePrivacySettings"/>
+                    android:fragment="com.android.settings.enterprise.EnterprisePrivacySettings" />
 
     </PreferenceCategory>
 
-    <Preference android:key="sim_lock_settings"
-                android:title="@string/sim_lock_settings_category">
+    <Preference
+        android:order="50"
+        android:key="sim_lock_settings"
+        android:title="@string/sim_lock_settings_category">
 
-        <intent android:action="android.intent.action.MAIN"
-                android:targetPackage="com.android.settings"
-                android:targetClass="com.android.settings.Settings$IccLockSettingsActivity"/>
+        <intent
+            android:action="android.intent.action.MAIN"
+            android:targetPackage="com.android.settings"
+            android:targetClass="com.android.settings.Settings$IccLockSettingsActivity" />
 
     </Preference>
 
     <Preference
+        android:order="60"
         android:key="encryption_and_credential"
         android:title="@string/encryption_and_credential_settings_title"
         android:summary="@string/encryption_and_credential_settings_summary"
-        android:fragment="com.android.settings.security.EncryptionAndCredential"/>
-
-    <Preference android:key="manage_trust_agents"
-                android:title="@string/manage_trust_agents"
-                android:persistent="false"
-                android:fragment="com.android.settings.security.trustagent.TrustAgentSettings"/>
+        android:fragment="com.android.settings.security.EncryptionAndCredential" />
 
     <Preference
+        android:order="70"
+        android:key="manage_trust_agents"
+        android:title="@string/manage_trust_agents"
+        android:persistent="false"
+        android:fragment="com.android.settings.security.trustagent.TrustAgentSettings" />
+
+    <Preference
+        android:order="80"
         android:key="screen_pinning_settings"
         android:title="@string/screen_pinning_title"
         android:summary="@string/summary_placeholder"
-        android:fragment="com.android.settings.security.ScreenPinningSettings"/>
+        android:fragment="com.android.settings.security.ScreenPinningSettings" />
 
-    <Preference android:key="security_misc_usage_access"
-                android:title="@string/usage_access_title"
-                android:fragment="com.android.settings.applications.manageapplications.ManageApplications">
+    <Preference
+        android:order="90"
+        android:key="security_misc_usage_access"
+        android:title="@string/usage_access_title"
+        android:fragment="com.android.settings.applications.manageapplications.ManageApplications">
         <extra
             android:name="classname"
             android:value="com.android.settings.Settings$UsageAccessSettingsActivity" />
diff --git a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java b/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
index f5f3017..026032d 100644
--- a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
+++ b/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
@@ -67,7 +67,7 @@
 
         @Override
         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-            setPreviewLayer(progress, true);
+            setPreviewLayer(progress, false);
             if (!mSeekByTouch) {
                 commit();
             }
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index cab3139..6b0a5b8 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -106,6 +106,7 @@
 import com.android.internal.app.UnlaunchableAppActivity;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.password.ChooseLockSettingsHelper;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
 import com.android.settings.wrapper.FingerprintManagerWrapper;
 
@@ -995,20 +996,37 @@
     }
 
     /**
-     * Returns the user id present in the bundle with {@link Intent#EXTRA_USER_ID} if it
-     * belongs to the current user.
+     * Returns the user id present in the bundle with
+     * {@link Intent#EXTRA_USER_ID} if it belongs to the current user.
      *
-     * @throws SecurityException if the given userId does not belong to the current user group.
+     * @throws SecurityException if the given userId does not belong to the
+     *             current user group.
      */
     public static int getUserIdFromBundle(Context context, Bundle bundle) {
+        return getUserIdFromBundle(context, bundle, false);
+    }
+
+    /**
+     * Returns the user id present in the bundle with
+     * {@link Intent#EXTRA_USER_ID} if it belongs to the current user.
+     *
+     * @param isInternal indicating if the caller is "internal" to the system,
+     *            meaning we're willing to trust extras like
+     *            {@link ChooseLockSettingsHelper#EXTRA_ALLOW_ANY_USER}.
+     * @throws SecurityException if the given userId does not belong to the
+     *             current user group.
+     */
+    public static int getUserIdFromBundle(Context context, Bundle bundle, boolean isInternal) {
         if (bundle == null) {
             return getCredentialOwnerUserId(context);
         }
+        final boolean allowAnyUser = isInternal
+                && bundle.getBoolean(ChooseLockSettingsHelper.EXTRA_ALLOW_ANY_USER, false);
         int userId = bundle.getInt(Intent.EXTRA_USER_ID, UserHandle.myUserId());
         if (userId == LockPatternUtils.USER_FRP) {
-            return enforceSystemUser(context, userId);
+            return allowAnyUser ? userId : enforceSystemUser(context, userId);
         } else {
-            return enforceSameOwner(context, userId);
+            return allowAnyUser ? userId : enforceSameOwner(context, userId);
         }
     }
 
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 160176e..cc72280 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -30,6 +30,7 @@
 import android.os.UserHandle;
 import android.provider.SearchIndexableResource;
 import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
 import android.support.v14.preference.SwitchPreference;
 import android.support.v4.content.ContextCompat;
 import android.support.v7.preference.ListPreference;
@@ -102,8 +103,6 @@
             "toggle_master_mono";
     private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE =
             "select_long_press_timeout_preference";
-    private static final String ACCESSIBILITY_SHORTCUT_PREFERENCE =
-            "accessibility_shortcut_preference";
     private static final String CAPTIONING_PREFERENCE_SCREEN =
             "captioning_preference_screen";
     private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
@@ -117,6 +116,9 @@
     private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN =
             "daltonizer_preference_screen";
 
+    @VisibleForTesting static final String ACCESSIBILITY_SHORTCUT_PREFERENCE =
+            "accessibility_shortcut_preference";
+
     // Extras passed to sub-fragments.
     static final String EXTRA_PREFERENCE_KEY = "preference_key";
     static final String EXTRA_CHECKED = "checked";
@@ -452,6 +454,7 @@
 
         // Accessibility shortcut
         mAccessibilityShortcutPreferenceScreen = findPreference(ACCESSIBILITY_SHORTCUT_PREFERENCE);
+
     }
 
     private void updateAllPreferences() {
@@ -668,6 +671,7 @@
         updateAutoclickSummary(mAutoclickPreferenceScreen);
 
         updateAccessibilityShortcut(mAccessibilityShortcutPreferenceScreen);
+        checkAccessibilityShortcutVisibility(mAccessibilityShortcutPreferenceScreen);
     }
 
     private void updateMagnificationSummary(Preference pref) {
@@ -765,6 +769,13 @@
         }
     }
 
+    @VisibleForTesting void checkAccessibilityShortcutVisibility(Preference preference) {
+        if (!getContext().getResources().getBoolean(
+                R.bool.config_show_accessibility_shortcut_preference)) {
+            removePreference(ACCESSIBILITY_SHORTCUT_PREFERENCE);
+        }
+    }
+
     private static void configureMagnificationPreferenceIfNeeded(Preference preference) {
         // Some devices support only a single magnification mode. In these cases, we redirect to
         // the magnification mode's UI directly, rather than showing a PreferenceScreen with a
@@ -800,6 +811,12 @@
                     keys.add(FONT_SIZE_PREFERENCE_SCREEN);
                     keys.add(KEY_DISPLAY_SIZE);
 
+                    // Remove Accessibility Shortcuts if it's not visible
+                    if (!context.getResources().getBoolean(
+                            R.bool.config_show_accessibility_shortcut_preference)) {
+                        keys.add(ACCESSIBILITY_SHORTCUT_PREFERENCE);
+                    }
+
                     // Duplicates in Language & Input
                     keys.add(TTS_SETTINGS_PREFERENCE);
 
diff --git a/src/com/android/settings/applications/AppPermissionsPreferenceController.java b/src/com/android/settings/applications/AppPermissionsPreferenceController.java
index c8ff381..6100123 100644
--- a/src/com/android/settings/applications/AppPermissionsPreferenceController.java
+++ b/src/com/android/settings/applications/AppPermissionsPreferenceController.java
@@ -75,7 +75,8 @@
        The 3 permissions are the first three from the list which any app has granted:
        Location, Microphone, Camera, Sms, Contacts, and Phone
      */
-    private String getSummary() {
+    @Override
+    public String getSummary() {
         final Set<String> permissions = getAllPermissionsInGroups();
         Set<String> grantedPermissionGroups = getGrantedPermissionGroups(permissions);
         CharSequence summary = null;
diff --git a/src/com/android/settings/applications/DataSaverController.java b/src/com/android/settings/applications/DataSaverController.java
new file mode 100644
index 0000000..d9710fc
--- /dev/null
+++ b/src/com/android/settings/applications/DataSaverController.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.settings.applications;
+
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.R;
+
+public class DataSaverController extends BasePreferenceController {
+
+    @VisibleForTesting static final String KEY_DATA_SAVER = "data_saver";
+
+    public DataSaverController(Context context) {
+        super(context, KEY_DATA_SAVER);
+    }
+
+    @AvailabilityStatus
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_data_saver)
+                ? AVAILABLE
+                : DISABLED_UNSUPPORTED;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/DeviceAdministratorsController.java b/src/com/android/settings/applications/DeviceAdministratorsController.java
new file mode 100644
index 0000000..c7ef8ce
--- /dev/null
+++ b/src/com/android/settings/applications/DeviceAdministratorsController.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.R;
+
+public class DeviceAdministratorsController extends BasePreferenceController {
+
+    @VisibleForTesting static final String KEY_DEVICE_ADMIN = "device_administrators";
+
+    public DeviceAdministratorsController(Context context) {
+        super(context, KEY_DEVICE_ADMIN);
+    }
+
+    @AvailabilityStatus
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_device_administrators)
+                ? AVAILABLE
+                : DISABLED_UNSUPPORTED;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/EnabledVrListenersController.java b/src/com/android/settings/applications/EnabledVrListenersController.java
new file mode 100644
index 0000000..94a70ef
--- /dev/null
+++ b/src/com/android/settings/applications/EnabledVrListenersController.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.R;
+
+public class EnabledVrListenersController extends BasePreferenceController {
+
+    @VisibleForTesting static final String KEY_ENABLED_VR_LISTENERS = "enabled_vr_listeners";
+
+    public EnabledVrListenersController(Context context) {
+        super(context, KEY_ENABLED_VR_LISTENERS);
+    }
+
+    @AvailabilityStatus
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_enabled_vr_listeners)
+                ? AVAILABLE
+                : DISABLED_UNSUPPORTED;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/HighPowerAppsController.java b/src/com/android/settings/applications/HighPowerAppsController.java
new file mode 100644
index 0000000..dc847b3
--- /dev/null
+++ b/src/com/android/settings/applications/HighPowerAppsController.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.R;
+
+public class HighPowerAppsController extends BasePreferenceController {
+
+    @VisibleForTesting static final String KEY_HIGH_POWER_APPS = "high_power_apps";
+
+    public HighPowerAppsController(Context context) {
+        super(context, KEY_HIGH_POWER_APPS);
+    }
+
+    @AvailabilityStatus
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_high_power_apps)
+                ? AVAILABLE
+                : DISABLED_UNSUPPORTED;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/PremiumSmsController.java b/src/com/android/settings/applications/PremiumSmsController.java
new file mode 100644
index 0000000..40911a5
--- /dev/null
+++ b/src/com/android/settings/applications/PremiumSmsController.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.R;
+
+public class PremiumSmsController extends BasePreferenceController {
+
+    @VisibleForTesting static final String KEY_PREMIUM_SMS = "premium_sms";
+
+    public PremiumSmsController(Context context) {
+        super(context, KEY_PREMIUM_SMS);
+    }
+
+    @AvailabilityStatus
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_premium_sms)
+                ? AVAILABLE
+                : DISABLED_UNSUPPORTED;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/SpecialAccessSettings.java b/src/com/android/settings/applications/SpecialAccessSettings.java
index 73ae744..4e43c05 100644
--- a/src/com/android/settings/applications/SpecialAccessSettings.java
+++ b/src/com/android/settings/applications/SpecialAccessSettings.java
@@ -17,6 +17,7 @@
 import android.app.ActivityManager;
 import android.content.Context;
 import android.os.Bundle;
+import android.support.annotation.NonNull;
 import android.provider.SearchIndexableResource;
 import android.support.v7.preference.Preference;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -31,7 +32,6 @@
 public class SpecialAccessSettings extends DashboardFragment {
 
     private static final String TAG = "SpecialAccessSettings";
-
     private static final String[] DISABLED_FEATURES_LOW_RAM =
             new String[]{"notification_access", "zen_access", "enabled_vr_listeners",
                     "picture_in_picture"};
@@ -62,7 +62,18 @@
 
     @Override
     protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
-        return null;
+        return buildPreferenceControllers(context);
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(
+            @NonNull Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new HighPowerAppsController(context));
+        controllers.add(new DeviceAdministratorsController(context));
+        controllers.add(new PremiumSmsController(context));
+        controllers.add(new DataSaverController(context));
+        controllers.add(new EnabledVrListenersController(context));
+        return controllers;
     }
 
     @Override
@@ -82,5 +93,11 @@
                     result.add(sir);
                     return result;
                 }
+
+                @Override
+                public List<AbstractPreferenceController> getPreferenceControllers(
+                        Context context) {
+                    return buildPreferenceControllers(context);
+                }
             };
 }
diff --git a/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBase.java b/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBase.java
index fa67ec8..873c98c 100644
--- a/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBase.java
+++ b/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBase.java
@@ -14,7 +14,6 @@
 
 package com.android.settings.applications.appinfo;
 
-import android.app.slice.Slice;
 import android.content.Context;
 import android.os.Bundle;
 import android.os.UserManager;
@@ -52,7 +51,13 @@
 
     @Override
     public void updateState(Preference preference) {
-        preference.setSummary(isDefaultApp() ? R.string.yes : R.string.no);
+        preference.setSummary(getSummary());
+    }
+
+    @Override
+    public String getSummary() {
+        int summaryResId = isDefaultApp() ? R.string.yes : R.string.no;
+        return mContext.getString(summaryResId);
     }
 
     @Override
@@ -69,12 +74,14 @@
 
     /**
      * Check whether the app has the default app capability
+     *
      * @return true if the app has the default app capability
      */
     protected abstract boolean hasAppCapability();
 
     /**
      * Check whether the app is the default app
+     *
      * @return true if the app is the default app
      */
     protected abstract boolean isDefaultApp();
diff --git a/src/com/android/settings/applications/appinfo/DrawOverlayDetailPreferenceController.java b/src/com/android/settings/applications/appinfo/DrawOverlayDetailPreferenceController.java
index 37a9edf..02f52b6 100644
--- a/src/com/android/settings/applications/appinfo/DrawOverlayDetailPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/DrawOverlayDetailPreferenceController.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.os.UserManager;
-import android.support.annotation.VisibleForTesting;
 import android.support.v7.preference.Preference;
 
 import com.android.settings.SettingsPreferenceFragment;
@@ -61,9 +60,8 @@
         return DrawOverlayDetails.class;
     }
 
-    @VisibleForTesting
-    CharSequence getSummary() {
-        return DrawOverlayDetails.getSummary(mContext, mParent.getAppEntry());
+    @Override
+    public String getSummary() {
+        return DrawOverlayDetails.getSummary(mContext, mParent.getAppEntry()).toString();
     }
-
 }
diff --git a/src/com/android/settings/applications/appinfo/WriteSystemSettingsPreferenceController.java b/src/com/android/settings/applications/appinfo/WriteSystemSettingsPreferenceController.java
index 2a88d2f..73e7675 100644
--- a/src/com/android/settings/applications/appinfo/WriteSystemSettingsPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/WriteSystemSettingsPreferenceController.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.os.UserManager;
-import android.support.annotation.VisibleForTesting;
 import android.support.v7.preference.Preference;
 
 import com.android.settings.SettingsPreferenceFragment;
@@ -62,9 +61,9 @@
         return WriteSettingsDetails.class;
     }
 
-    @VisibleForTesting
-    CharSequence getSummary() {
-        return WriteSettingsDetails.getSummary(mContext, mParent.getAppEntry());
-    }
+    @Override
+    public String getSummary() {
+        return WriteSettingsDetails.getSummary(mContext, mParent.getAppEntry()).toString();
 
+    }
 }
diff --git a/src/com/android/settings/backup/BackupSettingsActivityPreferenceController.java b/src/com/android/settings/backup/BackupSettingsActivityPreferenceController.java
index 7a7530c..dccc310 100644
--- a/src/com/android/settings/backup/BackupSettingsActivityPreferenceController.java
+++ b/src/com/android/settings/backup/BackupSettingsActivityPreferenceController.java
@@ -23,8 +23,6 @@
 
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
 
 public class BackupSettingsActivityPreferenceController extends BasePreferenceController {
     private static final String TAG = "BackupSettingActivityPC";
@@ -49,10 +47,15 @@
 
     @Override
     public void updateState(Preference preference) {
+        preference.setSummary(getSummary());
+    }
+
+    @Override
+    public String getSummary() {
         final boolean backupEnabled = mBackupManager.isBackupEnabled();
 
-        preference.setSummary(backupEnabled
-                ? R.string.accessibility_feature_state_on
-                : R.string.accessibility_feature_state_off);
+        return backupEnabled
+                ? mContext.getString(R.string.accessibility_feature_state_on)
+                : mContext.getString(R.string.accessibility_feature_state_off);
     }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
index 2d0ce60..bf13e07 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
@@ -109,7 +109,19 @@
 
     @Override
     public void updateState(Preference preference) {
-        updateDeviceName(preference, mLocalAdapter.getName());
+        updateDeviceName(preference);
+    }
+
+    @Override
+    public String getSummary() {
+        String deviceName = getDeviceName();
+        if (TextUtils.isEmpty(deviceName)) {
+            return super.getSummary();
+        }
+
+        return TextUtils.expandTemplate(
+                mContext.getText(R.string.bluetooth_device_name_summary),
+                BidiFormatter.getInstance().unicodeWrap(deviceName)).toString();
     }
 
     /**
@@ -132,18 +144,14 @@
      * Update device summary with {@code deviceName}, where {@code deviceName} has accent color
      *
      * @param preference to set the summary for
-     * @param deviceName bluetooth device name to show in the summary
      */
-    protected void updateDeviceName(final Preference preference, final String deviceName) {
-        if (deviceName == null) {
-            // TODO: show error message in preference subtitle
-            return;
-        }
-        final CharSequence summary = TextUtils.expandTemplate(
-                mContext.getText(R.string.bluetooth_device_name_summary),
-                BidiFormatter.getInstance().unicodeWrap(deviceName));
+    protected void updateDeviceName(final Preference preference) {
         preference.setSelectable(false);
-        preference.setSummary(summary);
+        preference.setSummary(getSummary());
+    }
+
+    protected String getDeviceName() {
+        return mLocalAdapter.getName();
     }
 
     /**
@@ -158,7 +166,7 @@
 
             if (TextUtils.equals(action, BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
                 if (mPreference != null && mLocalAdapter != null && mLocalAdapter.isEnabled()) {
-                    updateDeviceName(mPreference, mLocalAdapter.getName());
+                    updateDeviceName(mPreference);
                 }
             }
         }
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
index 69eefcf..a12d1a8 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
@@ -67,8 +67,13 @@
     }
 
     @Override
-    protected void updateDeviceName(final Preference preference, final String deviceName) {
-        preference.setSummary(deviceName);
+    protected void updateDeviceName(final Preference preference) {
+        preference.setSummary(getSummary());
+    }
+
+    @Override
+    public String getSummary() {
+        return getDeviceName();
     }
 
     @Override
diff --git a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java
index 3482ee2..8a59768 100644
--- a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java
@@ -98,10 +98,11 @@
     }
 
     @Override
-    public void setChecked(boolean isChecked) {
+    public boolean setChecked(boolean isChecked) {
         if (mBluetoothAdapter != null) {
             mBluetoothAdapter.setBluetoothEnabled(isChecked);
         }
+        return true;
     }
 
     /**
diff --git a/src/com/android/settings/core/TogglePreferenceController.java b/src/com/android/settings/core/TogglePreferenceController.java
index febd7ad..5431f4d 100644
--- a/src/com/android/settings/core/TogglePreferenceController.java
+++ b/src/com/android/settings/core/TogglePreferenceController.java
@@ -40,8 +40,9 @@
      * Set the Setting to {@param isChecked}
      *
      * @param isChecked Is {@true} when the setting should be enabled.
+     * @return {@true} if the underlying setting is updated.
      */
-    public abstract void setChecked(boolean isChecked);
+    public abstract boolean setChecked(boolean isChecked);
 
     @Override
     public final void updateState(Preference preference) {
@@ -50,8 +51,6 @@
 
     @Override
     public final boolean onPreferenceChange(Preference preference, Object newValue) {
-        boolean auto = (Boolean) newValue;
-        setChecked(auto);
-        return true;
+        return setChecked((Boolean) newValue);
     }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/development/BluetoothInbandRingingPreferenceController.java b/src/com/android/settings/development/BluetoothInbandRingingPreferenceController.java
index db5a881..809db19 100644
--- a/src/com/android/settings/development/BluetoothInbandRingingPreferenceController.java
+++ b/src/com/android/settings/development/BluetoothInbandRingingPreferenceController.java
@@ -31,11 +31,11 @@
         DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener,
         PreferenceControllerMixin {
 
-    private static final String BLUETOOTH_ENABLE_INBAND_RINGING_KEY =
-            "bluetooth_enable_inband_ringing";
+    private static final String BLUETOOTH_DISABLE_INBAND_RINGING_KEY =
+            "bluetooth_disable_inband_ringing";
     @VisibleForTesting
-    static final String BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY =
-            "persist.bluetooth.enableinbandringing";
+    static final String BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY =
+            "persist.bluetooth.disableinbandringing";
 
     private SwitchPreference mPreference;
 
@@ -50,7 +50,7 @@
 
     @Override
     public String getPreferenceKey() {
-        return BLUETOOTH_ENABLE_INBAND_RINGING_KEY;
+        return BLUETOOTH_DISABLE_INBAND_RINGING_KEY;
     }
 
     @Override
@@ -62,16 +62,16 @@
 
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final boolean isEnabled = (Boolean) newValue;
-        SystemProperties.set(BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY,
-                isEnabled ? "true" : "false");
+        final boolean isChecked = (Boolean) newValue;
+        SystemProperties.set(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY,
+                isChecked ? "true" : "false");
         return true;
     }
 
     @Override
     public void updateState(Preference preference) {
         final boolean isEnabled = SystemProperties.getBoolean(
-                BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY, true /* default */);
+                BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, false /* default */);
         mPreference.setChecked(isEnabled);
     }
 
@@ -83,9 +83,8 @@
     @Override
     protected void onDeveloperOptionsSwitchDisabled() {
         mPreference.setEnabled(false);
-        // the default setting for this preference is the enabled state
-        mPreference.setChecked(true);
-        SystemProperties.set(BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY, "true");
+        mPreference.setChecked(false);
+        SystemProperties.set(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, "false");
     }
 
     @VisibleForTesting
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java
index d9e42df..8c8b90e 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java
@@ -16,22 +16,28 @@
 
 package com.android.settings.deviceinfo;
 
+import static com.android.settings.deviceinfo.StorageSettings.TAG;
+
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
 import android.os.Bundle;
+import android.os.UserManager;
 import android.os.storage.DiskInfo;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.text.TextUtils;
 import android.util.Log;
-
 import android.widget.Toast;
+
 import com.android.settings.R;
+import com.android.settings.password.ChooseLockSettingsHelper;
 
 import java.util.Objects;
 
-import static com.android.settings.deviceinfo.StorageSettings.TAG;
-
 public class StorageWizardMigrateConfirm extends StorageWizardBase {
+    private static final int REQUEST_CREDENTIAL = 100;
+
     private MigrateEstimateTask mEstimate;
 
     @Override
@@ -75,9 +81,22 @@
 
     @Override
     public void onNavigateNext() {
-        int moveId;
+        // Ensure that all users are unlocked so that we can move their data
+        if (StorageManager.isFileEncryptedNativeOrEmulated()) {
+            for (UserInfo user : getSystemService(UserManager.class).getUsers()) {
+                if (!StorageManager.isUserKeyUnlocked(user.id)) {
+                    Log.d(TAG, "User " + user.id + " is currently locked; requesting unlock");
+                    final CharSequence description = TextUtils.expandTemplate(
+                            getText(R.string.storage_wizard_move_unlock), user.name);
+                    new ChooseLockSettingsHelper(this).launchConfirmationActivityForAnyUser(
+                            REQUEST_CREDENTIAL, null, null, description, user.id);
+                    return;
+                }
+            }
+        }
 
         // We only expect exceptions from StorageManagerService#setPrimaryStorageUuid
+        int moveId;
         try {
             moveId = getPackageManager().movePrimaryStorage(mVolume);
         } catch (IllegalArgumentException e) {
@@ -108,4 +127,22 @@
         startActivity(intent);
         finishAffinity();
     }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_CREDENTIAL) {
+            if (resultCode == RESULT_OK) {
+                // Credentials confirmed, so storage should be unlocked; let's
+                // go look for the next locked user.
+                onNavigateNext();
+            } else {
+                // User wasn't able to confirm credentials, so we're okay
+                // landing back at the wizard page again, where they read
+                // instructions again and tap "Next" to try again.
+                Log.w(TAG, "Failed to confirm credentials");
+            }
+        } else {
+            super.onActivityResult(requestCode, resultCode, data);
+        }
+    }
 }
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
index 65b3d1f..e82612c 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
@@ -16,20 +16,30 @@
 
 package com.android.settings.deviceinfo;
 
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Bundle;
-
-import com.android.internal.util.Preconditions;
-import com.android.settings.R;
-
 import static android.content.Intent.EXTRA_PACKAGE_NAME;
 import static android.content.Intent.EXTRA_TITLE;
 import static android.content.pm.PackageManager.EXTRA_MOVE_ID;
 import static android.os.storage.VolumeInfo.EXTRA_VOLUME_ID;
 
+import static com.android.settings.deviceinfo.StorageSettings.TAG;
+
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.util.Preconditions;
+import com.android.settings.R;
+import com.android.settings.password.ChooseLockSettingsHelper;
+
 public class StorageWizardMoveConfirm extends StorageWizardBase {
+    private static final int REQUEST_CREDENTIAL = 100;
+
     private String mPackageName;
     private ApplicationInfo mApp;
 
@@ -66,6 +76,20 @@
 
     @Override
     public void onNavigateNext() {
+        // Ensure that all users are unlocked so that we can move their data
+        if (StorageManager.isFileEncryptedNativeOrEmulated()) {
+            for (UserInfo user : getSystemService(UserManager.class).getUsers()) {
+                if (!StorageManager.isUserKeyUnlocked(user.id)) {
+                    Log.d(TAG, "User " + user.id + " is currently locked; requesting unlock");
+                    final CharSequence description = TextUtils.expandTemplate(
+                            getText(R.string.storage_wizard_move_unlock), user.name);
+                    new ChooseLockSettingsHelper(this).launchConfirmationActivityForAnyUser(
+                            REQUEST_CREDENTIAL, null, null, description, user.id);
+                    return;
+                }
+            }
+        }
+
         // Kick off move before we transition
         final String appName = getPackageManager().getApplicationLabel(mApp).toString();
         final int moveId = getPackageManager().movePackage(mPackageName, mVolume);
@@ -77,4 +101,22 @@
         startActivity(intent);
         finishAffinity();
     }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_CREDENTIAL) {
+            if (resultCode == RESULT_OK) {
+                // Credentials confirmed, so storage should be unlocked; let's
+                // go look for the next locked user.
+                onNavigateNext();
+            } else {
+                // User wasn't able to confirm credentials, so we're okay
+                // landing back at the wizard page again, where they read
+                // instructions again and tap "Next" to try again.
+                Log.w(TAG, "Failed to confirm credentials");
+            }
+        } else {
+            super.onActivityResult(requestCode, resultCode, data);
+        }
+    }
 }
diff --git a/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java b/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java
index 92c33d8..a061f82 100644
--- a/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java
@@ -78,8 +78,12 @@
 
     @Override
     public void updateState(Preference preference) {
-        preference.setSummary(mContext.getString(R.string.about_summary,
-                Build.VERSION.RELEASE));
+        preference.setSummary(getSummary());
+    }
+
+    @Override
+    public String getSummary() {
+        return mContext.getString(R.string.about_summary, Build.VERSION.RELEASE);
     }
 
     /**
diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
index d71a1f8..28f9260 100644
--- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java
+++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
@@ -45,9 +45,10 @@
     }
 
     @Override
-    public void setChecked(boolean isChecked) {
+    public boolean setChecked(boolean isChecked) {
         Settings.System.putInt(mContext.getContentResolver(), SYSTEM_KEY,
                 isChecked ? SCREEN_BRIGHTNESS_MODE_AUTOMATIC : DEFAULT_VALUE);
+        return true;
     }
 
     @Override
diff --git a/src/com/android/settings/fingerprint/FingerprintSettings.java b/src/com/android/settings/fingerprint/FingerprintSettings.java
index ad7f83a..5d178d2 100644
--- a/src/com/android/settings/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/fingerprint/FingerprintSettings.java
@@ -974,6 +974,10 @@
         }
     }
 
+    /**
+     * @deprecated in favor of new SecuritySettings.
+     */
+    @Deprecated
     public static Preference getFingerprintPreferenceForUser(Context context, final int userId) {
         final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(context);
         if (fpm == null || !fpm.isHardwareDetected()) {
diff --git a/src/com/android/settings/gestures/GesturesSettingPreferenceController.java b/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
index 819b128..8b2fcc0 100644
--- a/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
+++ b/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
@@ -24,7 +24,6 @@
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
-import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
 
@@ -58,25 +57,28 @@
 
     @Override
     public void updateState(Preference preference) {
+        preference.setSummary(getSummary());
+    }
+
+    @Override
+    public String getSummary() {
         if (!mFeatureProvider.isSensorAvailable(mContext)) {
-            preference.setSummary("");
-            return;
+            return "";
         }
         final ContentResolver contentResolver = mContext.getContentResolver();
         final boolean assistGestureEnabled = Settings.Secure.getInt(
                 contentResolver, Settings.Secure.ASSIST_GESTURE_ENABLED, 1) != 0;
         final boolean assistGestureSilenceEnabled = Settings.Secure.getInt(
                 contentResolver, Settings.Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED, 1) != 0;
-        final String summary;
+
         if (mFeatureProvider.isSupported(mContext) && assistGestureEnabled) {
-            summary = mContext.getString(
+            return mContext.getString(
                     R.string.language_input_gesture_summary_on_with_assist);
-        } else if (assistGestureSilenceEnabled) {
-            summary = mContext.getString(
-                    R.string.language_input_gesture_summary_on_non_assist);
-        } else {
-            summary = mContext.getString(R.string.language_input_gesture_summary_off);
         }
-        preference.setSummary(summary);
+        if (assistGestureSilenceEnabled) {
+            return mContext.getString(
+                    R.string.language_input_gesture_summary_on_non_assist);
+        }
+        return mContext.getString(R.string.language_input_gesture_summary_off);
     }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/notification/HeaderPreferenceController.java b/src/com/android/settings/notification/HeaderPreferenceController.java
index 3d51b25..5ec60c2 100644
--- a/src/com/android/settings/notification/HeaderPreferenceController.java
+++ b/src/com/android/settings/notification/HeaderPreferenceController.java
@@ -77,7 +77,8 @@
                         : mAppRow.label;
     }
 
-    CharSequence getSummary() {
+    @Override
+    public String getSummary() {
         if (mChannel != null) {
            if (mChannelGroup != null && mChannelGroup.getGroup() != null
                 && !TextUtils.isEmpty(mChannelGroup.getGroup().getName())) {
@@ -87,12 +88,12 @@
                summary.append(bidi.unicodeWrap(mContext.getText(
                        R.string.notification_header_divider_symbol_with_spaces)));
                summary.append(bidi.unicodeWrap(mChannelGroup.getGroup().getName().toString()));
-               return summary;
+               return summary.toString();
            } else {
-               return mAppRow.label;
+               return mAppRow.label.toString();
            }
         } else if (mChannelGroup != null && mChannelGroup.getGroup() != null) {
-            return mAppRow.label;
+            return mAppRow.label.toString();
         } else {
             return "";
         }
diff --git a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
index dd7b0fb..d56febb 100644
--- a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
@@ -36,6 +36,7 @@
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -78,7 +79,9 @@
 
         mProfileChallengeUserId = Utils.getManagedProfileId(
                 UserManager.get(context), UserHandle.myUserId());
-        final LockPatternUtils utils = new LockPatternUtils(context);
+        final LockPatternUtils utils = FeatureFactory.getFactory(context)
+                .getSecurityFeatureProvider()
+                .getLockPatternUtils(context);
         mSecure = utils.isSecure(UserHandle.myUserId());
         mSecureProfile = (mProfileChallengeUserId != UserHandle.USER_NULL)
                 && (utils.isSecure(mProfileChallengeUserId)
@@ -278,10 +281,14 @@
         }
     }
 
-    public int getSummaryResource() {
-        final boolean enabled = getLockscreenNotificationsEnabled(UserHandle.myUserId());
-        final boolean allowPrivate = !mSecure
-            || getLockscreenAllowPrivateNotifications(UserHandle.myUserId());
+    public static int getSummaryResource(Context context) {
+        final boolean enabled = getLockscreenNotificationsEnabled(context, UserHandle.myUserId());
+        final boolean secure = FeatureFactory.getFactory(context)
+                .getSecurityFeatureProvider()
+                .getLockPatternUtils(context)
+                .isSecure(UserHandle.myUserId());
+        final boolean allowPrivate = !secure
+            || getLockscreenAllowPrivateNotifications(context, UserHandle.myUserId());
         return !enabled ? R.string.lock_screen_notifications_summary_disable :
             allowPrivate ? R.string.lock_screen_notifications_summary_show :
                 R.string.lock_screen_notifications_summary_hide;
@@ -291,7 +298,7 @@
         if (mLockscreen == null) {
             return;
         }
-        mLockscreenSelectedValue = getSummaryResource();
+        mLockscreenSelectedValue = getSummaryResource(mContext);
         mLockscreen.setSummary("%s");
         mLockscreen.setValue(Integer.toString(mLockscreenSelectedValue));
     }
@@ -303,9 +310,9 @@
         if (mLockscreenProfile == null) {
             return;
         }
-        final boolean enabled = getLockscreenNotificationsEnabled(mProfileChallengeUserId);
+        final boolean enabled = getLockscreenNotificationsEnabled(mContext,mProfileChallengeUserId);
         final boolean allowPrivate = !mSecureProfile
-                || getLockscreenAllowPrivateNotifications(mProfileChallengeUserId);
+                || getLockscreenAllowPrivateNotifications(mContext, mProfileChallengeUserId);
         mLockscreenProfile.setSummary("%s");
         mLockscreenSelectedValueProfile = !enabled
                 ? R.string.lock_screen_notifications_summary_disable_profile
@@ -314,13 +321,13 @@
         mLockscreenProfile.setValue(Integer.toString(mLockscreenSelectedValueProfile));
     }
 
-    private boolean getLockscreenNotificationsEnabled(int userId) {
-        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+    private static boolean getLockscreenNotificationsEnabled(Context context, int userId) {
+        return Settings.Secure.getIntForUser(context.getContentResolver(),
                 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userId) != 0;
     }
 
-    private boolean getLockscreenAllowPrivateNotifications(int userId) {
-        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+    private static boolean getLockscreenAllowPrivateNotifications(Context context, int userId) {
+        return Settings.Secure.getIntForUser(context.getContentResolver(),
                 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userId) != 0;
     }
 
diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java
index 806ee67..11d40a3 100644
--- a/src/com/android/settings/password/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java
@@ -23,6 +23,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Intent;
 import android.content.IntentSender;
+import android.os.Bundle;
 import android.os.UserManager;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -42,6 +43,12 @@
     public static final String EXTRA_KEY_FOR_FINGERPRINT = "for_fingerprint";
     public static final String EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT = "for_cred_req_boot";
 
+    /**
+     * When invoked via {@link ConfirmLockPassword.InternalActivity}, this flag
+     * controls if we relax the enforcement of
+     * {@link Utils#enforceSameOwner(android.content.Context, int)}.
+     */
+    public static final String EXTRA_ALLOW_ANY_USER = "allow_any_user";
 
     @VisibleForTesting LockPatternUtils mLockPatternUtils;
     private Activity mActivity;
@@ -200,25 +207,47 @@
                 external, true, challenge, Utils.enforceSameOwner(mActivity, userId));
     }
 
+    /**
+     * Variant that allows you to prompt for credentials of any user, including
+     * those which aren't associated with the current user. As an example, this
+     * is useful when unlocking the storage for secondary users.
+     */
+    public boolean launchConfirmationActivityForAnyUser(int request,
+            @Nullable CharSequence title, @Nullable CharSequence header,
+            @Nullable CharSequence description, int userId) {
+        final Bundle extras = new Bundle();
+        extras.putBoolean(EXTRA_ALLOW_ANY_USER, true);
+        return launchConfirmationActivity(request, title, header, description, false,
+                false, true, 0, userId, extras);
+    }
+
     private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
             @Nullable CharSequence header, @Nullable CharSequence description,
             boolean returnCredentials, boolean external, boolean hasChallenge,
             long challenge, int userId) {
         return launchConfirmationActivity(request, title, header, description, returnCredentials,
-                external, hasChallenge, challenge, userId, null /* alternateButton */);
+                external, hasChallenge, challenge, userId, null /* alternateButton */, null);
+    }
+
+    private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
+            @Nullable CharSequence header, @Nullable CharSequence description,
+            boolean returnCredentials, boolean external, boolean hasChallenge,
+            long challenge, int userId, Bundle extras) {
+        return launchConfirmationActivity(request, title, header, description, returnCredentials,
+                external, hasChallenge, challenge, userId, null /* alternateButton */, extras);
     }
 
     public boolean launchFrpConfirmationActivity(int request, @Nullable CharSequence header,
             @Nullable CharSequence description, @Nullable CharSequence alternateButton) {
         return launchConfirmationActivity(request, null /* title */, header, description,
                 false /* returnCredentials */, true /* external */, false /* hasChallenge */,
-                0 /* challenge */, LockPatternUtils.USER_FRP, alternateButton);
+                0 /* challenge */, LockPatternUtils.USER_FRP, alternateButton, null);
     }
 
     private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
             @Nullable CharSequence header, @Nullable CharSequence description,
             boolean returnCredentials, boolean external, boolean hasChallenge,
-            long challenge, int userId, @Nullable CharSequence alternateButton) {
+            long challenge, int userId, @Nullable CharSequence alternateButton, Bundle extras) {
         final int effectiveUserId = UserManager.get(mActivity).getCredentialOwnerProfile(userId);
         boolean launched = false;
 
@@ -228,7 +257,7 @@
                         returnCredentials || hasChallenge
                                 ? ConfirmLockPattern.InternalActivity.class
                                 : ConfirmLockPattern.class, returnCredentials, external,
-                                hasChallenge, challenge, userId, alternateButton);
+                                hasChallenge, challenge, userId, alternateButton, extras);
                 break;
             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
@@ -240,7 +269,7 @@
                         returnCredentials || hasChallenge
                                 ? ConfirmLockPassword.InternalActivity.class
                                 : ConfirmLockPassword.class, returnCredentials, external,
-                                hasChallenge, challenge, userId, alternateButton);
+                                hasChallenge, challenge, userId, alternateButton, extras);
                 break;
         }
         return launched;
@@ -249,7 +278,7 @@
     private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header,
             CharSequence message, Class<?> activityClass, boolean returnCredentials,
             boolean external, boolean hasChallenge, long challenge,
-            int userId, @Nullable CharSequence alternateButton) {
+            int userId, @Nullable CharSequence alternateButton, Bundle extras) {
         final boolean frp = (userId == LockPatternUtils.USER_FRP);
         final Intent intent = new Intent();
         intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
@@ -266,6 +295,9 @@
         intent.putExtra(SettingsActivity.EXTRA_HIDE_DRAWER, true);
         intent.putExtra(Intent.EXTRA_USER_ID, userId);
         intent.putExtra(KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL, alternateButton);
+        if (extras != null) {
+            intent.putExtras(extras);
+        }
         intent.setClassName(ConfirmDeviceCredentialBaseFragment.PACKAGE, activityClass.getName());
         if (external) {
             intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java
index d2bd934..ab8c3dc 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java
@@ -45,10 +45,15 @@
     private boolean mIsKeyguardLocked = false;
     private ConfirmCredentialTheme mConfirmCredentialTheme;
 
+    private boolean isInternalActivity() {
+        return (this instanceof ConfirmLockPassword.InternalActivity)
+                || (this instanceof ConfirmLockPattern.InternalActivity);
+    }
+
     @Override
     protected void onCreate(Bundle savedState) {
         int credentialOwnerUserId = Utils.getCredentialOwnerUserId(this,
-                Utils.getUserIdFromBundle(this, getIntent().getExtras()));
+                Utils.getUserIdFromBundle(this, getIntent().getExtras(), isInternalActivity()));
         if (UserManager.get(this).isManagedProfile(credentialOwnerUserId)) {
             setTheme(R.style.Theme_ConfirmDeviceCredentialsWork);
             mConfirmCredentialTheme = ConfirmCredentialTheme.WORK;
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
index 350fc76..5b18925 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
@@ -94,6 +94,11 @@
     protected boolean mFrp;
     private CharSequence mFrpAlternateButtonText;
 
+    private boolean isInternalActivity() {
+        return (getActivity() instanceof ConfirmLockPassword.InternalActivity)
+                || (getActivity() instanceof ConfirmLockPattern.InternalActivity);
+    }
+
     @Override
     public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -103,7 +108,8 @@
                 ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, false);
         // Only take this argument into account if it belongs to the current profile.
         Intent intent = getActivity().getIntent();
-        mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras());
+        mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras(),
+                isInternalActivity());
         mFrp = (mUserId == LockPatternUtils.USER_FRP);
         mUserManager = UserManager.get(getActivity());
         mEffectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId);
@@ -141,7 +147,7 @@
                 getActivity(),
                 Utils.getUserIdFromBundle(
                         getActivity(),
-                        getActivity().getIntent().getExtras()));
+                        getActivity().getIntent().getExtras(), isInternalActivity()));
         if (mUserManager.isManagedProfile(credentialOwnerUserId)) {
             setWorkChallengeBackground(view, credentialOwnerUserId);
         }
diff --git a/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java
new file mode 100644
index 0000000..612dd6d
--- /dev/null
+++ b/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security;
+
+import static com.android.settings.security
+        .SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.support.v7.preference.Preference;
+import android.text.TextUtils;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.password.ChooseLockGeneric;
+import com.android.settings.widget.GearPreference;
+
+public class ChangeProfileScreenLockPreferenceController extends
+        ChangeScreenLockPreferenceController {
+
+    private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
+
+    public ChangeProfileScreenLockPreferenceController(Context context,
+            SecuritySettingsV2 host) {
+        super(context, host);
+    }
+
+    @Override
+    public void onGearClick(GearPreference p) {
+
+    }
+
+    @Override
+    public boolean isAvailable() {
+        if (mProfileChallengeUserId == UserHandle.USER_NULL ||
+                !mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId)) {
+            return false;
+        }
+        if (!mLockPatternUtils.isSecure(mProfileChallengeUserId)) {
+            return true;
+        }
+        switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)) {
+            case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
+            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
+            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
+            case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
+            case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
+            case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+            case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
+                return true;
+        }
+        return false;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_UNLOCK_SET_OR_CHANGE_PROFILE;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+            return false;
+        }
+        if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
+            return false;
+        }
+        final Bundle extras = new Bundle();
+        extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
+        mHost.startFragment(mHost, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
+                R.string.lock_settings_picker_title_profile,
+                SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
+        return true;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        updateSummary(preference, mProfileChallengeUserId);
+
+        if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
+            final String summary = mContext.getString(
+                    R.string.lock_settings_profile_unified_summary);
+            mPreference.setSummary(summary);
+            mPreference.setEnabled(false);
+        } else {
+            // PO may disallow to change profile password, and the profile's password is
+            // separated from screen lock password. Disable profile specific "Screen lock" menu.
+            disableIfPasswordQualityManaged(mProfileChallengeUserId);
+        }
+    }
+}
diff --git a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
new file mode 100644
index 0000000..3cd235f
--- /dev/null
+++ b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security;
+
+import static com.android.settings.security.SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.password.ChooseLockGeneric;
+import com.android.settings.security.screenlock.ScreenLockSettings;
+import com.android.settings.widget.GearPreference;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class ChangeScreenLockPreferenceController extends AbstractPreferenceController implements
+        PreferenceControllerMixin, GearPreference.OnGearClickListener {
+
+    private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
+
+    protected final DevicePolicyManager mDPM;
+    protected final SecuritySettingsV2 mHost;
+    protected final UserManager mUm;
+    protected final LockPatternUtils mLockPatternUtils;
+
+    protected final int mUserId = UserHandle.myUserId();
+    protected final int mProfileChallengeUserId;
+
+    protected RestrictedPreference mPreference;
+
+    public ChangeScreenLockPreferenceController(Context context, SecuritySettingsV2 host) {
+        super(context);
+        mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mLockPatternUtils = FeatureFactory.getFactory(context)
+                .getSecurityFeatureProvider()
+                .getLockPatternUtils(context);
+        mHost = host;
+        mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_UNLOCK_SET_OR_CHANGE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = (RestrictedPreference) screen.findPreference(getPreferenceKey());
+        if (mPreference != null && mPreference instanceof GearPreference) {
+            ((GearPreference) mPreference).setOnGearClickListener(this);
+        }
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        updateSummary(preference, mUserId);
+        disableIfPasswordQualityManaged(mUserId);
+        if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
+            // PO may disallow to change password for the profile, but screen lock and managed
+            // profile's lock is the same. Disable main "Screen lock" menu.
+            disableIfPasswordQualityManaged(mProfileChallengeUserId);
+        }
+    }
+
+    @Override
+    public void onGearClick(GearPreference p) {
+        if (TextUtils.equals(p.getKey(), getPreferenceKey())) {
+            mHost.startFragment(mHost, ScreenLockSettings.class.getName(), 0, 0, null);
+        }
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+            return super.handlePreferenceTreeClick(preference);
+        }
+        // TODO(b/35930129): Remove once existing password can be passed into vold directly.
+        // Currently we need this logic to ensure that the QUIET_MODE is off for any work
+        // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
+        // able to complete the operation due to the lack of (old) encryption key.
+        if (mProfileChallengeUserId != UserHandle.USER_NULL
+                && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
+                && StorageManager.isFileEncryptedNativeOnly()) {
+            if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
+                return false;
+            }
+        }
+        mHost.startFragment(mHost, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
+                R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
+        return true;
+    }
+
+    protected void updateSummary(Preference preference, int userId) {
+        if (!mLockPatternUtils.isSecure(userId)) {
+            if (userId == mProfileChallengeUserId
+                    || mLockPatternUtils.isLockScreenDisabled(userId)) {
+                preference.setSummary(R.string.unlock_set_unlock_mode_off);
+            } else {
+                preference.setSummary(R.string.unlock_set_unlock_mode_none);
+            }
+        } else {
+            switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
+                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
+                    preference.setSummary(R.string.unlock_set_unlock_mode_pattern);
+                    break;
+                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
+                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
+                    preference.setSummary(R.string.unlock_set_unlock_mode_pin);
+                    break;
+                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
+                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
+                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+                case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
+                    preference.setSummary(R.string.unlock_set_unlock_mode_password);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Sets the preference as disabled by admin if PASSWORD_QUALITY_MANAGED is set.
+     * The preference must be a RestrictedPreference.
+     * <p/>
+     * DO or PO installed in the user may disallow to change password.
+     */
+    void disableIfPasswordQualityManaged(int userId) {
+        final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtils
+                .checkIfPasswordQualityIsSet(mContext, userId);
+        final DevicePolicyManager dpm = (DevicePolicyManager) mContext
+                .getSystemService(Context.DEVICE_POLICY_SERVICE);
+        if (admin != null && dpm.getPasswordQuality(admin.component, userId)
+                == DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
+            mPreference.setDisabledByAdmin(admin);
+        }
+    }
+}
diff --git a/src/com/android/settings/security/FingerprintProfileStatusPreferenceController.java b/src/com/android/settings/security/FingerprintProfileStatusPreferenceController.java
new file mode 100644
index 0000000..1c72a46
--- /dev/null
+++ b/src/com/android/settings/security/FingerprintProfileStatusPreferenceController.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+public class FingerprintProfileStatusPreferenceController
+        extends FingerprintStatusPreferenceController {
+
+    public static final String KEY_FINGERPRINT_SETTINGS = "fingerprint_settings_profile";
+
+    public FingerprintProfileStatusPreferenceController(Context context) {
+        super(context, KEY_FINGERPRINT_SETTINGS);
+    }
+
+    @Override
+    protected boolean isUserSupported() {
+        return mProfileChallengeUserId != UserHandle.USER_NULL
+                && mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId);
+    }
+
+    @Override
+    protected int getUserId() {
+        return mProfileChallengeUserId;
+    }
+}
diff --git a/src/com/android/settings/security/FingerprintStatusPreferenceController.java b/src/com/android/settings/security/FingerprintStatusPreferenceController.java
new file mode 100644
index 0000000..2985f40
--- /dev/null
+++ b/src/com/android/settings/security/FingerprintStatusPreferenceController.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security;
+
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.fingerprint.Fingerprint;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.fingerprint.FingerprintEnrollIntroduction;
+import com.android.settings.fingerprint.FingerprintSettings;
+import com.android.settings.overlay.FeatureFactory;
+
+import java.util.List;
+
+public class FingerprintStatusPreferenceController extends BasePreferenceController {
+
+    private static final String KEY_FINGERPRINT_SETTINGS = "fingerprint_settings";
+
+    protected final FingerprintManager mFingerprintManager;
+    protected final UserManager mUm;
+    protected final LockPatternUtils mLockPatternUtils;
+
+    protected final int mUserId = UserHandle.myUserId();
+    protected final int mProfileChallengeUserId;
+
+    public FingerprintStatusPreferenceController(Context context) {
+        this(context, KEY_FINGERPRINT_SETTINGS);
+    }
+
+    public FingerprintStatusPreferenceController(Context context, String key) {
+        super(context, key);
+        mFingerprintManager = Utils.getFingerprintManagerOrNull(context);
+        mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        mLockPatternUtils = FeatureFactory.getFactory(context)
+                .getSecurityFeatureProvider()
+                .getLockPatternUtils(context);
+        mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (mFingerprintManager == null || !mFingerprintManager.isHardwareDetected()) {
+            return DISABLED_UNSUPPORTED;
+        }
+        if (isUserSupported()) {
+            return AVAILABLE;
+        } else {
+            return DISABLED_FOR_USER;
+        }
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        if (!isAvailable()) {
+            if (preference != null) {
+                preference.setVisible(false);
+            }
+            return;
+        } else {
+            preference.setVisible(true);
+        }
+        final int userId = getUserId();
+        final List<Fingerprint> items = mFingerprintManager.getEnrolledFingerprints(userId);
+        final int fingerprintCount = items != null ? items.size() : 0;
+        final String clazz;
+        if (fingerprintCount > 0) {
+            preference.setSummary(mContext.getResources().getQuantityString(
+                    R.plurals.security_settings_fingerprint_preference_summary,
+                    fingerprintCount, fingerprintCount));
+            clazz = FingerprintSettings.class.getName();
+        } else {
+            preference.setSummary(
+                    R.string.security_settings_fingerprint_preference_summary_none);
+            clazz = FingerprintEnrollIntroduction.class.getName();
+        }
+        preference.setOnPreferenceClickListener(target -> {
+            final Context context = target.getContext();
+            final UserManager userManager = UserManager.get(context);
+            if (Utils.startQuietModeDialogIfNecessary(context, userManager,
+                    userId)) {
+                return false;
+            }
+            Intent intent = new Intent();
+            intent.setClassName("com.android.settings", clazz);
+            intent.putExtra(Intent.EXTRA_USER_ID, userId);
+            context.startActivity(intent);
+            return true;
+        });
+    }
+
+    protected int getUserId() {
+        return mUserId;
+    }
+
+    protected boolean isUserSupported() {
+        return true;
+    }
+}
diff --git a/src/com/android/settings/security/LockScreenPreferenceController.java b/src/com/android/settings/security/LockScreenPreferenceController.java
new file mode 100644
index 0000000..213c39c
--- /dev/null
+++ b/src/com/android/settings/security/LockScreenPreferenceController.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.notification.LockScreenNotificationPreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+
+public class LockScreenPreferenceController extends BasePreferenceController {
+
+    static final String KEY_LOCKSCREEN_PREFERENCES = "lockscreen_preferences";
+
+    private static final int MY_USER_ID = UserHandle.myUserId();
+    private final LockPatternUtils mLockPatternUtils;
+
+    public LockScreenPreferenceController(Context context) {
+        super(context, KEY_LOCKSCREEN_PREFERENCES);
+        mLockPatternUtils = FeatureFactory.getFactory(context)
+                .getSecurityFeatureProvider().getLockPatternUtils(context);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (!mLockPatternUtils.isSecure(MY_USER_ID)) {
+            return mLockPatternUtils.isLockScreenDisabled(MY_USER_ID)
+                    ? DISABLED_FOR_USER : AVAILABLE;
+        } else {
+            return mLockPatternUtils.getKeyguardStoredPasswordQuality(MY_USER_ID)
+                    == PASSWORD_QUALITY_UNSPECIFIED
+                    ? DISABLED_FOR_USER : AVAILABLE;
+        }
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        final Preference lockscreenPreferences = screen.findPreference(getPreferenceKey());
+        if (lockscreenPreferences != null) {
+            lockscreenPreferences.setSummary(
+                    LockScreenNotificationPreferenceController.getSummaryResource(mContext));
+        }
+    }
+}
diff --git a/src/com/android/settings/security/LockUnificationPreferenceController.java b/src/com/android/settings/security/LockUnificationPreferenceController.java
new file mode 100644
index 0000000..5486e29
--- /dev/null
+++ b/src/com/android/settings/security/LockUnificationPreferenceController.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security;
+
+import static com.android.settings.security
+        .SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
+import static com.android.settings.security.SecuritySettingsV2.UNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
+import static com.android.settings.security.SecuritySettingsV2.UNIFY_LOCK_CONFIRM_PROFILE_REQUEST;
+import static com.android.settings.security.SecuritySettingsV2.UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.password.ChooseLockGeneric;
+import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class LockUnificationPreferenceController extends AbstractPreferenceController
+        implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+    private static final String KEY_UNIFICATION = "unification";
+
+    private static final int MY_USER_ID = UserHandle.myUserId();
+
+    private final UserManager mUm;
+    private final LockPatternUtils mLockPatternUtils;
+    private final int mProfileChallengeUserId;
+    private final SecuritySettingsV2 mHost;
+
+    private RestrictedSwitchPreference mUnifyProfile;
+
+
+    private String mCurrentDevicePassword;
+    private String mCurrentProfilePassword;
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mUnifyProfile = (RestrictedSwitchPreference) screen.findPreference(KEY_UNIFICATION);
+    }
+
+    public LockUnificationPreferenceController(Context context, SecuritySettingsV2 host) {
+        super(context);
+        mHost = host;
+        mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        mLockPatternUtils = FeatureFactory.getFactory(context)
+                .getSecurityFeatureProvider()
+                .getLockPatternUtils(context);
+        mProfileChallengeUserId = Utils.getManagedProfileId(mUm, MY_USER_ID);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        final boolean allowSeparateProfileChallenge =
+                mProfileChallengeUserId != UserHandle.USER_NULL
+                        && mLockPatternUtils.isSeparateProfileChallengeAllowed(
+                        mProfileChallengeUserId);
+        return allowSeparateProfileChallenge;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_UNIFICATION;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object value) {
+        if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
+            return false;
+        }
+        if ((Boolean) value) {
+            final boolean compliantForDevice =
+                    (mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
+                            >= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+                            && mLockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
+                            mProfileChallengeUserId));
+            UnificationConfirmationDialog dialog =
+                    UnificationConfirmationDialog.newInstance(compliantForDevice);
+            dialog.show(mHost);
+        } else {
+            final String title = mContext.getString(R.string.unlock_set_unlock_launch_picker_title);
+            final ChooseLockSettingsHelper helper =
+                    new ChooseLockSettingsHelper(mHost.getActivity(), mHost);
+            if (!helper.launchConfirmationActivity(
+                    UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST,
+                    title, true /* returnCredentials */, MY_USER_ID)) {
+                ununifyLocks();
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        if (mUnifyProfile != null) {
+            final boolean separate =
+                    mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId);
+            mUnifyProfile.setChecked(!separate);
+            if (separate) {
+                mUnifyProfile.setDisabledByAdmin(RestrictedLockUtils.checkIfRestrictionEnforced(
+                        mContext, UserManager.DISALLOW_UNIFIED_PASSWORD,
+                        mProfileChallengeUserId));
+            }
+        }
+    }
+
+    public boolean handleActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST
+                && resultCode == Activity.RESULT_OK) {
+            ununifyLocks();
+            return true;
+        } else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST
+                && resultCode == Activity.RESULT_OK) {
+            mCurrentDevicePassword =
+                    data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+            launchConfirmProfileLockForUnification();
+            return true;
+        } else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST
+                && resultCode == Activity.RESULT_OK) {
+            mCurrentProfilePassword =
+                    data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+            unifyLocks();
+            return true;
+        }
+        return false;
+    }
+
+    private void ununifyLocks() {
+        Bundle extras = new Bundle();
+        extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
+        mHost.startFragment(mHost,
+                ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
+                R.string.lock_settings_picker_title_profile,
+                SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
+    }
+
+    void launchConfirmDeviceLockForUnification() {
+        final String title = mContext.getString(
+                R.string.unlock_set_unlock_launch_picker_title);
+        final ChooseLockSettingsHelper helper =
+                new ChooseLockSettingsHelper(mHost.getActivity(), mHost);
+        if (!helper.launchConfirmationActivity(
+                UNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
+            launchConfirmProfileLockForUnification();
+        }
+    }
+
+    private void launchConfirmProfileLockForUnification() {
+        final String title = mContext.getString(
+                R.string.unlock_set_unlock_launch_picker_title_profile);
+        final ChooseLockSettingsHelper helper =
+                new ChooseLockSettingsHelper(mHost.getActivity(), mHost);
+        if (!helper.launchConfirmationActivity(
+                UNIFY_LOCK_CONFIRM_PROFILE_REQUEST, title, true, mProfileChallengeUserId)) {
+            unifyLocks();
+            // TODO: update relevant prefs.
+            // createPreferenceHierarchy();
+        }
+    }
+
+    private void unifyLocks() {
+        int profileQuality =
+                mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId);
+        if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
+            mLockPatternUtils.saveLockPattern(
+                    LockPatternUtils.stringToPattern(mCurrentProfilePassword),
+                    mCurrentDevicePassword, MY_USER_ID);
+        } else {
+            mLockPatternUtils.saveLockPassword(
+                    mCurrentProfilePassword, mCurrentDevicePassword,
+                    profileQuality, MY_USER_ID);
+        }
+        mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
+                mCurrentProfilePassword);
+        final boolean profilePatternVisibility =
+                mLockPatternUtils.isVisiblePatternEnabled(mProfileChallengeUserId);
+        mLockPatternUtils.setVisiblePatternEnabled(profilePatternVisibility, MY_USER_ID);
+        mCurrentDevicePassword = null;
+        mCurrentProfilePassword = null;
+    }
+
+    void unifyUncompliantLocks() {
+        mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
+                mCurrentProfilePassword);
+        mHost.startFragment(mHost, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
+                R.string.lock_settings_picker_title,
+                SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
+    }
+
+}
diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java
index fc47b5c..f099b44 100644
--- a/src/com/android/settings/security/SecuritySettings.java
+++ b/src/com/android/settings/security/SecuritySettings.java
@@ -161,7 +161,6 @@
     private LocationPreferenceController mLocationcontroller;
     private ManageDeviceAdminPreferenceController mManageDeviceAdminPreferenceController;
     private EnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController;
-    private LockScreenNotificationPreferenceController mLockScreenNotificationPreferenceController;
 
     @Override
     public int getMetricsCategory() {
@@ -208,8 +207,6 @@
                 = new ManageDeviceAdminPreferenceController(activity);
         mEnterprisePrivacyPreferenceController
                 = new EnterprisePrivacyPreferenceController(activity);
-        mLockScreenNotificationPreferenceController
-                = new LockScreenNotificationPreferenceController(activity);
     }
 
     private static int getResIdForLockUnlockScreen(LockPatternUtils lockPatternUtils,
@@ -430,7 +427,7 @@
         final Preference lockscreenPreferences = group.findPreference(KEY_LOCKSCREEN_PREFERENCES);
         if (lockscreenPreferences != null) {
             lockscreenPreferences.setSummary(
-                mLockScreenNotificationPreferenceController.getSummaryResource());
+                LockScreenNotificationPreferenceController.getSummaryResource(getContext()));
         }
     }
 
diff --git a/src/com/android/settings/security/SecuritySettingsV2.java b/src/com/android/settings/security/SecuritySettingsV2.java
index 002e447..7ae6ca7 100644
--- a/src/com/android/settings/security/SecuritySettingsV2.java
+++ b/src/com/android/settings/security/SecuritySettingsV2.java
@@ -1,25 +1,16 @@
 package com.android.settings.security;
 
-import static com.android.settings.security.EncryptionStatusPreferenceController
-        .PREF_KEY_ENCRYPTION_SECURITY_PAGE;
+import static com.android.settings.security.EncryptionStatusPreferenceController.PREF_KEY_ENCRYPTION_SECURITY_PAGE;
 
 import android.app.Activity;
-import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.Intent;
-import android.content.res.Resources;
 import android.hardware.fingerprint.FingerprintManager;
-import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.StorageManager;
 import android.provider.SearchIndexableResource;
-import android.support.annotation.VisibleForTesting;
-import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
 import android.support.v7.preference.PreferenceScreen;
-import android.text.TextUtils;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.widget.LockPatternUtils;
@@ -30,96 +21,62 @@
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.enterprise.EnterprisePrivacyPreferenceController;
 import com.android.settings.enterprise.ManageDeviceAdminPreferenceController;
-import com.android.settings.fingerprint.FingerprintSettings;
 import com.android.settings.location.LocationPreferenceController;
-import com.android.settings.notification.LockScreenNotificationPreferenceController;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.password.ChooseLockGeneric;
 import com.android.settings.password.ChooseLockSettingsHelper;
-import com.android.settings.password.ManagedLockPasswordProvider;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.SearchIndexableRaw;
-import com.android.settings.security.screenlock.ScreenLockSettings;
 import com.android.settings.security.trustagent.ManageTrustAgentsPreferenceController;
 import com.android.settings.security.trustagent.TrustAgentListPreferenceController;
-import com.android.settings.widget.GearPreference;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedPreference;
-import com.android.settingslib.RestrictedSwitchPreference;
 import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.drawer.CategoryKey;
 
 import java.util.ArrayList;
 import java.util.List;
 
-public class SecuritySettingsV2 extends DashboardFragment
-        implements Preference.OnPreferenceChangeListener,
-        GearPreference.OnGearClickListener {
+public class SecuritySettingsV2 extends DashboardFragment {
 
     private static final String TAG = "SecuritySettingsV2";
 
-    // Lock Settings
-    private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
-    private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
-    private static final String KEY_VISIBLE_PATTERN_PROFILE = "visiblepattern_profile";
-    private static final String KEY_SECURITY_CATEGORY = "security_category";
-    private static final String KEY_UNIFICATION = "unification";
-    @VisibleForTesting
-    static final String KEY_LOCKSCREEN_PREFERENCES = "lockscreen_preferences";
-    private static final String KEY_ENCRYPTION_AND_CREDENTIALS = "encryption_and_credential";
-    private static final String KEY_LOCATION_SCANNING = "location_scanning";
-    private static final String KEY_LOCATION = "location";
-
-    private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
+    public static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
     public static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
-    private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE = 127;
-    private static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 128;
-    private static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
-    private static final int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130;
-    private static final String TAG_UNIFICATION_DIALOG = "unification_dialog";
+    public static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE = 127;
+    public static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 128;
+    public static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
+    public static final int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130;
+
 
     // Security status
     private static final String KEY_SECURITY_STATUS = "security_status";
     private static final String SECURITY_STATUS_KEY_PREFIX = "security_status_";
 
-    // Device management settings
-    private static final String KEY_ENTERPRISE_PRIVACY = "enterprise_privacy";
-    private static final String KEY_MANAGE_DEVICE_ADMIN = "manage_device_admin";
-
-    // These switch preferences need special handling since they're not all stored in Settings.
-    private static final String SWITCH_PREFERENCE_KEYS[] = {
-            KEY_UNIFICATION, KEY_VISIBLE_PATTERN_PROFILE
-    };
-
     private static final int MY_USER_ID = UserHandle.myUserId();
 
     private DashboardFeatureProvider mDashboardFeatureProvider;
-    private DevicePolicyManager mDPM;
     private SecurityFeatureProvider mSecurityFeatureProvider;
     private UserManager mUm;
 
     private ChooseLockSettingsHelper mChooseLockSettingsHelper;
     private LockPatternUtils mLockPatternUtils;
-    private ManagedLockPasswordProvider mManagedPasswordProvider;
-
-    private SwitchPreference mVisiblePatternProfile;
-    private RestrictedSwitchPreference mUnifyProfile;
 
     private int mProfileChallengeUserId;
 
-    private String mCurrentDevicePassword;
-    private String mCurrentProfilePassword;
-
     private LocationPreferenceController mLocationController;
     private ManageDeviceAdminPreferenceController mManageDeviceAdminPreferenceController;
     private EnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController;
     private EncryptionStatusPreferenceController mEncryptionStatusPreferenceController;
-    private LockScreenNotificationPreferenceController mLockScreenNotificationPreferenceController;
     private ManageTrustAgentsPreferenceController mManageTrustAgentsPreferenceController;
     private ScreenPinningPreferenceController mScreenPinningPreferenceController;
     private SimLockPreferenceController mSimLockPreferenceController;
     private ShowPasswordPreferenceController mShowPasswordPreferenceController;
     private TrustAgentListPreferenceController mTrustAgentListPreferenceController;
+    private LockScreenPreferenceController mLockScreenPreferenceController;
+    private ChangeScreenLockPreferenceController mChangeScreenLockPreferenceController;
+    private ChangeProfileScreenLockPreferenceController
+            mChangeProfileScreenLockPreferenceController;
+    private LockUnificationPreferenceController mLockUnificationPreferenceController;
+    private VisiblePatternProfilePreferenceController mVisiblePatternProfilePreferenceController;
+    private FingerprintStatusPreferenceController mFingerprintStatusPreferenceController;
+    private FingerprintProfileStatusPreferenceController
+            mFingerprintProfileStatusPreferenceController;
 
     @Override
     public int getMetricsCategory() {
@@ -132,8 +89,6 @@
         mSecurityFeatureProvider = FeatureFactory.getFactory(context).getSecurityFeatureProvider();
         mLocationController = new LocationPreferenceController(context, getLifecycle());
         mLockPatternUtils = mSecurityFeatureProvider.getLockPatternUtils(context);
-        mManagedPasswordProvider = ManagedLockPasswordProvider.get(context, MY_USER_ID);
-        mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
         mUm = UserManager.get(context);
         mDashboardFeatureProvider = FeatureFactory.getFactory(context)
                 .getDashboardFeatureProvider(context);
@@ -151,14 +106,18 @@
         return TAG;
     }
 
+
+    @Override
+    public int getHelpResource() {
+        return R.string.help_url_security;
+    }
+
     @Override
     protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
         mManageDeviceAdminPreferenceController
                 = new ManageDeviceAdminPreferenceController(context);
         mEnterprisePrivacyPreferenceController
                 = new EnterprisePrivacyPreferenceController(context);
-        mLockScreenNotificationPreferenceController
-                = new LockScreenNotificationPreferenceController(context);
         mManageTrustAgentsPreferenceController = new ManageTrustAgentsPreferenceController(context);
         mScreenPinningPreferenceController = new ScreenPinningPreferenceController(context);
         mSimLockPreferenceController = new SimLockPreferenceController(context);
@@ -167,46 +126,21 @@
                 context, PREF_KEY_ENCRYPTION_SECURITY_PAGE);
         mTrustAgentListPreferenceController = new TrustAgentListPreferenceController(getActivity(),
                 this /* host */, getLifecycle());
+        mLockScreenPreferenceController = new LockScreenPreferenceController(context);
+        mChangeScreenLockPreferenceController = new ChangeScreenLockPreferenceController(context,
+                this /* host */);
+        mChangeProfileScreenLockPreferenceController =
+                new ChangeProfileScreenLockPreferenceController(context, this /* host */);
+        mLockUnificationPreferenceController = new LockUnificationPreferenceController(context,
+                this /* host */);
+        mVisiblePatternProfilePreferenceController =
+                new VisiblePatternProfilePreferenceController(context);
+        mFingerprintStatusPreferenceController = new FingerprintStatusPreferenceController(context);
+        mFingerprintProfileStatusPreferenceController =
+                new FingerprintProfileStatusPreferenceController(context);
         return null;
     }
 
-    private static int getResIdForLockUnlockScreen(LockPatternUtils lockPatternUtils,
-            ManagedLockPasswordProvider managedPasswordProvider, int userId) {
-        final boolean isMyUser = userId == MY_USER_ID;
-        int resid = 0;
-        if (!lockPatternUtils.isSecure(userId)) {
-            if (!isMyUser) {
-                resid = R.xml.security_settings_lockscreen_profile;
-            } else if (lockPatternUtils.isLockScreenDisabled(userId)) {
-                resid = R.xml.security_settings_lockscreen;
-            } else {
-                resid = R.xml.security_settings_chooser;
-            }
-        } else {
-            switch (lockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
-                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
-                    resid = isMyUser ? R.xml.security_settings_pattern
-                            : R.xml.security_settings_pattern_profile;
-                    break;
-                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
-                    resid = isMyUser ? R.xml.security_settings_pin
-                            : R.xml.security_settings_pin_profile;
-                    break;
-                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
-                    resid = isMyUser ? R.xml.security_settings_password
-                            : R.xml.security_settings_password_profile;
-                    break;
-                case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
-                    resid = managedPasswordProvider.getResIdForLockUnlockScreen(!isMyUser);
-                    break;
-            }
-        }
-        return resid;
-    }
-
     /**
      * Important!
      *
@@ -214,65 +148,15 @@
      * logic or adding/removing preferences here.
      */
     private PreferenceScreen createPreferenceHierarchy() {
-        PreferenceScreen root = getPreferenceScreen();
-        if (root != null) {
-            root.removeAll();
-        }
-        addPreferencesFromResource(R.xml.security_settings_v2);
-        root = getPreferenceScreen();
+        final PreferenceScreen root = getPreferenceScreen();
         mTrustAgentListPreferenceController.displayPreference(root);
-
-        // Add options for lock/unlock screen
-        final int resid = getResIdForLockUnlockScreen(mLockPatternUtils,
-                mManagedPasswordProvider, MY_USER_ID);
-        addPreferencesFromResource(resid);
-
-        // DO or PO installed in the user may disallow to change password.
-        disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE, MY_USER_ID);
-
-        mProfileChallengeUserId = Utils.getManagedProfileId(mUm, MY_USER_ID);
-        if (mProfileChallengeUserId != UserHandle.USER_NULL
-                && mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId)) {
-            addPreferencesFromResource(R.xml.security_settings_profile);
-            addPreferencesFromResource(R.xml.security_settings_unification);
-            final int profileResid = getResIdForLockUnlockScreen(mLockPatternUtils,
-                    mManagedPasswordProvider, mProfileChallengeUserId);
-            addPreferencesFromResource(profileResid);
-            maybeAddFingerprintPreference(root, mProfileChallengeUserId);
-            if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
-                final Preference lockPreference =
-                        root.findPreference(KEY_UNLOCK_SET_OR_CHANGE_PROFILE);
-                final String summary = getContext().getString(
-                        R.string.lock_settings_profile_unified_summary);
-                lockPreference.setSummary(summary);
-                lockPreference.setEnabled(false);
-                // PO may disallow to change password for the profile, but screen lock and managed
-                // profile's lock is the same. Disable main "Screen lock" menu.
-                disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE, mProfileChallengeUserId);
-            } else {
-                // PO may disallow to change profile password, and the profile's password is
-                // separated from screen lock password. Disable profile specific "Screen lock" menu.
-                disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE_PROFILE,
-                        mProfileChallengeUserId);
-            }
-        }
-        Preference unlockSetOrChange = findPreference(KEY_UNLOCK_SET_OR_CHANGE);
-        if (unlockSetOrChange instanceof GearPreference) {
-            ((GearPreference) unlockSetOrChange).setOnGearClickListener(this);
-        }
-
-
-        // Fingerprint and trust agents
-        PreferenceGroup securityCategory = (PreferenceGroup)
-                root.findPreference(KEY_SECURITY_CATEGORY);
-        if (securityCategory != null) {
-            maybeAddFingerprintPreference(securityCategory, UserHandle.myUserId());
-            setLockscreenPreferencesSummary(securityCategory);
-        }
-
-        mVisiblePatternProfile =
-                (SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN_PROFILE);
-        mUnifyProfile = (RestrictedSwitchPreference) root.findPreference(KEY_UNIFICATION);
+        mLockScreenPreferenceController.displayPreference(root);
+        mChangeScreenLockPreferenceController.displayPreference(root);
+        mChangeProfileScreenLockPreferenceController.displayPreference(root);
+        mLockUnificationPreferenceController.displayPreference(root);
+        mVisiblePatternProfilePreferenceController.displayPreference(root);
+        mFingerprintStatusPreferenceController.displayPreference(root);
+        mFingerprintProfileStatusPreferenceController.displayPreference(root);
 
         mSimLockPreferenceController.displayPreference(root);
         mScreenPinningPreferenceController.displayPreference(root);
@@ -280,45 +164,40 @@
         // Advanced Security features
         mManageTrustAgentsPreferenceController.displayPreference(root);
 
-        PreferenceGroup securityStatusPreferenceGroup =
-                (PreferenceGroup) root.findPreference(KEY_SECURITY_STATUS);
-        final List<Preference> tilePrefs = mDashboardFeatureProvider.getPreferencesForCategory(
-                getActivity(), getPrefContext(), getMetricsCategory(),
-                CategoryKey.CATEGORY_SECURITY);
-        int numSecurityStatusPrefs = 0;
-        if (tilePrefs != null && !tilePrefs.isEmpty()) {
-            for (Preference preference : tilePrefs) {
-                if (!TextUtils.isEmpty(preference.getKey())
-                        && preference.getKey().startsWith(SECURITY_STATUS_KEY_PREFIX)) {
-                    // Injected security status settings are placed under the Security status
-                    // category.
-                    securityStatusPreferenceGroup.addPreference(preference);
-                    numSecurityStatusPrefs++;
-                } else {
-                    // Other injected settings are placed under the Security preference screen.
-                    root.addPreference(preference);
-                }
-            }
-        }
-
-        if (numSecurityStatusPrefs == 0) {
-            root.removePreference(securityStatusPreferenceGroup);
-        } else if (numSecurityStatusPrefs > 0) {
-            // Update preference data with tile data. Security feature provider only updates the
-            // data if it actually needs to be changed.
-            mSecurityFeatureProvider.updatePreferences(getActivity(), root,
-                    mDashboardFeatureProvider.getTilesForCategory(
-                            CategoryKey.CATEGORY_SECURITY));
-        }
-
-        for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) {
-            final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]);
-            if (pref != null) pref.setOnPreferenceChangeListener(this);
-        }
+//        PreferenceGroup securityStatusPreferenceGroup =
+//                (PreferenceGroup) root.findPreference(KEY_SECURITY_STATUS);
+//        final List<Preference> tilePrefs = mDashboardFeatureProvider.getPreferencesForCategory(
+//                getActivity(), getPrefContext(), getMetricsCategory(),
+//                CategoryKey.CATEGORY_SECURITY);
+//        int numSecurityStatusPrefs = 0;
+//        if (tilePrefs != null && !tilePrefs.isEmpty()) {
+//            for (Preference preference : tilePrefs) {
+//                if (!TextUtils.isEmpty(preference.getKey())
+//                        && preference.getKey().startsWith(SECURITY_STATUS_KEY_PREFIX)) {
+//                    // Injected security status settings are placed under the Security status
+//                    // category.
+//                    securityStatusPreferenceGroup.addPreference(preference);
+//                    numSecurityStatusPrefs++;
+//                } else {
+//                    // Other injected settings are placed under the Security preference screen.
+//                    root.addPreference(preference);
+//                }
+//            }
+//        }
+//
+//        if (numSecurityStatusPrefs == 0) {
+//            root.removePreference(securityStatusPreferenceGroup);
+//        } else if (numSecurityStatusPrefs > 0) {
+//            // Update preference data with tile data. Security feature provider only updates the
+//            // data if it actually needs to be changed.
+//            mSecurityFeatureProvider.updatePreferences(getActivity(), root,
+//                    mDashboardFeatureProvider.getTilesForCategory(
+//                            CategoryKey.CATEGORY_SECURITY));
+//        }
 
         mLocationController.displayPreference(root);
         mManageDeviceAdminPreferenceController.updateState(
-                root.findPreference(KEY_MANAGE_DEVICE_ADMIN));
+                root.findPreference(mManageDeviceAdminPreferenceController.getPreferenceKey()));
         mEnterprisePrivacyPreferenceController.displayPreference(root);
         final Preference enterprisePrivacyPreference = root.findPreference(
                 mEnterprisePrivacyPreferenceController.getPreferenceKey());
@@ -327,47 +206,6 @@
         return root;
     }
 
-    @VisibleForTesting
-    void setLockscreenPreferencesSummary(PreferenceGroup group) {
-        final Preference lockscreenPreferences = group.findPreference(KEY_LOCKSCREEN_PREFERENCES);
-        if (lockscreenPreferences != null) {
-            lockscreenPreferences.setSummary(
-                    mLockScreenNotificationPreferenceController.getSummaryResource());
-        }
-    }
-
-    /*
-     * Sets the preference as disabled by admin if PASSWORD_QUALITY_MANAGED is set.
-     * The preference must be a RestrictedPreference.
-     */
-    private void disableIfPasswordQualityManaged(String preferenceKey, int userId) {
-        final RestrictedLockUtils.EnforcedAdmin admin =
-                RestrictedLockUtils.checkIfPasswordQualityIsSet(
-                        getActivity(), userId);
-        if (admin != null && mDPM.getPasswordQuality(admin.component, userId) ==
-                DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
-            final RestrictedPreference pref =
-                    (RestrictedPreference) getPreferenceScreen().findPreference(preferenceKey);
-            pref.setDisabledByAdmin(admin);
-        }
-    }
-
-    private void maybeAddFingerprintPreference(PreferenceGroup securityCategory, int userId) {
-        Preference fingerprintPreference =
-                FingerprintSettings.getFingerprintPreferenceForUser(
-                        securityCategory.getContext(), userId);
-        if (fingerprintPreference != null) {
-            securityCategory.addPreference(fingerprintPreference);
-        }
-    }
-
-    @Override
-    public void onGearClick(GearPreference p) {
-        if (KEY_UNLOCK_SET_OR_CHANGE.equals(p.getKey())) {
-            startFragment(this, ScreenLockSettings.class.getName(), 0, 0, null);
-        }
-    }
-
     @Override
     public void onResume() {
         super.onResume();
@@ -376,18 +214,40 @@
         // depend on others...
         createPreferenceHierarchy();
 
-        if (mVisiblePatternProfile != null) {
-            mVisiblePatternProfile.setChecked(mLockPatternUtils.isVisiblePatternEnabled(
-                    mProfileChallengeUserId));
+        final Preference visiblePatternProfilePref = getPreferenceScreen().findPreference(
+                mVisiblePatternProfilePreferenceController.getPreferenceKey());
+        if (visiblePatternProfilePref != null) {
+            visiblePatternProfilePref
+                    .setOnPreferenceChangeListener(mVisiblePatternProfilePreferenceController);
+            mVisiblePatternProfilePreferenceController.updateState(visiblePatternProfilePref);
         }
 
-        updateUnificationPreference();
-
         final Preference showPasswordPref = getPreferenceScreen().findPreference(
                 mShowPasswordPreferenceController.getPreferenceKey());
         showPasswordPref.setOnPreferenceChangeListener(mShowPasswordPreferenceController);
         mShowPasswordPreferenceController.updateState(showPasswordPref);
 
+        final Preference lockUnificationPref = getPreferenceScreen().findPreference(
+                mLockUnificationPreferenceController.getPreferenceKey());
+        lockUnificationPref.setOnPreferenceChangeListener(mLockUnificationPreferenceController);
+        mLockUnificationPreferenceController.updateState(lockUnificationPref);
+
+        final Preference changeDeviceLockPref = getPreferenceScreen().findPreference(
+                mChangeScreenLockPreferenceController.getPreferenceKey());
+        mChangeScreenLockPreferenceController.updateState(changeDeviceLockPref);
+
+        mFingerprintStatusPreferenceController.updateState(
+                getPreferenceScreen().findPreference(
+                        mFingerprintStatusPreferenceController.getPreferenceKey()));
+
+        mFingerprintProfileStatusPreferenceController.updateState(
+                getPreferenceScreen().findPreference(
+                        mFingerprintProfileStatusPreferenceController.getPreferenceKey()));
+
+        final Preference changeProfileLockPref = getPreferenceScreen().findPreference(
+                mChangeProfileScreenLockPreferenceController.getPreferenceKey());
+        mChangeProfileScreenLockPreferenceController.updateState(changeProfileLockPref);
+
         final Preference encryptionStatusPref = getPreferenceScreen().findPreference(
                 mEncryptionStatusPreferenceController.getPreferenceKey());
         mEncryptionStatusPreferenceController.updateState(encryptionStatusPref);
@@ -395,56 +255,20 @@
         mLocationController.updateSummary();
     }
 
-    @VisibleForTesting
-    void updateUnificationPreference() {
-        if (mUnifyProfile != null) {
-            final boolean separate =
-                    mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId);
-            mUnifyProfile.setChecked(!separate);
-            if (separate) {
-                mUnifyProfile.setDisabledByAdmin(RestrictedLockUtils.checkIfRestrictionEnforced(
-                        getContext(), UserManager.DISALLOW_UNIFIED_PASSWORD,
-                        mProfileChallengeUserId));
-            }
-        }
-    }
 
     @Override
     public boolean onPreferenceTreeClick(Preference preference) {
         if (mTrustAgentListPreferenceController.handlePreferenceTreeClick(preference)) {
             return true;
         }
-        final String key = preference.getKey();
-        if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) {
-            // TODO(b/35930129): Remove once existing password can be passed into vold directly.
-            // Currently we need this logic to ensure that the QUIET_MODE is off for any work
-            // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
-            // able to complete the operation due to the lack of (old) encryption key.
-            if (mProfileChallengeUserId != UserHandle.USER_NULL
-                    && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
-                    && StorageManager.isFileEncryptedNativeOnly()) {
-                if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
-                        mProfileChallengeUserId)) {
-                    return false;
-                }
-            }
-            startFragment(this, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
-                    R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
-        } else if (KEY_UNLOCK_SET_OR_CHANGE_PROFILE.equals(key)) {
-            if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
-                    mProfileChallengeUserId)) {
-                return false;
-            }
-            Bundle extras = new Bundle();
-            extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
-            startFragment(this, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
-                    R.string.lock_settings_picker_title_profile,
-                    SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
-        } else {
-            // If we didn't handle it, let preferences handle it.
-            return super.onPreferenceTreeClick(preference);
+        if (mChangeScreenLockPreferenceController.handlePreferenceTreeClick(preference)) {
+            return true;
         }
-        return true;
+        if (mChangeProfileScreenLockPreferenceController.handlePreferenceTreeClick(preference)) {
+            return true;
+        }
+        // If we didn't handle it, let preferences handle it.
+        return super.onPreferenceTreeClick(preference);
     }
 
     /**
@@ -453,139 +277,34 @@
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
-        if (requestCode == CHANGE_TRUST_AGENT_SETTINGS && resultCode == Activity.RESULT_OK) {
-            mTrustAgentListPreferenceController.handleActivityResult(resultCode);
+        if (mTrustAgentListPreferenceController.handleActivityResult(requestCode, resultCode)) {
             return;
-        } else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST
-                && resultCode == Activity.RESULT_OK) {
-            mCurrentDevicePassword =
-                    data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
-            launchConfirmProfileLockForUnification();
-            return;
-        } else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST
-                && resultCode == Activity.RESULT_OK) {
-            mCurrentProfilePassword =
-                    data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
-            unifyLocks();
-            return;
-        } else if (requestCode == UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST
-                && resultCode == Activity.RESULT_OK) {
-            ununifyLocks();
+        }
+        if (mLockUnificationPreferenceController.handleActivityResult(
+                requestCode, resultCode, data)) {
             return;
         }
         createPreferenceHierarchy();
     }
 
-    void launchConfirmDeviceLockForUnification() {
-        final String title = getActivity().getString(
-                R.string.unlock_set_unlock_launch_picker_title);
-        final ChooseLockSettingsHelper helper =
-                new ChooseLockSettingsHelper(getActivity(), this);
-        if (!helper.launchConfirmationActivity(
-                UNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
-            launchConfirmProfileLockForUnification();
-        }
-    }
-
-    private void launchConfirmProfileLockForUnification() {
-        final String title = getActivity().getString(
-                R.string.unlock_set_unlock_launch_picker_title_profile);
-        final ChooseLockSettingsHelper helper =
-                new ChooseLockSettingsHelper(getActivity(), this);
-        if (!helper.launchConfirmationActivity(
-                UNIFY_LOCK_CONFIRM_PROFILE_REQUEST, title, true, mProfileChallengeUserId)) {
-            unifyLocks();
-            createPreferenceHierarchy();
-        }
-    }
-
-    private void unifyLocks() {
-        int profileQuality =
-                mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId);
-        if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
-            mLockPatternUtils.saveLockPattern(
-                    LockPatternUtils.stringToPattern(mCurrentProfilePassword),
-                    mCurrentDevicePassword, MY_USER_ID);
-        } else {
-            mLockPatternUtils.saveLockPassword(
-                    mCurrentProfilePassword, mCurrentDevicePassword,
-                    profileQuality, MY_USER_ID);
-        }
-        mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
-                mCurrentProfilePassword);
-        final boolean profilePatternVisibility =
-                mLockPatternUtils.isVisiblePatternEnabled(mProfileChallengeUserId);
-        mLockPatternUtils.setVisiblePatternEnabled(profilePatternVisibility, MY_USER_ID);
-        mCurrentDevicePassword = null;
-        mCurrentProfilePassword = null;
-    }
-
-    void unifyUncompliantLocks() {
-        mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
-                mCurrentProfilePassword);
-        startFragment(this, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
-                R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
-    }
-
-    private void ununifyLocks() {
-        Bundle extras = new Bundle();
-        extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
-        startFragment(this,
-                ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
-                R.string.lock_settings_picker_title_profile,
-                SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object value) {
-        boolean result = true;
-        final String key = preference.getKey();
-        final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
-        if (KEY_VISIBLE_PATTERN_PROFILE.equals(key)) {
-            if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
-                    mProfileChallengeUserId)) {
-                return false;
-            }
-            lockPatternUtils.setVisiblePatternEnabled((Boolean) value, mProfileChallengeUserId);
-        } else if (KEY_UNIFICATION.equals(key)) {
-            if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
-                    mProfileChallengeUserId)) {
-                return false;
-            }
-            if ((Boolean) value) {
-                final boolean compliantForDevice =
-                        (mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
-                                >= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
-                                && mLockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
-                                mProfileChallengeUserId));
-                UnificationConfirmationDialog dialog =
-                        UnificationConfirmationDialog.newIntance(compliantForDevice);
-                dialog.show(getChildFragmentManager(), TAG_UNIFICATION_DIALOG);
-            } else {
-                final String title = getActivity().getString(
-                        R.string.unlock_set_unlock_launch_picker_title);
-                final ChooseLockSettingsHelper helper =
-                        new ChooseLockSettingsHelper(getActivity(), this);
-                if (!helper.launchConfirmationActivity(
-                        UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
-                    ununifyLocks();
-                }
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public int getHelpResource() {
-        return R.string.help_url_security;
-    }
-
     /**
      * For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
      */
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new SecuritySearchIndexProvider();
 
+    void launchConfirmDeviceLockForUnification() {
+        mLockUnificationPreferenceController.launchConfirmDeviceLockForUnification();
+    }
+
+    void unifyUncompliantLocks() {
+        mLockUnificationPreferenceController.unifyUncompliantLocks();
+    }
+
+    void updateUnificationPreference() {
+        mLockUnificationPreferenceController.updateState(null);
+    }
+
     private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider {
 
         // TODO (b/68001777) Refactor indexing to include all XML and block other settings.
@@ -594,123 +313,11 @@
         public List<SearchIndexableResource> getXmlResourcesToIndex(
                 Context context, boolean enabled) {
             final List<SearchIndexableResource> index = new ArrayList<>();
-
-            final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
-            final ManagedLockPasswordProvider managedPasswordProvider =
-                    ManagedLockPasswordProvider.get(context, MY_USER_ID);
-            final DevicePolicyManager dpm = (DevicePolicyManager)
-                    context.getSystemService(Context.DEVICE_POLICY_SERVICE);
-            final UserManager um = UserManager.get(context);
-            final int profileUserId = Utils.getManagedProfileId(um, MY_USER_ID);
-
-            // To add option for unlock screen, user's password must not be managed and
-            // must not be unified with managed profile, whose password is managed.
-            if (!isPasswordManaged(MY_USER_ID, context, dpm)
-                    && (profileUserId == UserHandle.USER_NULL
-                    || lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
-                    || !isPasswordManaged(profileUserId, context, dpm))) {
-                // Add options for lock/unlock screen
-                final int resId = getResIdForLockUnlockScreen(lockPatternUtils,
-                        managedPasswordProvider, MY_USER_ID);
-                index.add(getSearchResource(context, resId));
-            }
-
-            if (profileUserId != UserHandle.USER_NULL
-                    && lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
-                    && !isPasswordManaged(profileUserId, context, dpm)) {
-                index.add(getSearchResource(context, getResIdForLockUnlockScreen(
-                        lockPatternUtils, managedPasswordProvider, profileUserId)));
-            }
-
             // Append the rest of the settings
-            index.add(getSearchResource(context, R.xml.security_settings_misc));
-
-            return index;
-        }
-
-        private SearchIndexableResource getSearchResource(Context context, int xmlResId) {
             final SearchIndexableResource sir = new SearchIndexableResource(context);
-            sir.xmlResId = xmlResId;
-            return sir;
-        }
-
-        private boolean isPasswordManaged(int userId, Context context, DevicePolicyManager dpm) {
-            final RestrictedLockUtils.EnforcedAdmin admin =
-                    RestrictedLockUtils.checkIfPasswordQualityIsSet(
-                            context, userId);
-            return admin != null && dpm.getPasswordQuality(admin.component, userId) ==
-                    DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
-        }
-
-        @Override
-        public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
-            final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
-            final Resources res = context.getResources();
-
-            final String screenTitle = res.getString(R.string.security_settings_title);
-
-            SearchIndexableRaw data = new SearchIndexableRaw(context);
-            data.title = screenTitle;
-            data.key = "security_settings_screen";
-            data.screenTitle = screenTitle;
-            result.add(data);
-
-            final UserManager um = UserManager.get(context);
-
-            // Fingerprint
-            final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(context);
-            if (fpm != null && fpm.isHardwareDetected()) {
-                // This catches the title which can be overloaded in an overlay
-                data = new SearchIndexableRaw(context);
-                data.title = res.getString(R.string.security_settings_fingerprint_preference_title);
-                data.key = "security_fingerprint";
-                data.screenTitle = screenTitle;
-                result.add(data);
-                // Fallback for when the above doesn't contain "fingerprint"
-                data = new SearchIndexableRaw(context);
-                data.title = res.getString(R.string.fingerprint_manage_category_title);
-                data.key = "security_managed_fingerprint";
-                data.screenTitle = screenTitle;
-                result.add(data);
-            }
-
-            final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
-            final int profileUserId = Utils.getManagedProfileId(um, MY_USER_ID);
-            if (profileUserId != UserHandle.USER_NULL
-                    && lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)) {
-                if (lockPatternUtils.getKeyguardStoredPasswordQuality(profileUserId)
-                        >= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
-                        && lockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
-                        profileUserId)) {
-                    data = new SearchIndexableRaw(context);
-                    data.title = res.getString(R.string.lock_settings_profile_unification_title);
-                    data.key = "security_use_one_lock";
-                    data.screenTitle = screenTitle;
-                    result.add(data);
-                }
-            }
-            return result;
-        }
-
-        @Override
-        public List<String> getNonIndexableKeys(Context context) {
-            final List<String> keys = super.getNonIndexableKeys(context);
-
-            new SimLockPreferenceController(context).updateNonIndexableKeys(keys);
-
-            if (!(new EnterprisePrivacyPreferenceController(context))
-                    .isAvailable()) {
-                keys.add(KEY_ENTERPRISE_PRIVACY);
-            }
-
-            // Duplicate in special app access
-            keys.add(KEY_MANAGE_DEVICE_ADMIN);
-            // Duplicates between parent-child
-            keys.add(KEY_LOCATION);
-            keys.add(KEY_ENCRYPTION_AND_CREDENTIALS);
-            keys.add(KEY_LOCATION_SCANNING);
-
-            return keys;
+            sir.xmlResId = R.xml.security_settings_v2;
+            index.add(sir);
+            return index;
         }
     }
 
diff --git a/src/com/android/settings/security/ShowPasswordPreferenceController.java b/src/com/android/settings/security/ShowPasswordPreferenceController.java
index 9f9b52d..d0216e8 100644
--- a/src/com/android/settings/security/ShowPasswordPreferenceController.java
+++ b/src/com/android/settings/security/ShowPasswordPreferenceController.java
@@ -44,10 +44,11 @@
     }
 
     @Override
-    public void setChecked(boolean isChecked) {
+    public boolean setChecked(boolean isChecked) {
         Settings.System.putInt(mContext.getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
                 isChecked ? 1 : 0);
         mLockPatternUtils.setVisiblePasswordEnabled(isChecked, MY_USER_ID);
+        return true;
     }
 
     @Override
diff --git a/src/com/android/settings/security/UnificationConfirmationDialog.java b/src/com/android/settings/security/UnificationConfirmationDialog.java
index 21118d7..482e268 100644
--- a/src/com/android/settings/security/UnificationConfirmationDialog.java
+++ b/src/com/android/settings/security/UnificationConfirmationDialog.java
@@ -27,9 +27,11 @@
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 
 public class UnificationConfirmationDialog extends InstrumentedDialogFragment {
+
+    static final String TAG_UNIFICATION_DIALOG = "unification_dialog";
     private static final String EXTRA_COMPLIANT = "compliant";
 
-    public static UnificationConfirmationDialog newIntance(boolean compliant) {
+    public static UnificationConfirmationDialog newInstance(boolean compliant) {
         UnificationConfirmationDialog
                 dialog = new UnificationConfirmationDialog();
         Bundle args = new Bundle();
@@ -38,11 +40,11 @@
         return dialog;
     }
 
-    @Override
-    public void show(FragmentManager manager, String tag) {
-        if (manager.findFragmentByTag(tag) == null) {
+    public void show(SecuritySettingsV2 host) {
+        final FragmentManager manager = host.getChildFragmentManager();
+        if (manager.findFragmentByTag(TAG_UNIFICATION_DIALOG) == null) {
             // Prevent opening multiple dialogs if tapped on button quickly
-            super.show(manager, tag);
+            show(manager, TAG_UNIFICATION_DIALOG);
         }
     }
 
@@ -56,11 +58,12 @@
                         : R.string.lock_settings_profile_unification_dialog_uncompliant_body)
                 .setPositiveButton(
                         compliant ? R.string.lock_settings_profile_unification_dialog_confirm
-                                : R.string.lock_settings_profile_unification_dialog_uncompliant_confirm,
+                                : R.string
+                                        .lock_settings_profile_unification_dialog_uncompliant_confirm,
                         (dialog, whichButton) -> {
                             if (compliant) {
                                 parentFragment.launchConfirmDeviceLockForUnification();
-                            }    else {
+                            } else {
                                 parentFragment.unifyUncompliantLocks();
                             }
                         }
diff --git a/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java b/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java
new file mode 100644
index 0000000..39b1916
--- /dev/null
+++ b/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.Utils;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+
+public class VisiblePatternProfilePreferenceController extends TogglePreferenceController {
+
+    private static final String KEY_VISIBLE_PATTERN_PROFILE = "visiblepattern_profile";
+
+    private final LockPatternUtils mLockPatternUtils;
+    private final UserManager mUm;
+    private final int mUserId = UserHandle.myUserId();
+    private final int mProfileChallengeUserId;
+
+    public VisiblePatternProfilePreferenceController(Context context) {
+        super(context, KEY_VISIBLE_PATTERN_PROFILE);
+        mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        mLockPatternUtils = FeatureFactory.getFactory(context)
+                .getSecurityFeatureProvider()
+                .getLockPatternUtils(context);
+        mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (mLockPatternUtils.isSecure(mProfileChallengeUserId)
+                && mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
+                == PASSWORD_QUALITY_SOMETHING) {
+            return AVAILABLE;
+        }
+        return DISABLED_FOR_USER;
+    }
+
+    @Override
+    public boolean isChecked() {
+        return mLockPatternUtils.isVisiblePatternEnabled(
+                mProfileChallengeUserId);
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
+            return false;
+        }
+        mLockPatternUtils.setVisiblePatternEnabled(isChecked, mProfileChallengeUserId);
+        return true;
+    }
+}
diff --git a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java
index d99757b..8d198e7 100644
--- a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java
+++ b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.security.trustagent;
 
+import static com.android.settings.security.SecuritySettingsV2.CHANGE_TRUST_AGENT_SETTINGS;
+
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
@@ -113,7 +115,7 @@
         final ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(mActivity, mHost);
         mTrustAgentClickIntent = preference.getIntent();
         boolean confirmationLaunched = helper.launchConfirmationActivity(
-                SecuritySettingsV2.CHANGE_TRUST_AGENT_SETTINGS, preference.getTitle());
+                CHANGE_TRUST_AGENT_SETTINGS, preference.getTitle());
 
         if (!confirmationLaunched && mTrustAgentClickIntent != null) {
             // If this returns false, it means no password confirmation is required.
@@ -163,10 +165,14 @@
         }
     }
 
-    public void handleActivityResult(int resultCode) {
-        if (resultCode == Activity.RESULT_OK && mTrustAgentClickIntent != null) {
-            mHost.startActivity(mTrustAgentClickIntent);
-            mTrustAgentClickIntent = null;
+    public boolean handleActivityResult(int requestCode, int resultCode) {
+        if (requestCode == CHANGE_TRUST_AGENT_SETTINGS && resultCode == Activity.RESULT_OK) {
+            if (mTrustAgentClickIntent != null){
+                mHost.startActivity(mTrustAgentClickIntent);
+                mTrustAgentClickIntent = null;
+            }
+            return true;
         }
+        return false;
     }
 }
diff --git a/src/com/android/settings/widget/MasterSwitchPreference.java b/src/com/android/settings/widget/MasterSwitchPreference.java
index d47de88..73774be 100644
--- a/src/com/android/settings/widget/MasterSwitchPreference.java
+++ b/src/com/android/settings/widget/MasterSwitchPreference.java
@@ -22,7 +22,6 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Switch;
-import android.widget.TextView;
 
 import com.android.settings.R;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml
index d2e146b..7ae7c1f 100644
--- a/tests/robotests/res/values-mcc999/config.xml
+++ b/tests/robotests/res/values-mcc999/config.xml
@@ -21,7 +21,13 @@
     <bool name="config_show_connectivity_monitor">false</bool>
     <bool name="config_display_recent_apps">false</bool>
     <bool name="config_show_wifi_settings">false</bool>
+    <bool name="config_show_high_power_apps">false</bool>
+    <bool name="config_show_device_administrators">false</bool>
+    <bool name="config_show_premium_sms">false</bool>
+    <bool name="config_show_data_saver">false</bool>
+    <bool name="config_show_enabled_vr_listeners">false</bool>
     <bool name="config_location_mode_available">false</bool>
     <bool name="config_show_wallpaper_attribution">false</bool>
     <bool name="config_show_default_home">false</bool>
+    <bool name="config_show_accessibility_shortcut_preference">false</bool>
 </resources>
diff --git a/tests/robotests/src/com/android/internal/accessibility/AccessibilityShortcutController.java b/tests/robotests/src/com/android/internal/accessibility/AccessibilityShortcutController.java
new file mode 100644
index 0000000..aae2f8d
--- /dev/null
+++ b/tests/robotests/src/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -0,0 +1,42 @@
+/*
+ * 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.internal.accessibility;
+
+import android.content.ComponentName;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Fake controller to make robolectric test compile. Should be removed when Robolectric supports
+ * API 25.
+ */
+public class AccessibilityShortcutController {
+
+    public static Map<ComponentName, AccessibilityShortcutController.ToggleableFrameworkFeatureInfo>
+        getFrameworkShortcutFeaturesMap() {
+        return new HashMap<>();
+    }
+
+    public static class ToggleableFrameworkFeatureInfo {
+        private String mSettingKey;
+
+        public String getSettingKey() {
+            return mSettingKey;
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
index fb32da1..c721fc9 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
@@ -16,35 +16,92 @@
 
 package com.android.settings.accessibility;
 
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
 import android.content.Context;
+import android.support.v7.preference.Preference;
 
 import com.android.settings.R;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.XmlTestUtils;
+
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import static com.google.common.truth.Truth.assertThat;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class AccessibilitySettingsTest {
 
+    private Context mContext;
+    private AccessibilitySettings mFragment;
+    private boolean mAccessibilityShortcutPreferenceRemoved;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mFragment = new AccessibilitySettings() {
+            @Override
+            public Context getContext() {
+                return mContext;
+            }
+
+            @Override
+            protected boolean removePreference(String key) {
+                if (AccessibilitySettings.ACCESSIBILITY_SHORTCUT_PREFERENCE.equals(key)) {
+                    mAccessibilityShortcutPreferenceRemoved = true;
+
+                    return true;
+                }
+                return false;
+            }
+        };
+    }
+
     @Test
     public void testNonIndexableKeys_existInXmlLayout() {
-        final Context context = RuntimeEnvironment.application;
         final List<String> niks = AccessibilitySettings.SEARCH_INDEX_DATA_PROVIDER
-                .getNonIndexableKeys(context);
+                .getNonIndexableKeys(mContext);
         final List<String> keys = new ArrayList<>();
 
-        keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context, R.xml.accessibility_settings));
+        keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(mContext, R.xml.accessibility_settings));
 
         assertThat(keys).containsAllIn(niks);
     }
+
+    @Test
+    public void testAccessibilityShortcutPreference_byDefault_shouldBeShown() {
+        final Preference preference = new Preference(mContext);
+        mFragment.checkAccessibilityShortcutVisibility(preference);
+
+        assertThat(mAccessibilityShortcutPreferenceRemoved).isFalse();
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void testAccessibilityShortcutPreference_ifDisabled_shouldNotBeShown() {
+        final Preference preference = new Preference(mContext);
+        mFragment.checkAccessibilityShortcutVisibility(preference);
+
+        assertThat(mAccessibilityShortcutPreferenceRemoved).isTrue();
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void testNonIndexableKeys_ifAccessibilityShortcutNotVisible_containsKey() {
+        final List<String> niks = AccessibilitySettings.SEARCH_INDEX_DATA_PROVIDER
+                .getNonIndexableKeys(mContext);
+
+        assertThat(niks).contains(AccessibilitySettings.ACCESSIBILITY_SHORTCUT_PREFERENCE);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/applications/DataSaverControllerTest.java b/tests/robotests/src/com/android/settings/applications/DataSaverControllerTest.java
new file mode 100644
index 0000000..237aa71
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/DataSaverControllerTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class DataSaverControllerTest {
+
+    private Context mContext;
+    private DataSaverController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application.getApplicationContext());
+        mController = new DataSaverController(mContext);
+    }
+
+    @Test
+    public void testDataSaver_byDefault_shouldBeShown() {
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void testDataSaver_ifDisabled_shouldNotBeShown() {
+        assertThat(mController.isAvailable()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/DeviceAdministratorsControllerTest.java b/tests/robotests/src/com/android/settings/applications/DeviceAdministratorsControllerTest.java
new file mode 100644
index 0000000..5482cd1
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/DeviceAdministratorsControllerTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class DeviceAdministratorsControllerTest {
+
+    private Context mContext;
+    private DeviceAdministratorsController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application.getApplicationContext());
+        mController = new DeviceAdministratorsController(mContext);
+    }
+
+    @Test
+    public void testDeviceAdministrators_byDefault_shouldBeShown() {
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void testDeviceAdministrators_ifDisabled_shouldNotBeShown() {
+        assertThat(mController.isAvailable()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/EnabledVrListenersControllerTest.java b/tests/robotests/src/com/android/settings/applications/EnabledVrListenersControllerTest.java
new file mode 100644
index 0000000..5be2296
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/EnabledVrListenersControllerTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class EnabledVrListenersControllerTest {
+
+    private Context mContext;
+    private EnabledVrListenersController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application.getApplicationContext());
+        mController = new EnabledVrListenersController(mContext);
+    }
+
+    @Test
+    public void testEnabledVrListeners_byDefault_shouldBeShown() {
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void testEnabledVrListeners_ifDisabled_shouldNotBeShown() {
+        assertThat(mController.isAvailable()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/HighPowerAppsControllerTest.java b/tests/robotests/src/com/android/settings/applications/HighPowerAppsControllerTest.java
new file mode 100644
index 0000000..d84d9bf
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/HighPowerAppsControllerTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class HighPowerAppsControllerTest {
+
+    private Context mContext;
+    private HighPowerAppsController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application.getApplicationContext());
+        mController = new HighPowerAppsController(mContext);
+    }
+
+    @Test
+    public void testHighPowerApps_byDefault_shouldBeShown() {
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void testHighPowerApps_ifDisabled_shouldNotBeShown() {
+        assertThat(mController.isAvailable()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/PremiumSmsControllerTest.java b/tests/robotests/src/com/android/settings/applications/PremiumSmsControllerTest.java
new file mode 100644
index 0000000..0f454fc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/PremiumSmsControllerTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class PremiumSmsControllerTest {
+
+    private Context mContext;
+    private PremiumSmsController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application.getApplicationContext());
+        mController = new PremiumSmsController(mContext);
+    }
+
+    @Test
+    public void testPremiumSms_byDefault_shouldBeShown() {
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void testPremiumSms_ifDisabled_shouldNotBeShown() {
+        assertThat(mController.isAvailable()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/SpecialAccessSettingsTest.java b/tests/robotests/src/com/android/settings/applications/SpecialAccessSettingsTest.java
new file mode 100644
index 0000000..b0cf2f6
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/SpecialAccessSettingsTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.settings.applications;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SpecialAccessSettingsTest {
+
+  private Context mContext;
+  private SpecialAccessSettings mFragment;
+
+  @Before
+  public void setUp() {
+    MockitoAnnotations.initMocks(this);
+    mContext = spy(RuntimeEnvironment.application);
+    mFragment = new SpecialAccessSettings() {
+      @Override
+      public Context getContext() {
+        return mContext;
+      }
+    };
+  }
+
+  @Test
+  public void testSearchIndexProvider_shouldIndexResource() {
+    final List<SearchIndexableResource> indexRes =
+            SpecialAccessSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(mContext,
+                    true /* enabled */);
+    final List<String> niks =
+            SpecialAccessSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
+
+    assertThat(indexRes).isNotNull();
+    assertThat(indexRes.get(0).xmlResId).isEqualTo(R.xml.special_access);
+    assertThat(niks).isEmpty();
+  }
+
+  @Test
+  @Config(qualifiers = "mcc999")
+  public void testSearchIndexProvider_ifElementsAreNotShown_shouldNotBeIndexed() {
+    final List<String> niks =
+            SpecialAccessSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
+
+    assertThat(niks).contains(HighPowerAppsController.KEY_HIGH_POWER_APPS);
+    assertThat(niks).contains(DeviceAdministratorsController.KEY_DEVICE_ADMIN);
+    assertThat(niks).contains(PremiumSmsController.KEY_PREMIUM_SMS);
+    assertThat(niks).contains(DataSaverController.KEY_DATA_SAVER);
+    assertThat(niks).contains(EnabledVrListenersController.KEY_ENABLED_VR_LISTENERS);
+  }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java
index e44fdfb..8667f74 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java
@@ -96,8 +96,8 @@
         mController.isDefault = true;
 
         mController.updateState(mPreference);
-
-        verify(mPreference).setSummary(R.string.yes);
+        String yesString = mContext.getString(R.string.yes);
+        verify(mPreference).setSummary(yesString);
     }
 
     @Test
@@ -106,7 +106,8 @@
 
         mController.updateState(mPreference);
 
-        verify(mPreference).setSummary(R.string.no);
+        String noString = mContext.getString(R.string.no);
+        verify(mPreference).setSummary(noString);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/backup/BackupSettingsActivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/backup/BackupSettingsActivityPreferenceControllerTest.java
index 5fc3ebc..0c98ddc 100644
--- a/tests/robotests/src/com/android/settings/backup/BackupSettingsActivityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/backup/BackupSettingsActivityPreferenceControllerTest.java
@@ -77,8 +77,8 @@
         mBackupEnabled = true;
 
         mController.updateState(mBackupPreference);
-
-        verify(mBackupPreference).setSummary(R.string.accessibility_feature_state_on);
+        String summaryString = mContext.getString(R.string.accessibility_feature_state_on);
+        verify(mBackupPreference).setSummary(summaryString);
     }
 
     @Test
@@ -86,8 +86,8 @@
         mBackupEnabled = false;
 
         mController.updateState(mBackupPreference);
-
-        verify(mBackupPreference).setSummary(R.string.accessibility_feature_state_off);
+        String summaryString = mContext.getString(R.string.accessibility_feature_state_off);
+        verify(mBackupPreference).setSummary(summaryString);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java
index 2e094e2..c3515df 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java
@@ -63,13 +63,14 @@
         doReturn(mContext).when(mPreferenceScreen).getContext();
         mPreference = new Preference(mContext);
         mPreference.setKey(BluetoothDeviceNamePreferenceController.KEY_DEVICE_NAME);
-        mController = new BluetoothDeviceNamePreferenceController(
-                mContext, mLocalAdapter);
+        mController = spy(new BluetoothDeviceNamePreferenceController(
+                mContext, mLocalAdapter));
+        doReturn(DEVICE_NAME).when(mController).getDeviceName();
     }
 
     @Test
     public void testUpdateDeviceName_showSummaryWithDeviceName() {
-        mController.updateDeviceName(mPreference, DEVICE_NAME);
+        mController.updateDeviceName(mPreference);
 
         final CharSequence summary = mPreference.getSummary();
 
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java
index 62a0d42..faf9069 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -69,13 +70,14 @@
         mPreference = new Preference(mContext);
         mPreference.setKey(PREF_KEY);
 
-        mController = new BluetoothDeviceRenamePreferenceController(
-                mContext, PREF_KEY, mFragment, mLocalAdapter);
+        mController = spy(new BluetoothDeviceRenamePreferenceController(
+                mContext, PREF_KEY, mFragment, mLocalAdapter));
+        doReturn(DEVICE_NAME).when(mController).getDeviceName();
     }
 
     @Test
     public void testUpdateDeviceName_showSummaryWithDeviceName() {
-        mController.updateDeviceName(mPreference, DEVICE_NAME);
+        mController.updateDeviceName(mPreference);
 
         final CharSequence summary = mPreference.getSummary();
 
diff --git a/tests/robotests/src/com/android/settings/development/BluetoothInbandRingingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothInbandRingingPreferenceControllerTest.java
index 4074e25..d0552ec 100644
--- a/tests/robotests/src/com/android/settings/development/BluetoothInbandRingingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BluetoothInbandRingingPreferenceControllerTest.java
@@ -18,7 +18,7 @@
 
 
 import static com.android.settings.development.BluetoothInbandRingingPreferenceController
-        .BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY;
+        .BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -84,7 +84,7 @@
         mController.onPreferenceChange(mPreference, true /* new value */);
 
         final boolean mode = SettingsShadowSystemProperties.getBoolean(
-                BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY, false /* default */);
+                BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, false /* default */);
 
         assertThat(mode).isTrue();
     }
@@ -94,14 +94,14 @@
         mController.onPreferenceChange(mPreference, false /* new value */);
 
         final boolean mode = SettingsShadowSystemProperties.getBoolean(
-                BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY, false /* default */);
+                BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, false /* default */);
 
         assertThat(mode).isFalse();
     }
 
     @Test
     public void updateState_settingEnabled_preferenceShouldBeChecked() {
-        SettingsShadowSystemProperties.set(BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY,
+        SettingsShadowSystemProperties.set(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY,
                 Boolean.toString(true));
         mController.updateState(mPreference);
 
@@ -110,7 +110,7 @@
 
     @Test
     public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
-        SettingsShadowSystemProperties.set(BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY,
+        SettingsShadowSystemProperties.set(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY,
                 Boolean.toString(false));
         mController.updateState(mPreference);
 
@@ -122,11 +122,11 @@
         mController.onDeveloperOptionsDisabled();
 
         final boolean mode = SettingsShadowSystemProperties.getBoolean(
-                BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY, false /* default */);
+                BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, false /* default */);
 
-        assertThat(mode).isTrue();
+        assertThat(mode).isFalse();
         verify(mPreference).setEnabled(false);
-        verify(mPreference).setChecked(true);
+        verify(mPreference).setChecked(false);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java b/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java
index 231cce9..81e1481 100644
--- a/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java
@@ -17,7 +17,6 @@
 package com.android.settings.security;
 
 import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -35,14 +34,12 @@
 import android.os.UserManager;
 import android.os.UserManager.EnforcingUser;
 import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.notification.LockScreenNotificationPreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.XmlTestUtils;
@@ -162,24 +159,6 @@
     }
 
     @Test
-    public void testSetLockscreenPreferencesSummary_shouldSetSummaryFromLockScreenNotification() {
-        final Preference preference = mock(Preference.class);
-        final PreferenceGroup group = mock(PreferenceGroup.class);
-        when(group.findPreference(SecuritySettings.KEY_LOCKSCREEN_PREFERENCES))
-                .thenReturn(preference);
-        final LockScreenNotificationPreferenceController controller =
-                mock(LockScreenNotificationPreferenceController.class);
-
-        final SecuritySettings securitySettings = new SecuritySettings();
-        ReflectionHelpers.setField(securitySettings,
-                "mLockScreenNotificationPreferenceController", controller);
-
-        when(controller.getSummaryResource()).thenReturn(1234);
-        securitySettings.setLockscreenPreferencesSummary(group);
-        verify(preference).setSummary(1234);
-    }
-
-    @Test
     public void testNonIndexableKeys_existInXmlLayout() {
         final Context context = spy(RuntimeEnvironment.application);
         UserManager manager = mock(UserManager.class);