Merge "Move iccid number to sim status dialog"
diff --git a/res/layout/dialog_firmware_version.xml b/res/layout/dialog_firmware_version.xml
new file mode 100644
index 0000000..e49255f
--- /dev/null
+++ b/res/layout/dialog_firmware_version.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2017 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="@dimen/sim_content_padding">
+
+        <TextView
+            style="@style/device_info_dialog_label"
+            android:id="@+id/firmware_version_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/firmware_version"/>
+        <TextView
+            style="@style/device_info_dialog_value"
+            android:id="@+id/firmware_version_value"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+        <TextView
+            style="@style/device_info_dialog_label"
+            android:id="@+id/security_patch_level_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/security_patch"/>
+        <TextView
+            style="@style/device_info_dialog_value"
+            android:id="@+id/security_patch_level_value"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+        <TextView
+            style="@style/device_info_dialog_label"
+            android:id="@+id/baseband_version_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/baseband_version"/>
+        <TextView
+            style="@style/device_info_dialog_value"
+            android:id="@+id/baseband_version_value"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+        <TextView
+            style="@style/device_info_dialog_label"
+            android:id="@+id/kernel_version_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/kernel_version"/>
+        <TextView
+            style="@style/device_info_dialog_value"
+            android:id="@+id/kernel_version_value"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+        <TextView
+            style="@style/device_info_dialog_label"
+            android:id="@+id/build_number_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/build_number"/>
+        <TextView
+            style="@style/device_info_dialog_value"
+            android:id="@+id/build_number_value"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+    </LinearLayout>
+</ScrollView>
diff --git a/res/layout/private_dns_mode_dialog.xml b/res/layout/private_dns_mode_dialog.xml
new file mode 100644
index 0000000..4347055
--- /dev/null
+++ b/res/layout/private_dns_mode_dialog.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RadioGroup
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="8dip">
+
+    <RadioButton
+        android:id="@+id/private_dns_mode_off"
+        android:text="@string/private_dns_mode_off"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="8dip"
+        />
+
+    <RadioButton
+        android:id="@+id/private_dns_mode_opportunistic"
+        android:text="@string/private_dns_mode_opportunistic"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="8dip"
+        />
+
+    <RadioButton
+        android:id="@+id/private_dns_mode_provider"
+        android:text="@string/private_dns_mode_provider"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="8dip"
+        />
+
+    <EditText
+        android:id="@+id/private_dns_mode_provider_hostname"
+        android:hint="@string/private_dns_mode_provider_hostname_hint"
+        style="@android:style/Widget.CompoundButton.RadioButton"
+        android:imeOptions="actionDone"
+        android:inputType="textFilter|textUri"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dip"
+        android:layout_marginEnd="8dip"
+        />
+
+</RadioGroup>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c6bc549..4582bc4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2237,9 +2237,9 @@
     <!-- Wi-Fi Calling settings. Additional text displayed when Wi-Fi Calling is off. Default empty. [CHAR LIMIT=NONE] -->
     <string name="wifi_calling_off_explanation_2"></string>
     <!-- Title of a preference for updating emergency address [CHAR LIMIT=40] -->
-    <string name="emergency_address_title">Update Emergency Address</string>
+    <string name="emergency_address_title">Emergency Address</string>
     <!-- Summary of Update Emergency Address preference, explaining usage of emergency address [CHAR LIMIT=NONE] -->
-    <string name="emergency_address_summary">Address used by emergency services as your location if you make an emergency call using Wi\u2011Fi</string>
+    <string name="emergency_address_summary">Used as your location when you make an emergency call over Wi\u2011Fi</string>
 
 
     <!-- Sound and alerts settings -->
@@ -2622,6 +2622,8 @@
 
     <!-- About phone screen, status item label  [CHAR LIMIT=40] -->
     <string name="firmware_version">Android version</string>
+    <!-- About phone screen, dialog title for showing device software information such as android version, security patch level, etc  [CHAR LIMIT=60] -->
+    <string name="firmware_title">Android</string>
     <!-- About phone screen, status item label  [CHAR LIMIT=60] -->
     <string name="security_patch">Android security patch level</string>
     <!-- About phone screen, status item label  [CHAR LIMIT=40] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8815bb3..f3b67e2 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -479,11 +479,13 @@
     </style>
 
     <style name="device_info_dialog_label">
+        <item name="android:textAlignment">viewStart</item>
         <item name="android:textAppearance">@android:style/TextAppearance.Material.Body1</item>
         <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
     <style name="device_info_dialog_value">
+        <item name="android:textAlignment">viewStart</item>
         <item name="android:textAppearance">@android:style/TextAppearance.Material.Body2</item>
         <item name="android:paddingBottom">24dp</item>
     </style>
diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml
index 999e2d1..c8c57a5 100644
--- a/res/xml/development_prefs.xml
+++ b/res/xml/development_prefs.xml
@@ -280,10 +280,13 @@
             android:entries="@array/bluetooth_a2dp_codec_ldac_playback_quality_titles"
             android:entryValues="@array/bluetooth_a2dp_codec_ldac_playback_quality_values" />
 
-        <SwitchPreference
-            android:key="dns_tls"
-            android:title="@string/dns_tls"
-            android:summary="@string/dns_tls_summary" />
+        <com.android.settings.development.PrivateDnsModeDialogPreference
+            android:key="select_private_dns_configuration"
+            android:title="@string/select_private_dns_configuration_title"
+            android:dialogTitle="@string/select_private_dns_configuration_dialog_title"
+            android:dialogLayout="@layout/private_dns_mode_dialog"
+            android:positiveButtonText="@string/save"
+            android:negativeButtonText="@string/cancel" />
 
     </PreferenceCategory>
 
diff --git a/res/xml/device_info_settings_v2.xml b/res/xml/device_info_settings_v2.xml
index 2edfdce..5957c1a 100644
--- a/res/xml/device_info_settings_v2.xml
+++ b/res/xml/device_info_settings_v2.xml
@@ -69,20 +69,20 @@
 
     <!--IP address -->
     <Preference
-        android:key="ip_address"
+        android:key="wifi_ip_address"
         android:title="@string/wifi_ip_address"
         android:summary="@string/summary_placeholder"
         settings:allowDividerAbove="true"/>
 
     <!-- Wi-Fi MAC address -->
     <Preference
-        android:key="mac_address"
+        android:key="wifi_mac_address"
         android:title="@string/status_wifi_mac_address"
         android:summary="@string/summary_placeholder"/>
 
     <!-- Bluetooth address -->
     <Preference
-        android:key="bluetooth_address"
+        android:key="bt_address"
         android:title="@string/status_bt_address"
         android:summary="@string/summary_placeholder"/>
 
diff --git a/res/xml/screen_lock_settings.xml b/res/xml/screen_lock_settings.xml
new file mode 100644
index 0000000..3bd8255
--- /dev/null
+++ b/res/xml/screen_lock_settings.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2017 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:key="security_settings_password_sub_screen"
+    android:title="@string/security_settings_title">
+
+    <!-- available in pattern -->
+    <SwitchPreference
+        android:key="visiblepattern"
+        android:title="@string/lockpattern_settings_enable_visible_pattern_title" />
+
+    <!-- available in pin/pattern/password -->
+    <com.android.settings.TimeoutListPreference
+        android:key="lock_after_timeout"
+        android:title="@string/lock_after_timeout"
+        android:summary="@string/summary_placeholder"
+        android:entries="@array/lock_after_timeout_entries"
+        android:entryValues="@array/lock_after_timeout_values" />
+
+    <!-- available in pin/pattern/password -->
+    <SwitchPreference
+        android:key="power_button_instantly_locks"
+        android:title="@string/lockpattern_settings_enable_power_button_instantly_locks" />
+
+    <!-- available in pin/pattern/password/slide -->
+    <com.android.settingslib.RestrictedPreference
+        android:key="owner_info_settings"
+        android:title="@string/owner_info_settings_title" />
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/security_settings_password_sub.xml b/res/xml/security_settings_password_sub.xml
deleted file mode 100644
index d9e6111c..0000000
--- a/res/xml/security_settings_password_sub.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="security_settings_password_sub_screen"
-    android:title="@string/settings_label">
-
-    <com.android.settings.TimeoutListPreference
-        android:key="lock_after_timeout"
-        android:title="@string/lock_after_timeout"
-        android:summary="@string/summary_placeholder"
-        android:entries="@array/lock_after_timeout_entries"
-        android:entryValues="@array/lock_after_timeout_values" />
-
-    <SwitchPreference
-        android:key="power_button_instantly_locks"
-        android:title="@string/lockpattern_settings_enable_power_button_instantly_locks" />
-
-    <com.android.settingslib.RestrictedPreference
-        android:key="owner_info_settings"
-        android:title="@string/owner_info_settings_title" />
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_pattern_sub.xml b/res/xml/security_settings_pattern_sub.xml
deleted file mode 100644
index c898d6f..0000000
--- a/res/xml/security_settings_pattern_sub.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="security_settings_pattern_sub_screen"
-    android:title="@string/settings_label">
-
-    <SwitchPreference
-        android:key="visiblepattern"
-        android:title="@string/lockpattern_settings_enable_visible_pattern_title" />
-
-    <com.android.settings.TimeoutListPreference
-        android:key="lock_after_timeout"
-        android:title="@string/lock_after_timeout"
-        android:summary="@string/summary_placeholder"
-        android:entries="@array/lock_after_timeout_entries"
-        android:entryValues="@array/lock_after_timeout_values" />
-
-    <SwitchPreference
-        android:key="power_button_instantly_locks"
-        android:title="@string/lockpattern_settings_enable_power_button_instantly_locks" />
-
-    <com.android.settingslib.RestrictedPreference
-        android:key="owner_info_settings"
-        android:title="@string/owner_info_settings_title" />
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_pin_sub.xml b/res/xml/security_settings_pin_sub.xml
deleted file mode 100644
index f98ccbc..0000000
--- a/res/xml/security_settings_pin_sub.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="security_settings_pin_sub_screen"
-    android:title="@string/settings_label">
-
-    <com.android.settings.TimeoutListPreference
-        android:key="lock_after_timeout"
-        android:title="@string/lock_after_timeout"
-        android:summary="@string/summary_placeholder"
-        android:entries="@array/lock_after_timeout_entries"
-        android:entryValues="@array/lock_after_timeout_values" />
-
-    <SwitchPreference
-        android:key="power_button_instantly_locks"
-        android:title="@string/lockpattern_settings_enable_power_button_instantly_locks" />
-
-    <com.android.settingslib.RestrictedPreference
-        android:key="owner_info_settings"
-        android:title="@string/owner_info_settings_title" />
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_slide_sub.xml b/res/xml/security_settings_slide_sub.xml
deleted file mode 100644
index 126b8af..0000000
--- a/res/xml/security_settings_slide_sub.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="security_settings_slide_sub_screen"
-    android:title="@string/settings_label">
-
-    <com.android.settingslib.RestrictedPreference
-        android:key="owner_info_settings"
-        android:title="@string/owner_info_settings_title"
-        android:summary="@string/owner_info_settings_summary" />
-
-</PreferenceScreen>
diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java
index c20b5e7..5c26645 100644
--- a/src/com/android/settings/DeviceInfoSettings.java
+++ b/src/com/android/settings/DeviceInfoSettings.java
@@ -27,11 +27,14 @@
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.deviceinfo.BasebandVersionPreferenceController;
+import com.android.settings.deviceinfo.BluetoothAddressPreferenceController;
 import com.android.settings.deviceinfo.BuildNumberPreferenceController;
 import com.android.settings.deviceinfo.DeviceModelPreferenceController;
 import com.android.settings.deviceinfo.FccEquipmentIdPreferenceController;
 import com.android.settings.deviceinfo.FeedbackPreferenceController;
 import com.android.settings.deviceinfo.FirmwareVersionPreferenceController;
