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);
+ }
+}