+import com.android.settings.deviceinfo.IpAddressPreferenceController;
+import com.android.settings.deviceinfo.WifiMacAddressPreferenceController;
 import com.android.settings.deviceinfo.imei.ImeiInfoDualSimPreferenceController;
 import com.android.settings.deviceinfo.imei.ImeiInfoPreferenceControllerV2;
 import com.android.settings.deviceinfo.KernelVersionPreferenceController;
@@ -41,6 +44,7 @@
 import com.android.settings.deviceinfo.SecurityPatchPreferenceController;
 import com.android.settings.deviceinfo.simstatus.SimStatusDualSimPreferenceController;
 import com.android.settings.deviceinfo.simstatus.SimStatusPreferenceControllerV2;
+import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionPreferenceControllerV2;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
@@ -138,13 +142,13 @@
 
             controllers.add(new ImeiInfoDualSimPreferenceController(context, fragment));
 
-            // Android version
+            controllers.add(new FirmwareVersionPreferenceControllerV2(context, fragment));
 
-            // IP address
+            controllers.add(new IpAddressPreferenceController(context, lifecycle));
 
-            // Wifi MAC address
+            controllers.add(new WifiMacAddressPreferenceController(context, lifecycle));
 
-            // Bluetooth Address
+            controllers.add(new BluetoothAddressPreferenceController(context, lifecycle));
 
             controllers.add(new RegulatoryInfoPreferenceController(context));
 
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index 9bc20b5..35f7375 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -107,8 +107,6 @@
                     videoView.setLayoutParams(videoLp);
                     videoView.invalidate();
                     videoView.start();
-                    mVideoBackgroundView.getViewTreeObserver()
-                            .removeOnGlobalLayoutListener(mLayoutListener);
                 }
             };
 
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java
index e77881e..71bf107 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java
@@ -97,7 +97,10 @@
         if (DEBUG) {
             Log.d(TAG, "SuggestionService disconnected");
         }
-        mHost.getLoaderManager().destroyLoader(SuggestionLoader.LOADER_ID_SUGGESTIONS);
+        final LoaderManager loaderManager = mHost.getLoaderManager();
+        if (loaderManager != null) {
+            loaderManager.destroyLoader(SuggestionLoader.LOADER_ID_SUGGESTIONS);
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/development/DevelopmentSettings.java b/src/com/android/settings/development/DevelopmentSettings.java
index b492c1a..558ebcf 100644
--- a/src/com/android/settings/development/DevelopmentSettings.java
+++ b/src/com/android/settings/development/DevelopmentSettings.java
@@ -193,7 +193,7 @@
     private static final String BLUETOOTH_SELECT_A2DP_CHANNEL_MODE_KEY = "bluetooth_select_a2dp_channel_mode";
     private static final String BLUETOOTH_SELECT_A2DP_LDAC_PLAYBACK_QUALITY_KEY = "bluetooth_select_a2dp_ldac_playback_quality";
 
-    private static final String DNS_TLS_KEY = "dns_tls";
+    private static final String PRIVATE_DNS_PREF_KEY = "select_private_dns_configuration";
 
     private static final String INACTIVE_APPS_KEY = "inactive_apps";
 
@@ -273,8 +273,6 @@
     private ListPreference mBluetoothSelectA2dpChannelMode;
     private ListPreference mBluetoothSelectA2dpLdacPlaybackQuality;
 
-    private SwitchPreference mDnsTls;
-
     private SwitchPreference mOtaDisableAutomaticUpdate;
     private SwitchPreference mWifiAllowScansWithTraffic;
     private SwitchPreference mStrictMode;
@@ -495,7 +493,7 @@
         mBluetoothSelectA2dpLdacPlaybackQuality = addListPreference(BLUETOOTH_SELECT_A2DP_LDAC_PLAYBACK_QUALITY_KEY);
         initBluetoothConfigurationValues();
 
-        mDnsTls = findAndInitSwitchPref(DNS_TLS_KEY);
+        updatePrivateDnsSummary();
 
         mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY);
         mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY);
@@ -854,8 +852,7 @@
         updateBluetoothDisableAbsVolumeOptions();
         updateBluetoothEnableInbandRingingOptions();
         updateBluetoothA2dpConfigurationValues();
-        updateSwitchPreference(mDnsTls, Settings.Global.getInt(cr,
-                Settings.Global.DNS_TLS_DISABLED, 0) == 0);
+        updatePrivateDnsSummary();
     }
 
     private void resetDangerousOptions() {
@@ -2020,6 +2017,13 @@
         }
     }
 
+    private void updatePrivateDnsSummary() {
+        final String summary = PrivateDnsModeDialogPreference.getSummaryStringForModeFromSettings(
+                getActivity().getContentResolver(), getActivity().getResources());
+        final Preference pref = findPreference(PRIVATE_DNS_PREF_KEY);
+        pref.setSummary(summary);
+    }
+
     private void writeImmediatelyDestroyActivitiesOptions() {
         try {
             ActivityManager.getService().setAlwaysFinish(
@@ -2371,10 +2375,6 @@
             writeBluetoothDisableAbsVolumeOptions();
         } else if (preference == mBluetoothEnableInbandRinging) {
             writeBluetoothEnableInbandRingingOptions();
-        } else if (preference == mDnsTls) {
-            Settings.Global.putInt(getActivity().getContentResolver(),
-                    Settings.Global.DNS_TLS_DISABLED,
-                    mDnsTls.isChecked() ? 0 : 1);
         } else if (SHORTCUT_MANAGER_RESET_KEY.equals(preference.getKey())) {
             resetShortcutManagerThrottling();
         } else {
diff --git a/src/com/android/settings/development/PrivateDnsModeDialogPreference.java b/src/com/android/settings/development/PrivateDnsModeDialogPreference.java
new file mode 100644
index 0000000..ee44b08
--- /dev/null
+++ b/src/com/android/settings/development/PrivateDnsModeDialogPreference.java
@@ -0,0 +1,246 @@
+/*
+ * 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.development;
+
+import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v14.preference.PreferenceDialogFragment;
+import android.support.v7.preference.DialogPreference;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.EditText;
+import android.widget.RadioButton;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+import com.android.settings.R;
+import com.android.settingslib.CustomDialogPreference;
+
+
+public class PrivateDnsModeDialogPreference extends CustomDialogPreference
+        implements OnCheckedChangeListener, TextWatcher, OnEditorActionListener {
+    private static final String TAG = PrivateDnsModeDialogPreference.class.getSimpleName();
+
+    private static final String MODE_KEY = Settings.Global.PRIVATE_DNS_MODE;
+    private static final String HOSTNAME_KEY = Settings.Global.PRIVATE_DNS_SPECIFIER;
+    private String mMode;
+    private EditText mEditText;
+
+    public static String getSummaryStringForModeFromSettings(ContentResolver cr, Resources res) {
+        final String mode = getModeFromSettings(cr);
+        switch (mode) {
+            case PRIVATE_DNS_MODE_OFF:
+                return res.getString(R.string.private_dns_mode_off);
+            case PRIVATE_DNS_MODE_OPPORTUNISTIC:
+                return res.getString(R.string.private_dns_mode_opportunistic);
+            case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
+                return getHostnameFromSettings(cr);
+            default:
+                return "unknown";
+        }
+    }
+
+    public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public PrivateDnsModeDialogPreference(Context context) {
+        super(context);
+    }
+
+    // This is called first when the dialog is launched.
+    @Override
+    protected void onBindDialogView(View view) {
+        final String mode = getModeFromSettings();
+
+        RadioButton rb = (RadioButton) view.findViewById(R.id.private_dns_mode_off);
+        if (mode.equals(PRIVATE_DNS_MODE_OFF)) rb.setChecked(true);
+        rb.setOnCheckedChangeListener(this);
+
+        rb = (RadioButton) view.findViewById(R.id.private_dns_mode_opportunistic);
+        if (mode.equals(PRIVATE_DNS_MODE_OPPORTUNISTIC)) rb.setChecked(true);
+        rb.setOnCheckedChangeListener(this);
+
+        rb = (RadioButton) view.findViewById(R.id.private_dns_mode_provider);
+        if (mode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) rb.setChecked(true);
+        rb.setOnCheckedChangeListener(this);
+
+        mEditText = (EditText) view.findViewById(R.id.private_dns_mode_provider_hostname);
+        mEditText.setOnEditorActionListener(this);
+        mEditText.addTextChangedListener(this);
+
+        // (Mostly) Fix the EditText field's indentation to align underneath the
+        // displayed radio button text, and not under the radio button itself.
+        final int padding = rb.isLayoutRtl()
+                ? rb.getCompoundPaddingRight()
+                : rb.getCompoundPaddingLeft();
+        final MarginLayoutParams marginParams = (MarginLayoutParams) mEditText.getLayoutParams();
+        marginParams.setMarginStart(marginParams.getMarginStart() + padding);
+        mEditText.setLayoutParams(marginParams);
+        mEditText.setText(getHostnameFromSettings());
+
+        setDialogValue(mode);
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        if (!positiveResult) return;
+
+        saveDialogValue();
+        setSummary(getSummaryStringForModeFromSettings(
+                getContext().getContentResolver(), getContext().getResources()));
+    }
+
+    @Override
+    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        if (!isChecked) return;
+
+        switch (buttonView.getId()) {
+            case R.id.private_dns_mode_off:
+                setDialogValue(PRIVATE_DNS_MODE_OFF);
+                break;
+            case R.id.private_dns_mode_opportunistic:
+                setDialogValue(PRIVATE_DNS_MODE_OPPORTUNISTIC);
+                break;
+            case R.id.private_dns_mode_provider:
+                setDialogValue(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+                break;
+            default:
+                // Unknown button; ignored.
+                break;
+        }
+    }
+
+    @Override
+    public boolean onEditorAction(TextView tv, int actionId, KeyEvent k) {
+        if (actionId == EditorInfo.IME_ACTION_DONE) {
+            saveDialogValue();
+            getDialog().dismiss();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) { return; }
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) { return; }
+
+    @Override
+    public void afterTextChanged(Editable s) {
+        final String hostname = s.toString();
+        final boolean appearsValid = isWeaklyValidatedHostname(hostname);
+        // TODO: Disable the "positive button" ("Save") when appearsValid is false.
+    }
+
+    private void setDialogValue(String mode) {
+        mMode = mode;
+        final boolean txtEnabled = mMode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+        mEditText.setEnabled(txtEnabled);
+    }
+
+    private void saveDialogValue() {
+        if (!isValidMode(mMode)) {
+            mMode = PRIVATE_DNS_DEFAULT_MODE;
+        }
+
+        if (mMode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
+            final String hostname = mEditText.getText().toString();
+            if (isWeaklyValidatedHostname(hostname)) {
+                saveHostnameToSettings(hostname);
+            } else {
+                // TODO: Once quasi-validation of hostnames works and acceptable
+                // user signaling is working, this can be deleted.
+                mMode = PRIVATE_DNS_MODE_OPPORTUNISTIC;
+                if (TextUtils.isEmpty(hostname)) saveHostnameToSettings("");
+            }
+        }
+
+        saveModeToSettings(mMode);
+    }
+
+    private String getModeFromSettings() {
+        return getModeFromSettings(getContext().getContentResolver());
+    }
+
+    private void saveModeToSettings(String value) {
+        Settings.Global.putString(getContext().getContentResolver(), MODE_KEY, value);
+    }
+
+    private String getHostnameFromSettings() {
+        return getHostnameFromSettings(getContext().getContentResolver());
+    }
+
+    private void saveHostnameToSettings(String hostname) {
+        Settings.Global.putString(getContext().getContentResolver(), HOSTNAME_KEY, hostname);
+    }
+
+    private static String getModeFromSettings(ContentResolver cr) {
+        final String mode = Settings.Global.getString(cr, MODE_KEY);
+        return isValidMode(mode) ? mode : PRIVATE_DNS_DEFAULT_MODE;
+    }
+
+    private static boolean isValidMode(String mode) {
+        return !TextUtils.isEmpty(mode) && (
+                mode.equals(PRIVATE_DNS_MODE_OFF) ||
+                mode.equals(PRIVATE_DNS_MODE_OPPORTUNISTIC) ||
+                mode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME));
+    }
+
+    private static String getHostnameFromSettings(ContentResolver cr) {
+        return Settings.Global.getString(cr, HOSTNAME_KEY);
+    }
+
+    private static boolean isWeaklyValidatedHostname(String hostname) {
+        // TODO: Find and use a better validation method.  Specifically:
+        //     [1] this should reject IP string literals, and
+        //     [2] do the best, simplest, future-proof verification that
+        //         the input approximates a DNS hostname.
+        final String WEAK_HOSTNAME_REGEX = "^[a-zA-Z0-9_.-]+$";
+        return hostname.matches(WEAK_HOSTNAME_REGEX);
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/FirmwareVersionPreferenceController.java b/src/com/android/settings/deviceinfo/FirmwareVersionPreferenceController.java
index fd73ed5..8c9a2f1 100644
--- a/src/com/android/settings/deviceinfo/FirmwareVersionPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/FirmwareVersionPreferenceController.java
@@ -27,13 +27,17 @@
 import android.util.Log;
 
 import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionPreferenceControllerV2;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
-
+/**
+ * deprecated in favor of {@link FirmwareVersionPreferenceControllerV2}
+ */
+@Deprecated
 public class FirmwareVersionPreferenceController extends AbstractPreferenceController implements
         PreferenceControllerMixin, LifecycleObserver, OnResume {
 
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogFragment.java b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogFragment.java
new file mode 100644
index 0000000..3af21a9
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogFragment.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.firmwareversion;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+public class FirmwareVersionDialogFragment extends InstrumentedDialogFragment {
+
+    private static final String TAG = "firmwareVersionDialog";
+
+    public static void show(Fragment host) {
+        final FragmentManager manager = host.getChildFragmentManager();
+        if (manager.findFragmentByTag(TAG) == null) {
+            final FirmwareVersionDialogFragment dialog = new FirmwareVersionDialogFragment();
+            dialog.show(manager, TAG);
+        }
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.DIALOG_FIRMWARE_VERSION;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+                .setTitle(R.string.firmware_title)
+                .setPositiveButton(android.R.string.ok, null /* listener */);
+
+        final View view = LayoutInflater.from(getActivity()).inflate(
+                R.layout.dialog_firmware_version, null /* parent */);
+
+        return builder.setView(view).create();
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceControllerV2.java b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceControllerV2.java
new file mode 100644
index 0000000..3ce9ee1
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceControllerV2.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.firmwareversion;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Build;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class FirmwareVersionPreferenceControllerV2 extends AbstractPreferenceController implements
+        PreferenceControllerMixin {
+
+    private final static String FIRMWARE_VERSION_KEY = "firmware_version";
+
+    private final Fragment mFragment;
+
+    public FirmwareVersionPreferenceControllerV2(Context context, Fragment fragment) {
+        super(context);
+
+        mFragment = fragment;
+    }
+
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        final Preference pref = screen.findPreference(getPreferenceKey());
+        if (pref != null) {
+            pref.setSummary(Build.VERSION.RELEASE);
+        }
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return FIRMWARE_VERSION_KEY;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+            return false;
+        }
+
+        FirmwareVersionDialogFragment.show(mFragment);
+        return true;
+    }
+}
diff --git a/src/com/android/settings/password/ManagedLockPasswordProvider.java b/src/com/android/settings/password/ManagedLockPasswordProvider.java
index 09fe104..82135cf 100644
--- a/src/com/android/settings/password/ManagedLockPasswordProvider.java
+++ b/src/com/android/settings/password/ManagedLockPasswordProvider.java
@@ -66,15 +66,6 @@
     }
 
     /**
-     * Gets resource id of the subscreen that should be shown after clicking gear icon for lock
-     * screen preference in security settings if the current password quality is set to
-     * {@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_MANAGED}.
-     */
-    public int getResIdForLockUnlockSubScreen() {
-        return R.xml.security_settings_password_sub;
-    }
-
-    /**
      * Creates intent that should be launched when user chooses managed password in the lock
      * settings picker.
      * @param requirePasswordToDecrypt Whether a password is needed to decrypt the user.
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index ebba99a..47d17b6 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -76,6 +76,7 @@
 import com.android.settings.security.EncryptionAndCredential;
 import com.android.settings.security.LockscreenDashboardFragment;
 import com.android.settings.security.SecuritySettings;
+import com.android.settings.security.screenlock.ScreenLockSettings;
 import com.android.settings.sim.SimSettings;
 import com.android.settings.support.SupportDashboardActivity;
 import com.android.settings.system.ResetDashboardFragment;
@@ -138,6 +139,7 @@
         addIndex(LocationSettings.class);
         addIndex(ScanningSettings.class);
         addIndex(SecuritySettings.class);
+        addIndex(ScreenLockSettings.class);
         addIndex(EncryptionAndCredential.class);
         addIndex(ScreenPinningSettings.class);
         addIndex(UserAndAccountDashboardFragment.class);
diff --git a/src/com/android/settings/security/OwnerInfoPreferenceController.java b/src/com/android/settings/security/OwnerInfoPreferenceController.java
index cae4d10..395e532 100644
--- a/src/com/android/settings/security/OwnerInfoPreferenceController.java
+++ b/src/com/android/settings/security/OwnerInfoPreferenceController.java
@@ -22,9 +22,10 @@
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.Preference.OnPreferenceClickListener;
 import android.support.v7.preference.PreferenceScreen;
+
 import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.OwnerInfoSettings;
 import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.users.OwnerInfoSettings;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.RestrictedPreference;
@@ -45,7 +46,7 @@
 
     // Container fragment should implement this in order to show the correct summary
     public interface OwnerInfoCallback {
-        public void onOwnerInfoUpdated();
+        void onOwnerInfoUpdated();
     }
 
     public OwnerInfoPreferenceController(Context context, Fragment parent, Lifecycle lifecycle ) {
diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java
index 97cfbb9..02beaaa 100644
--- a/src/com/android/settings/security/SecuritySettings.java
+++ b/src/com/android/settings/security/SecuritySettings.java
@@ -23,12 +23,9 @@
 import android.app.Dialog;
 import android.app.FragmentManager;
 import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Bundle;
@@ -38,7 +35,6 @@
 import android.os.storage.StorageManager;
 import android.provider.SearchIndexableResource;
 import android.provider.Settings;
-import android.service.trust.TrustAgentService;
 import android.support.annotation.VisibleForTesting;
 import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.Preference;
@@ -71,6 +67,7 @@
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
+import com.android.settings.security.screenlock.ScreenLockSettings;
 import com.android.settings.security.trustagent.TrustAgentManager;
 import com.android.settings.security.trustagent.TrustAgentManager.TrustAgentComponentInfo;
 import com.android.settings.widget.GearPreference;
@@ -91,8 +88,6 @@
     private static final String TAG = "SecuritySettings";
 
     private static final String TRUST_AGENT_CLICK_INTENT = "trust_agent_click_intent";
-    private static final Intent TRUST_AGENT_INTENT =
-            new Intent(TrustAgentService.SERVICE_INTERFACE);
 
     // Lock Settings
     private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
@@ -135,9 +130,6 @@
             KEY_SHOW_PASSWORD, KEY_UNIFICATION, KEY_VISIBLE_PATTERN_PROFILE
     };
 
-    // Only allow one trust agent on the platform.
-    private static final boolean ONLY_ONE_TRUST_AGENT = true;
-
     private static final int MY_USER_ID = UserHandle.myUserId();
 
     private DashboardFeatureProvider mDashboardFeatureProvider;
@@ -466,11 +458,10 @@
     // Return the number of trust agents being added
     private int addTrustAgentSettings(PreferenceGroup securityCategory) {
         final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID);
-        ArrayList<TrustAgentComponentInfo> agents = getActiveTrustAgents(
-            getActivity(), mTrustAgentManager, mLockPatternUtils, mDPM);
-        for (int i = 0; i < agents.size(); i++) {
-            final TrustAgentComponentInfo agent = agents.get(i);
-            RestrictedPreference trustAgentPreference =
+        final List<TrustAgentComponentInfo> agents = mTrustAgentManager.getActiveTrustAgents(
+                getActivity(), mLockPatternUtils);
+        for (TrustAgentComponentInfo agent : agents) {
+            final RestrictedPreference trustAgentPreference =
                     new RestrictedPreference(securityCategory.getContext());
             trustAgentPreference.setKey(KEY_TRUST_AGENT);
             trustAgentPreference.setTitle(agent.title);
@@ -529,48 +520,10 @@
         return false;
     }
 
-    static ArrayList<TrustAgentComponentInfo> getActiveTrustAgents(Context context,
-        TrustAgentManager trustAgentManager, LockPatternUtils utils,
-        DevicePolicyManager dpm) {
-        PackageManager pm = context.getPackageManager();
-        ArrayList<TrustAgentComponentInfo> result = new ArrayList<>();
-        List<ResolveInfo> resolveInfos = pm.queryIntentServices(TRUST_AGENT_INTENT,
-                PackageManager.GET_META_DATA);
-        List<ComponentName> enabledTrustAgents = utils.getEnabledTrustAgents(MY_USER_ID);
-
-        EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(context,
-                DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId());
-
-        if (enabledTrustAgents != null && !enabledTrustAgents.isEmpty()) {
-            for (int i = 0; i < resolveInfos.size(); i++) {
-                ResolveInfo resolveInfo = resolveInfos.get(i);
-                if (resolveInfo.serviceInfo == null) continue;
-                if (!trustAgentManager.shouldProvideTrust(resolveInfo, pm)) {
-                    continue;
-                }
-                TrustAgentComponentInfo trustAgentComponentInfo =
-                        trustAgentManager.getSettingsComponent(pm, resolveInfo);
-                if (trustAgentComponentInfo.componentName == null ||
-                        !enabledTrustAgents.contains(
-                                trustAgentManager.getComponentName(resolveInfo)) ||
-                        TextUtils.isEmpty(trustAgentComponentInfo.title)) continue;
-                if (admin != null && dpm.getTrustAgentConfiguration(
-                        null, trustAgentManager.getComponentName(resolveInfo)) == null) {
-                    trustAgentComponentInfo.admin = admin;
-                }
-                result.add(trustAgentComponentInfo);
-                if (ONLY_ONE_TRUST_AGENT) break;
-            }
-        }
-        return result;
-    }
-
-
-
     @Override
     public void onGearClick(GearPreference p) {
         if (KEY_UNLOCK_SET_OR_CHANGE.equals(p.getKey())) {
-            startFragment(this, SecuritySubSettings.class.getName(), 0, 0, null);
+            startFragment(this, ScreenLockSettings.class.getName(), 0, 0, null);
         }
     }
 
@@ -811,7 +764,7 @@
         @Override
         public List<SearchIndexableResource> getXmlResourcesToIndex(
                 Context context, boolean enabled) {
-            final List<SearchIndexableResource> index = new ArrayList<SearchIndexableResource>();
+            final List<SearchIndexableResource> index = new ArrayList<>();
 
             final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
             final ManagedLockPasswordProvider managedPasswordProvider =
@@ -840,12 +793,6 @@
                         lockPatternUtils, managedPasswordProvider, profileUserId)));
             }
 
-            final SearchIndexableResource sir = getSearchResource(context,
-                    SecuritySubSettings.getResIdForLockUnlockSubScreen(lockPatternUtils,
-                            managedPasswordProvider));
-            sir.className = SecuritySubSettings.class.getName();
-            index.add(sir);
-
             // Append the rest of the settings
             index.add(getSearchResource(context, R.xml.security_settings_misc));
 
@@ -915,8 +862,7 @@
                     FeatureFactory.getFactory(context).getSecurityFeatureProvider()
                         .getTrustAgentManager();
                 final List<TrustAgentComponentInfo> agents =
-                        getActiveTrustAgents(context, trustAgentManager, lockPatternUtils,
-                                context.getSystemService(DevicePolicyManager.class));
+                        trustAgentManager.getActiveTrustAgents(context, lockPatternUtils);
                 for (int i = 0; i < agents.size(); i++) {
                     final TrustAgentComponentInfo agent = agents.get(i);
                     data = new SearchIndexableRaw(context);
diff --git a/src/com/android/settings/security/SecuritySubSettings.java b/src/com/android/settings/security/SecuritySubSettings.java
deleted file mode 100644
index d9f2f2c..0000000
--- a/src/com/android/settings/security/SecuritySubSettings.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.security;
-
-import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.TimeoutListPreference;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.password.ManagedLockPasswordProvider;
-import com.android.settings.security.trustagent.TrustAgentManager;
-import com.android.settingslib.RestrictedLockUtils;
-
-import java.util.ArrayList;
-
-public class SecuritySubSettings extends SettingsPreferenceFragment
-        implements Preference.OnPreferenceChangeListener,
-        OwnerInfoPreferenceController.OwnerInfoCallback {
-
-    private static final String TAG = "SecuritySubSettings";
-
-    private static final String KEY_VISIBLE_PATTERN = "visiblepattern";
-    private static final String KEY_LOCK_AFTER_TIMEOUT = "lock_after_timeout";
-    private static final String KEY_POWER_INSTANTLY_LOCKS = "power_button_instantly_locks";
-
-    // These switch preferences need special handling since they're not all stored in Settings.
-    private static final String SWITCH_PREFERENCE_KEYS[] = {
-            KEY_LOCK_AFTER_TIMEOUT, KEY_VISIBLE_PATTERN, KEY_POWER_INSTANTLY_LOCKS};
-    private static final int MY_USER_ID = UserHandle.myUserId();
-
-    private TimeoutListPreference mLockAfter;
-    private SwitchPreference mVisiblePattern;
-    private SwitchPreference mPowerButtonInstantlyLocks;
-
-    private TrustAgentManager mTrustAgentManager;
-    private LockPatternUtils mLockPatternUtils;
-    private DevicePolicyManager mDPM;
-    private OwnerInfoPreferenceController mOwnerInfoPreferenceController;
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsProto.MetricsEvent.SECURITY;
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        SecurityFeatureProvider securityFeatureProvider =
-                FeatureFactory.getFactory(getActivity()).getSecurityFeatureProvider();
-        mTrustAgentManager = securityFeatureProvider.getTrustAgentManager();
-        mLockPatternUtils = new LockPatternUtils(getContext());
-        mDPM = getContext().getSystemService(DevicePolicyManager.class);
-        mOwnerInfoPreferenceController =
-                new OwnerInfoPreferenceController(getContext(), this, null /* lifecycle */);
-        createPreferenceHierarchy();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        createPreferenceHierarchy();
-
-        if (mVisiblePattern != null) {
-            mVisiblePattern.setChecked(mLockPatternUtils.isVisiblePatternEnabled(MY_USER_ID));
-        }
-        if (mPowerButtonInstantlyLocks != null) {
-            mPowerButtonInstantlyLocks.setChecked(
-                    mLockPatternUtils.getPowerButtonInstantlyLocks(MY_USER_ID));
-        }
-
-        mOwnerInfoPreferenceController.updateSummary();
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        super.onActivityResult(requestCode, resultCode, data);
-
-        createPreferenceHierarchy();
-    }
-
-    private void createPreferenceHierarchy() {
-        PreferenceScreen root = getPreferenceScreen();
-        if (root != null) {
-            root.removeAll();
-        }
-
-        final int resid = getResIdForLockUnlockSubScreen(new LockPatternUtils(getContext()),
-                ManagedLockPasswordProvider.get(getContext(), MY_USER_ID));
-        addPreferencesFromResource(resid);
-
-        // lock after preference
-        mLockAfter = (TimeoutListPreference) findPreference(KEY_LOCK_AFTER_TIMEOUT);
-        if (mLockAfter != null) {
-            setupLockAfterPreference();
-            updateLockAfterPreferenceSummary();
-        }
-
-        // visible pattern
-        mVisiblePattern = (SwitchPreference) findPreference(KEY_VISIBLE_PATTERN);
-
-        // lock instantly on power key press
-        mPowerButtonInstantlyLocks = (SwitchPreference) findPreference(
-                KEY_POWER_INSTANTLY_LOCKS);
-        CharSequence trustAgentLabel = getActiveTrustAgentLabel(getContext(),
-                mTrustAgentManager, mLockPatternUtils, mDPM);
-        if (mPowerButtonInstantlyLocks != null && !TextUtils.isEmpty(trustAgentLabel)) {
-            mPowerButtonInstantlyLocks.setSummary(getString(
-                    R.string.lockpattern_settings_power_button_instantly_locks_summary,
-                    trustAgentLabel));
-        }
-
-        mOwnerInfoPreferenceController.displayPreference(getPreferenceScreen());
-        mOwnerInfoPreferenceController.updateEnableState();
-
-        for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) {
-            final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]);
-            if (pref != null) pref.setOnPreferenceChangeListener(this);
-        }
-    }
-
-    private void setupLockAfterPreference() {
-        // Compatible with pre-Froyo
-        long currentTimeout = Settings.Secure.getLong(getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
-        mLockAfter.setValue(String.valueOf(currentTimeout));
-        mLockAfter.setOnPreferenceChangeListener(this);
-        if (mDPM != null) {
-            final RestrictedLockUtils.EnforcedAdmin admin =
-                    RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(
-                            getActivity());
-            final long adminTimeout = mDPM
-                    .getMaximumTimeToLockForUserAndProfiles(UserHandle.myUserId());
-            final long displayTimeout = Math.max(0,
-                    Settings.System.getInt(getContentResolver(), SCREEN_OFF_TIMEOUT, 0));
-            // This setting is a slave to display timeout when a device policy is enforced.
-            // As such, maxLockTimeout = adminTimeout - displayTimeout.
-            // If there isn't enough time, shows "immediately" setting.
-            final long maxTimeout = Math.max(0, adminTimeout - displayTimeout);
-            mLockAfter.removeUnusableTimeouts(maxTimeout, admin);
-        }
-    }
-
-    private void updateLockAfterPreferenceSummary() {
-        final String summary;
-        if (mLockAfter.isDisabledByAdmin()) {
-            summary = getString(R.string.disabled_by_policy_title);
-        } else {
-            // Update summary message with current value
-            long currentTimeout = Settings.Secure.getLong(getContentResolver(),
-                    Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
-            final CharSequence[] entries = mLockAfter.getEntries();
-            final CharSequence[] values = mLockAfter.getEntryValues();
-            int best = 0;
-            for (int i = 0; i < values.length; i++) {
-                long timeout = Long.valueOf(values[i].toString());
-                if (currentTimeout >= timeout) {
-                    best = i;
-                }
-            }
-
-            CharSequence trustAgentLabel = getActiveTrustAgentLabel(getContext(),
-                    mTrustAgentManager, mLockPatternUtils, mDPM);
-            if (!TextUtils.isEmpty(trustAgentLabel)) {
-                if (Long.valueOf(values[best].toString()) == 0) {
-                    summary = getString(R.string.lock_immediately_summary_with_exception,
-                            trustAgentLabel);
-                } else {
-                    summary = getString(R.string.lock_after_timeout_summary_with_exception,
-                            entries[best], trustAgentLabel);
-                }
-            } else {
-                summary = getString(R.string.lock_after_timeout_summary, entries[best]);
-            }
-        }
-        mLockAfter.setSummary(summary);
-    }
-
-    @Override
-    public void onOwnerInfoUpdated() {
-        mOwnerInfoPreferenceController.updateSummary();
-    }
-
-    static int getResIdForLockUnlockSubScreen(LockPatternUtils lockPatternUtils,
-            ManagedLockPasswordProvider managedPasswordProvider) {
-        if (lockPatternUtils.isSecure(MY_USER_ID)) {
-            switch (lockPatternUtils.getKeyguardStoredPasswordQuality(MY_USER_ID)) {
-                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
-                    return R.xml.security_settings_pattern_sub;
-                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
-                    return R.xml.security_settings_pin_sub;
-                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
-                    return R.xml.security_settings_password_sub;
-                case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
-                    return managedPasswordProvider.getResIdForLockUnlockSubScreen();
-            }
-        } else if (!lockPatternUtils.isLockScreenDisabled(MY_USER_ID)) {
-            return R.xml.security_settings_slide_sub;
-        }
-        return 0;
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object value) {
-        String key = preference.getKey();
-        if (KEY_POWER_INSTANTLY_LOCKS.equals(key)) {
-            mLockPatternUtils.setPowerButtonInstantlyLocks((Boolean) value, MY_USER_ID);
-        } else if (KEY_LOCK_AFTER_TIMEOUT.equals(key)) {
-            int timeout = Integer.parseInt((String) value);
-            try {
-                Settings.Secure.putInt(getContentResolver(),
-                        Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeout);
-            } catch (NumberFormatException e) {
-                Log.e(TAG, "could not persist lockAfter timeout setting", e);
-            }
-            setupLockAfterPreference();
-            updateLockAfterPreferenceSummary();
-        } else if (KEY_VISIBLE_PATTERN.equals(key)) {
-            mLockPatternUtils.setVisiblePatternEnabled((Boolean) value, MY_USER_ID);
-        }
-        return true;
-    }
-
-    private static CharSequence getActiveTrustAgentLabel(Context context,
-            TrustAgentManager trustAgentManager, LockPatternUtils utils,
-            DevicePolicyManager dpm) {
-        ArrayList<TrustAgentManager.TrustAgentComponentInfo> agents =
-                SecuritySettings.getActiveTrustAgents(context, trustAgentManager, utils, dpm);
-        return agents.isEmpty() ? null : agents.get(0).title;
-    }
-}
diff --git a/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java b/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java
new file mode 100644
index 0000000..3cbde58
--- /dev/null
+++ b/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java
@@ -0,0 +1,155 @@
+/*
+ * 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.security.screenlock;
+
+import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.TimeoutListPreference;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.security.trustagent.TrustAgentManager;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class LockAfterTimeoutPreferenceController extends AbstractPreferenceController
+        implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+    private static final String KEY_LOCK_AFTER_TIMEOUT = "lock_after_timeout";
+
+    private final int mUserId;
+    private final LockPatternUtils mLockPatternUtils;
+    private final TrustAgentManager mTrustAgentManager;
+    private final DevicePolicyManager mDPM;
+
+    public LockAfterTimeoutPreferenceController(Context context, int userId,
+            LockPatternUtils lockPatternUtils) {
+        super(context);
+        mUserId = userId;
+        mLockPatternUtils = lockPatternUtils;
+        mDPM = context.getSystemService(DevicePolicyManager.class);
+        mTrustAgentManager = FeatureFactory.getFactory(context)
+                .getSecurityFeatureProvider().getTrustAgentManager();
+    }
+
+    @Override
+    public boolean isAvailable() {
+        if (!mLockPatternUtils.isSecure(mUserId)) {
+            return false;
+        }
+        switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId)) {
+            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;
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_LOCK_AFTER_TIMEOUT;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        setupLockAfterPreference((TimeoutListPreference) preference);
+        updateLockAfterPreferenceSummary((TimeoutListPreference) preference);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        try {
+            final int timeout = Integer.parseInt((String) newValue);
+            Settings.Secure.putInt(mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeout);
+            updateState(preference);
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "could not persist lockAfter timeout setting", e);
+        }
+        return true;
+    }
+
+    private void setupLockAfterPreference(TimeoutListPreference preference) {
+        // Compatible with pre-Froyo
+        long currentTimeout = Settings.Secure.getLong(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
+        preference.setValue(String.valueOf(currentTimeout));
+        if (mDPM != null) {
+            final RestrictedLockUtils.EnforcedAdmin admin =
+                    RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext);
+            final long adminTimeout = mDPM
+                    .getMaximumTimeToLockForUserAndProfiles(UserHandle.myUserId());
+            final long displayTimeout = Math.max(0,
+                    Settings.System.getInt(mContext.getContentResolver(), SCREEN_OFF_TIMEOUT, 0));
+            // This setting is a slave to display timeout when a device policy is enforced.
+            // As such, maxLockTimeout = adminTimeout - displayTimeout.
+            // If there isn't enough time, shows "immediately" setting.
+            final long maxTimeout = Math.max(0, adminTimeout - displayTimeout);
+            preference.removeUnusableTimeouts(maxTimeout, admin);
+        }
+    }
+
+    private void updateLockAfterPreferenceSummary(TimeoutListPreference preference) {
+        final CharSequence summary;
+        if (preference.isDisabledByAdmin()) {
+            summary = mContext.getText(R.string.disabled_by_policy_title);
+        } else {
+            // Update summary message with current value
+            long currentTimeout = Settings.Secure.getLong(mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
+            final CharSequence[] entries = preference.getEntries();
+            final CharSequence[] values = preference.getEntryValues();
+            int best = 0;
+            for (int i = 0; i < values.length; i++) {
+                long timeout = Long.valueOf(values[i].toString());
+                if (currentTimeout >= timeout) {
+                    best = i;
+                }
+            }
+
+            final CharSequence trustAgentLabel = mTrustAgentManager
+                    .getActiveTrustAgentLabel(mContext, mLockPatternUtils);
+            if (!TextUtils.isEmpty(trustAgentLabel)) {
+                if (Long.valueOf(values[best].toString()) == 0) {
+                    summary = mContext.getString(R.string.lock_immediately_summary_with_exception,
+                            trustAgentLabel);
+                } else {
+                    summary = mContext.getString(R.string.lock_after_timeout_summary_with_exception,
+                            entries[best], trustAgentLabel);
+                }
+            } else {
+                summary = mContext.getString(R.string.lock_after_timeout_summary, entries[best]);
+            }
+        }
+        preference.setSummary(summary);
+    }
+}
diff --git a/src/com/android/settings/security/screenlock/PatternVisiblePreferenceController.java b/src/com/android/settings/security/screenlock/PatternVisiblePreferenceController.java
new file mode 100644
index 0000000..beddd4b
--- /dev/null
+++ b/src/com/android/settings/security/screenlock/PatternVisiblePreferenceController.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security.screenlock;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.TwoStatePreference;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class PatternVisiblePreferenceController extends AbstractPreferenceController
+        implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+    private static final String PREF_KEY = "visiblepattern";
+
+    private final int mUserId;
+    private final LockPatternUtils mLockPatternUtils;
+
+    public PatternVisiblePreferenceController(Context context, int userId,
+            LockPatternUtils lockPatternUtils) {
+        super(context);
+        mUserId = userId;
+        mLockPatternUtils = lockPatternUtils;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return isPatternLock();
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return PREF_KEY;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        ((TwoStatePreference) preference).setChecked(
+                mLockPatternUtils.isVisiblePatternEnabled(mUserId));
+    }
+
+    private boolean isPatternLock() {
+        return mLockPatternUtils.isSecure(mUserId)
+                && mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId)
+                == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        mLockPatternUtils.setVisiblePatternEnabled((Boolean) newValue, mUserId);
+        return true;
+    }
+}
diff --git a/src/com/android/settings/security/screenlock/PowerButtonInstantLockPreferenceController.java b/src/com/android/settings/security/screenlock/PowerButtonInstantLockPreferenceController.java
new file mode 100644
index 0000000..1a32a0e
--- /dev/null
+++ b/src/com/android/settings/security/screenlock/PowerButtonInstantLockPreferenceController.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security.screenlock;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.TwoStatePreference;
+import android.text.TextUtils;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.security.trustagent.TrustAgentManager;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class PowerButtonInstantLockPreferenceController extends AbstractPreferenceController
+        implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+    private static final String KEY_POWER_INSTANTLY_LOCKS = "power_button_instantly_locks";
+
+    private final int mUserId;
+    private final LockPatternUtils mLockPatternUtils;
+    private final TrustAgentManager mTrustAgentManager;
+
+    public PowerButtonInstantLockPreferenceController(Context context, int userId,
+            LockPatternUtils lockPatternUtils) {
+        super(context);
+        mUserId = userId;
+        mLockPatternUtils = lockPatternUtils;
+        mTrustAgentManager = FeatureFactory.getFactory(context)
+                .getSecurityFeatureProvider().getTrustAgentManager();
+    }
+
+    @Override
+    public boolean isAvailable() {
+        if (!mLockPatternUtils.isSecure(mUserId)) {
+            return false;
+        }
+        switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId)) {
+            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;
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        ((TwoStatePreference) preference).setChecked(
+                mLockPatternUtils.getPowerButtonInstantlyLocks(mUserId));
+        final CharSequence trustAgentLabel = mTrustAgentManager.getActiveTrustAgentLabel(
+                mContext, mLockPatternUtils);
+        if (!TextUtils.isEmpty(trustAgentLabel)) {
+            preference.setSummary(mContext.getString(
+                    R.string.lockpattern_settings_power_button_instantly_locks_summary,
+                    trustAgentLabel));
+        } else {
+            preference.setSummary(R.string.summary_placeholder);
+        }
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_POWER_INSTANTLY_LOCKS;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        mLockPatternUtils.setPowerButtonInstantlyLocks((Boolean) newValue, mUserId);
+        return true;
+    }
+}
diff --git a/src/com/android/settings/security/screenlock/ScreenLockSettings.java b/src/com/android/settings/security/screenlock/ScreenLockSettings.java
new file mode 100644
index 0000000..8d48325
--- /dev/null
+++ b/src/com/android/settings/security/screenlock/ScreenLockSettings.java
@@ -0,0 +1,106 @@
+/*
+ * 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.security.screenlock;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.SearchIndexableResource;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settings.security.OwnerInfoPreferenceController;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ScreenLockSettings extends DashboardFragment
+        implements OwnerInfoPreferenceController.OwnerInfoCallback {
+
+    private static final String TAG = "ScreenLockSettings";
+
+    private static final int MY_USER_ID = UserHandle.myUserId();
+    private LockPatternUtils mLockPatternUtils;
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.SECURITY;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.screen_lock_settings;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+        mLockPatternUtils = new LockPatternUtils(context);
+        return buildPreferenceControllers(context, this /* parent */, getLifecycle(),
+                mLockPatternUtils);
+    }
+
+    @Override
+    public void onOwnerInfoUpdated() {
+        getPreferenceController(OwnerInfoPreferenceController.class).updateSummary();
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+            Fragment parent, Lifecycle lifecycle, LockPatternUtils lockPatternUtils) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new PatternVisiblePreferenceController(
+                context, MY_USER_ID, lockPatternUtils));
+        controllers.add(new PowerButtonInstantLockPreferenceController(
+                context, MY_USER_ID, lockPatternUtils));
+        controllers.add(new LockAfterTimeoutPreferenceController(
+                context, MY_USER_ID, lockPatternUtils));
+        controllers.add(new OwnerInfoPreferenceController(context, parent, lifecycle));
+        return controllers;
+    }
+
+
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider() {
+                @Override
+                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+                        boolean enabled) {
+                    final ArrayList<SearchIndexableResource> result = new ArrayList<>();
+
+                    final SearchIndexableResource sir = new SearchIndexableResource(context);
+                    sir.xmlResId = R.xml.screen_lock_settings;
+                    result.add(sir);
+                    return result;
+                }
+
+                @Override
+                public List<AbstractPreferenceController> getPreferenceControllers(
+                        Context context) {
+                    return buildPreferenceControllers(context, null /* parent */,
+                            null /* lifecycle */, new LockPatternUtils(context));
+                }
+            };
+}
diff --git a/src/com/android/settings/security/trustagent/TrustAgentManager.java b/src/com/android/settings/security/trustagent/TrustAgentManager.java
index 0655618..3710905 100644
--- a/src/com/android/settings/security/trustagent/TrustAgentManager.java
+++ b/src/com/android/settings/security/trustagent/TrustAgentManager.java
@@ -18,29 +18,41 @@
 
 import static android.service.trust.TrustAgentService.TRUST_AGENT_META_DATA;
 
+import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.os.UserHandle;
+import android.service.trust.TrustAgentService;
 import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
 import android.util.Xml;
 
+import com.android.internal.widget.LockPatternUtils;
 import com.android.settingslib.RestrictedLockUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 
 /** A manager for trust agent state. */
 public class TrustAgentManager {
 
+    // Only allow one trust agent on the platform.
+    private static final boolean ONLY_ONE_TRUST_AGENT = true;
+
     public static class TrustAgentComponentInfo {
         public ComponentName componentName;
         public String title;
@@ -49,6 +61,8 @@
     }
 
     private static final String TAG = "TrustAgentManager";
+    private static final Intent TRUST_AGENT_INTENT =
+            new Intent(TrustAgentService.SERVICE_INTERFACE);
 
     @VisibleForTesting
     static final String PERMISSION_PROVIDE_AGENT =
@@ -74,13 +88,66 @@
         return true;
     }
 
+    /**
+     * Return the display label for active trust agent.
+     */
+    public CharSequence getActiveTrustAgentLabel(Context context, LockPatternUtils utils) {
+        final List<TrustAgentComponentInfo> agents = getActiveTrustAgents(context, utils);
+        return agents.isEmpty() ? null : agents.get(0).title;
+    }
+
+    /**
+     * Returns a list of trust agents.
+     *
+     * If {@link #ONLY_ONE_TRUST_AGENT} is set, the list will contain up to 1 agent instead of all
+     * available agents on device.
+     */
+    public List<TrustAgentComponentInfo> getActiveTrustAgents(Context context,
+            LockPatternUtils utils) {
+        final int myUserId = UserHandle.myUserId();
+        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+        final PackageManager pm = context.getPackageManager();
+        final List<TrustAgentComponentInfo> result = new ArrayList<>();
+
+        final List<ResolveInfo> resolveInfos = pm.queryIntentServices(TRUST_AGENT_INTENT,
+                PackageManager.GET_META_DATA);
+        final List<ComponentName> enabledTrustAgents = utils.getEnabledTrustAgents(myUserId);
+        final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtils
+                .checkIfKeyguardFeaturesDisabled(
+                        context, DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, myUserId);
+
+        if (enabledTrustAgents != null && !enabledTrustAgents.isEmpty()) {
+            for (ResolveInfo resolveInfo : resolveInfos) {
+                if (resolveInfo.serviceInfo == null || !shouldProvideTrust(resolveInfo, pm)) {
+                    continue;
+                }
+                final TrustAgentComponentInfo trustAgentComponentInfo =
+                        getSettingsComponent(pm, resolveInfo);
+                if (trustAgentComponentInfo.componentName == null ||
+                        !enabledTrustAgents.contains(getComponentName(resolveInfo)) ||
+                        TextUtils.isEmpty(trustAgentComponentInfo.title)) {
+                    continue;
+                }
+                if (admin != null && dpm.getTrustAgentConfiguration(
+                        null, getComponentName(resolveInfo)) == null) {
+                    trustAgentComponentInfo.admin = admin;
+                }
+                result.add(trustAgentComponentInfo);
+                if (ONLY_ONE_TRUST_AGENT) {
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
     public ComponentName getComponentName(ResolveInfo resolveInfo) {
         if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
         return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
     }
 
-    public TrustAgentComponentInfo getSettingsComponent(
-            PackageManager pm, ResolveInfo resolveInfo) {
+    private TrustAgentComponentInfo getSettingsComponent(PackageManager pm,
+            ResolveInfo resolveInfo) {
         if (resolveInfo == null || resolveInfo.serviceInfo == null
                 || resolveInfo.serviceInfo.metaData == null) {
             return null;
diff --git a/src/com/android/settings/OwnerInfoSettings.java b/src/com/android/settings/users/OwnerInfoSettings.java
similarity index 97%
rename from src/com/android/settings/OwnerInfoSettings.java
rename to src/com/android/settings/users/OwnerInfoSettings.java
index 3128dfe..582431f 100644
--- a/src/com/android/settings/OwnerInfoSettings.java
+++ b/src/com/android/settings/users/OwnerInfoSettings.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings;
+package com.android.settings.users;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -30,6 +30,7 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settings.security.OwnerInfoPreferenceController.OwnerInfoCallback;
 
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index e6122b9..642f289 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -54,7 +54,6 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.OwnerInfoSettings;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 5a10ebf..4da7366 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -1028,7 +1028,7 @@
                 setUserCertInvisible();
                 setPasswordInvisible();
                 setIdentityInvisible();
-                if (mAccessPoint.isCarrierAp()) {
+                if (mAccessPoint != null && mAccessPoint.isCarrierAp()) {
                     setEapMethodInvisible();
                 }
                 break;
diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable
index 31b8f43..4ea5338 100644
--- a/tests/robotests/assets/grandfather_not_implementing_indexable
+++ b/tests/robotests/assets/grandfather_not_implementing_indexable
@@ -71,7 +71,6 @@
 com.android.settings.applications.PictureInPictureSettings
 com.android.settings.applications.PictureInPictureDetails
 com.android.settings.ApnSettings
-com.android.settings.security.SecuritySubSettings
 com.android.settings.PrivacySettings
 com.android.settings.WifiCallingSettings
 com.android.settings.WifiCallingSettingsForSub
diff --git a/tests/robotests/src/com/android/settings/ZonePickerTest.java b/tests/robotests/src/com/android/settings/ZonePickerTest.java
index 31606f1..6f9ce4e 100644
--- a/tests/robotests/src/com/android/settings/ZonePickerTest.java
+++ b/tests/robotests/src/com/android/settings/ZonePickerTest.java
@@ -29,6 +29,7 @@
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowLibcoreTimeZoneNames;
 import com.android.settings.testutils.shadow.ShadowTimeZoneNames;
+import com.android.settings.testutils.shadow.ShadowZoneGetterData;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -38,11 +39,12 @@
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(
         manifest = TestConfig.MANIFEST_PATH,
-        sdk = TestConfig.SDK_VERSION,
+        sdk = TestConfig.SDK_VERSION_O,
         shadows = {
                 ShadowLibcoreTimeZoneNames.class,
                 ShadowLibcoreTimeZoneNames.ShadowZoneStringsCache.class,
-                ShadowTimeZoneNames.class
+                ShadowTimeZoneNames.class,
+                ShadowZoneGetterData.class,
         }
 )
 public class ZonePickerTest {
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
index 89c45b4..696ea4b 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
@@ -97,4 +97,14 @@
 
         verify(mHost).getLoaderManager();
     }
+
+    @Test
+    public void onServiceDisconnected_hostNotAttached_shouldDoNothing() {
+        when(mHost.getLoaderManager()).thenReturn(null);
+
+        mMixin = new SuggestionControllerMixin(mContext, mHost, mLifecycle);
+        mMixin.onServiceDisconnected();
+
+        verify(mHost).getLoaderManager();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceControllerV2Test.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceControllerV2Test.java
new file mode 100644
index 0000000..5fa8a91
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceControllerV2Test.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.firmwareversion;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.os.Build;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+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.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class FirmwareVersionPreferenceControllerV2Test {
+
+    @Mock
+    private Preference mPreference;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private Fragment mFragment;
+
+    private Context mContext;
+    private FirmwareVersionPreferenceControllerV2 mController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mController = new FirmwareVersionPreferenceControllerV2(mContext, mFragment);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+    }
+
+    @Test
+    public void displayPreference_shouldSetSummaryToBuildNumber() {
+        mController.displayPreference(mScreen);
+
+        verify(mPreference).setSummary(Build.VERSION.RELEASE);
+    }
+
+    @Test
+    public void handlePreferenceTreeClick_samePreferenceKey_shouldStartDialogFragment() {
+        when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+        when(mFragment.getChildFragmentManager()).thenReturn(
+                mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS));
+
+        mController.handlePreferenceTreeClick(mPreference);
+
+        verify(mFragment).getChildFragmentManager();
+    }
+
+    @Test
+    public void handlePreferenceTreeClick_unknownPreferenceKey_shouldDoNothingAndReturnFalse() {
+        when(mPreference.getKey()).thenReturn("foobar");
+
+        final boolean result = mController.handlePreferenceTreeClick(mPreference);
+
+        assertThat(result).isFalse();
+        verify(mFragment, never()).getChildFragmentManager();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragmentTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragmentTest.java
index 8431fde..6b3791a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragmentTest.java
@@ -27,12 +27,15 @@
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.pm.permission.RuntimePermissionPresenter;
 import android.os.Build;
 
 import com.android.settings.R;
 import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.shadow.ShadowRuntimePermissionPresenter;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -46,7 +49,8 @@
 import org.robolectric.util.FragmentTestUtil;
 
 @RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+        shadows = ShadowRuntimePermissionPresenter.class)
 public class AnomalyDialogFragmentTest {
     private static final String PACKAGE_NAME = "com.android.app";
     private static final String DISPLAY_NAME = "app";
@@ -56,6 +60,8 @@
     private AnomalyUtils mAnomalyUtils;
     @Mock
     private AnomalyAction mAnomalyAction;
+    @Mock
+    private RuntimePermissionPresenter mRuntimePermissionPresenter;
     private Anomaly mWakeLockAnomaly;
     private Anomaly mWakeupAlarmAnomaly;
     private Anomaly mWakeupAlarmAnomaly2;
@@ -67,7 +73,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mContext = RuntimeEnvironment.application;
+        mContext = spy(RuntimeEnvironment.application);
         mWakeLockAnomaly = new Anomaly.Builder()
                 .setType(Anomaly.AnomalyType.WAKE_LOCK)
                 .setUid(UID)
@@ -93,6 +99,8 @@
                 .setPackageName(PACKAGE_NAME)
                 .setDisplayName(DISPLAY_NAME)
                 .build();
+        FakeFeatureFactory.setupForTest(mContext);
+        ShadowRuntimePermissionPresenter.setRuntimePermissionPresenter(mRuntimePermissionPresenter);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/security/ConfigureKeyGuardDialogTest.java b/tests/robotests/src/com/android/settings/security/ConfigureKeyGuardDialogTest.java
index 38a6b42..ab7512f 100644
--- a/tests/robotests/src/com/android/settings/security/ConfigureKeyGuardDialogTest.java
+++ b/tests/robotests/src/com/android/settings/security/ConfigureKeyGuardDialogTest.java
@@ -17,10 +17,14 @@
 package com.android.settings.security;
 
 
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
 import android.content.DialogInterface;
 
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
 
 import org.junit.Test;
@@ -29,10 +33,6 @@
 import org.robolectric.android.controller.FragmentController;
 import org.robolectric.annotation.Config;
 
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(
     manifest = TestConfig.MANIFEST_PATH,
diff --git a/tests/robotests/src/com/android/settings/security/OwnerInfoPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/OwnerInfoPreferenceControllerTest.java
index 8406d90..71e2d8b 100644
--- a/tests/robotests/src/com/android/settings/security/OwnerInfoPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/OwnerInfoPreferenceControllerTest.java
@@ -15,16 +15,27 @@
  */
 package com.android.settings.security;
 
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
 import android.content.Context;
-import android.support.v7.preference.PreferenceScreen;
 import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.PreferenceScreen;
 
 import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.OwnerInfoSettings;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.users.OwnerInfoSettings;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.RestrictedPreference;
 
@@ -37,18 +48,6 @@
 import org.robolectric.shadows.ShadowApplication;
 import org.robolectric.util.ReflectionHelpers;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class OwnerInfoPreferenceControllerTest {
@@ -139,7 +138,7 @@
         mController.updateSummary();
 
         verify(mPreference).setSummary(mContext.getString(
-            com.android.settings.R.string.owner_info_settings_summary));
+                com.android.settings.R.string.owner_info_settings_summary));
     }
 
     @Test
@@ -179,7 +178,7 @@
     public void performClick_shouldLaunchOwnerInfoSettings() {
         final ShadowApplication application = ShadowApplication.getInstance();
         final RestrictedPreference preference =
-            new RestrictedPreference(application.getApplicationContext());
+                new RestrictedPreference(application.getApplicationContext());
         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(preference);
         doReturn(false).when(mController).isDeviceOwnerInfoEnabled();
         doReturn(false).when(mLockPatternUtils).isLockScreenDisabled(anyInt());
@@ -190,7 +189,7 @@
 
         verify(mFragment).getFragmentManager();
         verify(mFragment.getFragmentManager().beginTransaction())
-            .add(any(OwnerInfoSettings.class), anyString());
+                .add(any(OwnerInfoSettings.class), anyString());
     }
 
 }
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceControllerTest.java
new file mode 100644
index 0000000..a1d7b4e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceControllerTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.security.screenlock;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.TestConfig;
+import com.android.settings.security.trustagent.TrustAgentManager;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.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_O)
+public class LockAfterTimeoutPreferenceControllerTest {
+
+    private static final int TEST_USER_ID = 0;
+
+    @Mock
+    private LockPatternUtils mLockPatternUtils;
+    @Mock
+    private TrustAgentManager mTrustAgentManager;
+
+    private Context mContext;
+    private LockAfterTimeoutPreferenceController mController;
+    private SwitchPreference mPreference;
+    private FakeFeatureFactory mFeatureFactory;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        when(mFeatureFactory.securityFeatureProvider.getTrustAgentManager())
+                .thenReturn(mTrustAgentManager);
+
+        mPreference = new SwitchPreference(mContext);
+        mController = new LockAfterTimeoutPreferenceController(
+                mContext, TEST_USER_ID, mLockPatternUtils);
+    }
+
+    @Test
+    public void isAvailable_lockSetToPattern_shouldReturnTrue() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(TEST_USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_lockSetToPin_shouldReturnTrue() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(TEST_USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_lockSetToPassword_shouldReturnTrue() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(TEST_USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_lockSetToNone_shouldReturnFalse() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+
+}
diff --git a/tests/robotests/src/com/android/settings/security/screenlock/PatternVisiblePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/screenlock/PatternVisiblePreferenceControllerTest.java
new file mode 100644
index 0000000..a947fca
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/security/screenlock/PatternVisiblePreferenceControllerTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.security.screenlock;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.internal.widget.LockPatternUtils;
+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_O)
+public class PatternVisiblePreferenceControllerTest {
+
+    private static final int TEST_USER_ID = 0;
+
+    @Mock
+    private LockPatternUtils mLockPatternUtils;
+    private Context mContext;
+    private PatternVisiblePreferenceController mController;
+    private SwitchPreference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mController = new PatternVisiblePreferenceController(
+                mContext, TEST_USER_ID, mLockPatternUtils);
+        mPreference = new SwitchPreference(mContext);
+    }
+
+    @Test
+    public void isAvailable_lockSetToPattern_shouldReturnTrue() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(TEST_USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_lockSetToPin_shouldReturnFalse() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(TEST_USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_lockSetToNone_shouldReturnFalse() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void updateState_shouldSetPref() {
+        when(mLockPatternUtils.isVisiblePatternEnabled(TEST_USER_ID)).thenReturn(true);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+
+        when(mLockPatternUtils.isVisiblePatternEnabled(TEST_USER_ID)).thenReturn(false);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isFalse();
+    }
+
+    @Test
+    public void onPreferenceChange_shouldUpdateLockPatternUtils() {
+        mController.onPreferenceChange(mPreference, true /* newValue */);
+
+        verify(mLockPatternUtils).setVisiblePatternEnabled(true, TEST_USER_ID);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/security/screenlock/PowerButtonInstantLockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/screenlock/PowerButtonInstantLockPreferenceControllerTest.java
new file mode 100644
index 0000000..2d2e92f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/security/screenlock/PowerButtonInstantLockPreferenceControllerTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.security.screenlock;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.security.trustagent.TrustAgentManager;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.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_O)
+public class PowerButtonInstantLockPreferenceControllerTest {
+
+    private static final int TEST_USER_ID = 0;
+
+    @Mock
+    private LockPatternUtils mLockPatternUtils;
+    @Mock
+    private TrustAgentManager mTrustAgentManager;
+
+    private Context mContext;
+    private PowerButtonInstantLockPreferenceController mController;
+    private SwitchPreference mPreference;
+    private FakeFeatureFactory mFeatureFactory;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        when(mFeatureFactory.securityFeatureProvider.getTrustAgentManager())
+                .thenReturn(mTrustAgentManager);
+
+        mPreference = new SwitchPreference(mContext);
+        mController = new PowerButtonInstantLockPreferenceController(
+                mContext, TEST_USER_ID, mLockPatternUtils);
+    }
+
+    @Test
+    public void isAvailable_lockSetToPattern_shouldReturnTrue() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(TEST_USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_lockSetToPin_shouldReturnTrue() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(TEST_USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_lockSetToPassword_shouldReturnTrue() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(TEST_USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_lockSetToNone_shouldReturnFalse() {
+        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void updateState_shouldSetPref() {
+        final String fakeTrustAgent = "trust_agent";
+        when(mTrustAgentManager.getActiveTrustAgentLabel(mContext, mLockPatternUtils))
+                .thenReturn(fakeTrustAgent);
+        when(mLockPatternUtils.getPowerButtonInstantlyLocks(TEST_USER_ID)).thenReturn(true);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+        assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(
+                R.string.lockpattern_settings_power_button_instantly_locks_summary,
+                fakeTrustAgent));
+
+        when(mTrustAgentManager.getActiveTrustAgentLabel(mContext, mLockPatternUtils))
+                .thenReturn(null);
+        when(mLockPatternUtils.getPowerButtonInstantlyLocks(TEST_USER_ID)).thenReturn(false);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isFalse();
+        assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(
+                R.string.summary_placeholder));
+    }
+
+    @Test
+    public void onPreferenceChange_shouldUpdateLockPatternUtils() {
+        mController.onPreferenceChange(mPreference, true /* newValue */);
+
+        verify(mLockPatternUtils).setPowerButtonInstantlyLocks(true, TEST_USER_ID);
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/security/screenlock/ScreenLockSettingsTest.java b/tests/robotests/src/com/android/settings/security/screenlock/ScreenLockSettingsTest.java
new file mode 100644
index 0000000..e8416ee
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/security/screenlock/ScreenLockSettingsTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.security.screenlock;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.security.OwnerInfoPreferenceController;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.util.Map;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ScreenLockSettingsTest {
+
+    private ScreenLockSettings mSettings;
+
+    @Before
+    public void setUp() {
+        mSettings = new ScreenLockSettings();
+    }
+
+    @Test
+    public void verifyConstants() {
+        assertThat(mSettings.getMetricsCategory()).isEqualTo(MetricsProto.MetricsEvent.SECURITY);
+        assertThat(mSettings.getPreferenceScreenResId()).isEqualTo(R.xml.screen_lock_settings);
+    }
+
+    @Test
+    public void onOwnerInfoUpdated_shouldUpdateOwnerInfoController() {
+        final Map<Class, AbstractPreferenceController> preferenceControllers =
+                ReflectionHelpers.getField(mSettings, "mPreferenceControllers");
+        final OwnerInfoPreferenceController controller = mock(OwnerInfoPreferenceController.class);
+        preferenceControllers.put(OwnerInfoPreferenceController.class, controller);
+
+        mSettings.onOwnerInfoUpdated();
+
+        verify(controller).updateSummary();
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentFeatureProviderTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentManagerTest.java
similarity index 98%
rename from tests/robotests/src/com/android/settings/security/trustagent/TrustAgentFeatureProviderTest.java
rename to tests/robotests/src/com/android/settings/security/trustagent/TrustAgentManagerTest.java
index 7840d1f..ed616be 100644
--- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentFeatureProviderTest.java
+++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentManagerTest.java
@@ -35,7 +35,7 @@
 
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
-public class TrustAgentFeatureProviderTest {
+public class TrustAgentManagerTest {
 
     private static final String CANNED_PACKAGE_NAME = "com.test.package";
 
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index 6da7a66..dd5c76a 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -15,6 +15,10 @@
  */
 package com.android.settings.testutils;
 
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
 
 import com.android.settings.applications.ApplicationFeatureProvider;
@@ -30,14 +34,12 @@
 import com.android.settings.localepicker.LocaleFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.overlay.SupportFeatureProvider;
-import com.android.settings.security.SecurityFeatureProvider;
-import com.android.settings.search.SearchFeatureProvider;
 import com.android.settings.overlay.SurveyFeatureProvider;
+import com.android.settings.search.SearchFeatureProvider;
+import com.android.settings.security.SecurityFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
 
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.mockito.Answers;
 
 /**
  * Test util to provide fake FeatureFactory. To use this factory, call {@code setupForTest} in
@@ -67,6 +69,7 @@
      *
      * @param context The context must be a deep mock.
      */
+    @Deprecated
     public static FakeFeatureFactory setupForTest(Context context) {
         sFactory = null;
         when(context.getString(com.android.settings.R.string.config_featureFactory))
@@ -81,6 +84,14 @@
     }
 
     /**
+     * Call this in {@code @Before} method of the test class to use fake factory.
+     */
+    public static FakeFeatureFactory setupForTest() {
+        final Context context = mock(Context.class, Answers.RETURNS_DEEP_STUBS);
+        return setupForTest(context);
+    }
+
+    /**
      * Used by reflection. Do not call directly.
      */
     public FakeFeatureFactory() {
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRuntimePermissionPresenter.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRuntimePermissionPresenter.java
new file mode 100644
index 0000000..834d285
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRuntimePermissionPresenter.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.testutils.shadow;
+
+import android.content.Context;
+import android.content.pm.permission.RuntimePermissionPresenter;
+
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(RuntimePermissionPresenter.class)
+public class ShadowRuntimePermissionPresenter {
+    private static RuntimePermissionPresenter mRuntimePermissionPresenter;
+
+    @Implementation
+    public static RuntimePermissionPresenter getInstance(Context context) {
+        return mRuntimePermissionPresenter;
+    }
+
+    public static void setRuntimePermissionPresenter(
+            RuntimePermissionPresenter runtimePermissionPresenter) {
+        mRuntimePermissionPresenter = runtimePermissionPresenter;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowZoneGetterData.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowZoneGetterData.java
new file mode 100644
index 0000000..1e6dbced
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowZoneGetterData.java
@@ -0,0 +1,52 @@
+/*
+ * 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.testutils.shadow;
+
+
+import android.icu.util.TimeZone;
+
+import com.android.settingslib.datetime.ZoneGetter;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Implements(ZoneGetter.ZoneGetterData.class)
+public class ShadowZoneGetterData {
+    private static final Map<String, List<String>> TIME_ZONE_LOOKUP = new HashMap<>();
+
+    static {
+        TIME_ZONE_LOOKUP.put("FR", Collections.singletonList(
+                TimeZone.getTimeZone("Europe/Paris", TimeZone.TIMEZONE_JDK).getID()));
+        TIME_ZONE_LOOKUP.put("ML", Collections.singletonList(
+                TimeZone.getTimeZone("Europe/Amsterdam", TimeZone.TIMEZONE_JDK).getID()));
+        TIME_ZONE_LOOKUP.put("US", Arrays.asList(
+                TimeZone.getTimeZone("America/New_York", TimeZone.TIMEZONE_JDK).getID()));
+        TIME_ZONE_LOOKUP.put("JP", Collections.singletonList(
+                TimeZone.getTimeZone("Asia/Tokyo", TimeZone.TIMEZONE_JDK).getID()));
+    }
+
+    @Implementation
+    public List<String> lookupTimeZoneIdsByCountry(String country) {
+        return TIME_ZONE_LOOKUP.get(country);
+    }
+}