Snap for 4434599 from c8b6833e13 to pi-release

Change-Id: I6d6b2300d39faa7222da47cb654356b6cd749132
This commit is contained in:
android-build-team Robot
2017-11-05 07:37:55 +00:00
84 changed files with 4348 additions and 952 deletions

View File

@@ -1247,7 +1247,7 @@
<meta-data android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.homepage" />
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.SecuritySettings" />
android:value="com.android.settings.security.SecuritySettings" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" />
</activity>
@@ -1289,7 +1289,7 @@
android:exported="true"
android:targetActivity="Settings$SecuritySettingsActivity">
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.SecuritySettings" />
android:value="com.android.settings.security.SecuritySettings" />
</activity-alias>
<activity android:name="Settings$PrivacySettingsActivity"
@@ -2384,7 +2384,7 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.CryptKeeperSettings" />
android:value="com.android.settings.security.CryptKeeperSettings" />
</activity>
<activity android:name="Settings$DataPlanUsageSummaryActivity"

View File

@@ -14,33 +14,29 @@
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
android:paddingStart="@dimen/preference_no_icon_padding_start"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:layout_weight="1"
>
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dip"
android:layout_marginBottom="16dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/crypt_keeper_desc"
/>
android:text="@string/crypt_keeper_desc" />
<TextView
android:id="@+id/warning_low_charge"
android:layout_width="match_parent"
@@ -49,8 +45,7 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="@string/crypt_keeper_low_charge_text"
android:visibility="gone"
/>
android:visibility="gone" />
<TextView
android:id="@+id/warning_unplugged"
android:layout_width="match_parent"
@@ -59,20 +54,14 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="@string/crypt_keeper_unplugged_text"
android:visibility="gone"
/>
android:visibility="gone" />
</LinearLayout>
</ScrollView>
<Button
android:id="@+id/initiate_encrypt"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dip"
android:layout_marginBottom="16dip"
style="@style/ActionPrimaryButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/crypt_keeper_button_text"
android:gravity="center"
/>
android:layout_gravity="end"
android:text="@string/crypt_keeper_button_text" />
</LinearLayout>

View File

@@ -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>

View File

@@ -0,0 +1,114 @@
<?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">
<!-- These items are only for CDMA phones -->
<LinearLayout
android:id="@+id/cdma_settings"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/min_number_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_min_number"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/min_number_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/prl_version_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_prl_version"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/prl_version_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/meid_number_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_meid_number"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/meid_number_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:id="@+id/gsm_settings"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/imei_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_imei"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/imei_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/imei_sv_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_imei_sv"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/imei_sv_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/icc_id_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_icc_id"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/icc_id_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,132 @@
<?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/operator_name_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_operator"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/operator_name_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/device_info_not_available"/>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/number_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_number_sim_status"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/number_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/device_info_not_available"/>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/data_state_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_data_state"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/data_state_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/device_info_not_available"/>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/latest_area_info_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_latest_area_info"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/latest_area_info_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/device_info_not_available"/>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/service_state_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_service_state"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/service_state_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/device_info_not_available"/>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/signal_strength_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_signal_strength"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/signal_strength_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/device_info_not_available"/>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/network_type_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_network_type"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/network_type_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/device_info_not_available"/>
<TextView
style="@style/device_info_dialog_label"
android:id="@+id/roaming_state_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/status_roaming"/>
<TextView
style="@style/device_info_dialog_value"
android:id="@+id/roaming_state_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/device_info_not_available"/>
</LinearLayout>
</ScrollView>

View File

@@ -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] -->
@@ -2661,6 +2663,10 @@
<string name="storage_settings_summary" product="nosdcard">Unmount USB storage, view available storage</string>
<!-- [CHAR LIMIT=100] Main settings screen item's summary for the SD card and storage settings -->
<string name="storage_settings_summary" product="default">Unmount SD card, view available storage</string>
<!-- About phone screen, title for IMEI for multi-sim devices -->
<string name="imei_multi_sim_slot_1">IMEI (sim slot 1)</string>
<!-- About phone screen, title for IMEI for multi-sim devices -->
<string name="imei_multi_sim_slot_2">IMEI (sim slot 2)</string>
<!-- Do not translate. About phone, status item title -->
<string name="status_imei">IMEI</string>
<!-- Do not translate. About phone, status item title -->
@@ -2671,12 +2677,20 @@
<string name="status_number" product="tablet">MDN</string>
<!-- About phone, status item title. The phone number of the current device [CHAR LIMIT=30] -->
<string name="status_number" product="default">Phone number</string>
<!-- About tablet, status item title. The Mobile Directory Number [CHAR LIMIT=30] -->
<string name="status_number_sim_status" product="tablet">MDN on SIM</string>
<!-- About phone, status item title. The phone number of the current device [CHAR LIMIT=30] -->
<string name="status_number_sim_status" product="default">Phone number on SIM</string>
<!-- About phone, status item title. The phone MIN number of the current device.-->
<string name="status_min_number">MIN</string>
<!-- About phone, status item title. The phone MSID number of the current device.-->
<string name="status_msid_number">MSID</string>
<!-- About phone, status item title. The phone PRL Version of the current device.-->
<string name="status_prl_version">PRL version</string>
<!-- About phone screen, title for MEID for multi-sim devices -->
<string name="meid_multi_sim_sim_slot_1">MEID (sim slot 1)</string>
<!-- About phone screen, title for MEID for multi-sim devices -->
<string name="meid_multi_sim_sim_slot_2">MEID (sim slot 2)</string>
<!-- About phone, status item title. The phone MEID number of the current LTE/CDMA device. [CHAR LIMIT=30] -->
<string name="status_meid_number">MEID</string>
<!-- About phone, status item title. The ICCID of the current LTE device. [CHAR LIMIT=30] -->
@@ -6430,6 +6444,10 @@
<string name="sim_no_inserted_msg">No SIM cards inserted</string>
<!-- SIM status title [CHAR LIMIT=40] -->
<string name="sim_status_title">SIM status</string>
<!-- SIM status title [CHAR LIMIT=40] -->
<string name="sim_status_title_sim_slot_1">SIM status (sim slot 1)</string>
<!-- SIM status title [CHAR LIMIT=40] -->
<string name="sim_status_title_sim_slot_2">SIM status (sim slot 2)</string>
<!-- Title for call back. [CHAR LIMIT=60] -->
<string name="sim_call_back_title">Call back from default SIM</string>
<!-- Title for outgoing back. [CHAR LIMIT=60] -->
@@ -6555,6 +6573,7 @@
<string name="keywords_payment_settings">pay, tap, payments</string>
<string name="keywords_backup">backup, back up</string>
<string name="keywords_assist_gesture_launch">gesture</string>
<string name="keywords_imei_info">imei, meid</string>
<!-- NFC Wi-Fi pairing/setup strings-->

View File

@@ -478,4 +478,14 @@
<item name="android:textSize">@dimen/search_bar_text_size</item>
</style>
<style name="device_info_dialog_label">
<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:textAppearance">@android:style/TextAppearance.Material.Body2</item>
<item name="android:paddingBottom">24dp</item>
</style>
</resources>

View File

@@ -28,22 +28,37 @@
android:title="@string/status_number"
android:summary="@string/summary_placeholder"/>
<!-- SIM status -->
<!-- SIM status Sim Slot 1 -->
<Preference
android:key="sim_status"
android:key="sim_status_sim_1"
android:title="@string/sim_status_title"
android:summary="@string/summary_placeholder"/>
<!-- SIM status Sim Slot 2-->
<Preference
android:key="sim_status_sim_2"
android:title="@string/sim_status_title_sim_slot_2"
android:summary="@string/summary_placeholder"/>
<!-- Model & hardware -->
<Preference
android:key="device_model"
android:title="@string/hardware_info"
android:summary="@string/summary_placeholder"/>
<!-- IMEI -->
<!-- IMEI Sim Slot 1 -->
<Preference
android:key="imei_info"
android:key="imei_info_sim_slot_1"
android:title="@string/status_imei"
settings:keywords="@string/keywords_imei_info"
android:summary="@string/summary_placeholder"/>
<!-- IMEI Sim Slot 2 -->
<Preference
android:key="imei_info_sim_slot_2"
android:title="@string/imei_multi_sim_slot_2"
settings:keywords="@string/keywords_imei_info"
android:summary="@string/summary_placeholder"/>
<!-- Android version -->

View File

@@ -14,45 +14,72 @@
limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/encryption_and_credential_settings_title"
android:key="encryption_and_credentials_screen">
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/encryption_and_credential_settings_title"
android:key="encryption_and_credentials_screen">
<PreferenceCategory android:key="credentials_management"
android:title="@string/credentials_title"
android:persistent="false"
android:order="100">
<PreferenceCategory
android:key="encryption_and_credentials_status_category"
android:title="@string/crypt_keeper_settings_title">
<com.android.settingslib.RestrictedPreference android:key="credential_storage_type"
android:title="@string/credential_storage_type" />
<Preference
android:key="encryption_and_credentials_encryption_status"
android:title="@string/crypt_keeper_encrypt_title"
android:fragment="com.android.settings.security.CryptKeeperSettings"
android:summary="@string/summary_placeholder" />
<Preference android:key="trusted_credentials"
android:title="@string/trusted_credentials"
android:summary="@string/trusted_credentials_summary"
android:fragment="com.android.settings.TrustedCredentialsSettings"/>
</PreferenceCategory>
<com.android.settingslib.RestrictedPreference android:key="user_credentials"
android:title="@string/user_credentials"
android:summary="@string/user_credentials_summary"
android:fragment="com.android.settings.UserCredentialsSettings"/>
<PreferenceCategory
android:key="credentials_management"
android:title="@string/credentials_title"
android:persistent="false"
android:order="100">
<com.android.settingslib.RestrictedPreference android:key="credentials_install"
android:title="@string/credentials_install"
android:summary="@string/credentials_install_summary">
<com.android.settingslib.RestrictedPreference
android:key="credential_storage_type"
android:title="@string/credential_storage_type"
android:summary="@string/summary_placeholder"
settings:userRestriction="no_config_credentials" />
<intent android:action="android.credentials.INSTALL"
android:targetPackage="com.android.certinstaller"
android:targetClass="com.android.certinstaller.CertInstallerMain"/>
<Preference
android:key="trusted_credentials"
android:title="@string/trusted_credentials"
android:summary="@string/trusted_credentials_summary"
android:fragment="com.android.settings.TrustedCredentialsSettings" />
<com.android.settingslib.RestrictedPreference
android:key="user_credentials"
android:title="@string/user_credentials"
android:summary="@string/user_credentials_summary"
android:fragment="com.android.settings.UserCredentialsSettings"
settings:userRestriction="no_config_credentials" />
<com.android.settingslib.RestrictedPreference
android:key="credentials_install"
android:title="@string/credentials_install"
android:summary="@string/credentials_install_summary"
settings:userRestriction="no_config_credentials">
<intent
android:action="android.credentials.INSTALL"
android:targetPackage="com.android.certinstaller"
android:targetClass="com.android.certinstaller.CertInstallerMain" />
</com.android.settingslib.RestrictedPreference>
<com.android.settingslib.RestrictedPreference android:key="credentials_reset"
android:title="@string/credentials_reset"
android:summary="@string/credentials_reset_summary">
<com.android.settingslib.RestrictedPreference
android:key="credentials_reset"
android:title="@string/credentials_reset"
android:summary="@string/credentials_reset_summary"
settings:userRestriction="no_config_credentials">
<intent android:action="com.android.credentials.RESET"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.CredentialStorage"/>
<intent
android:action="com.android.credentials.RESET"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.CredentialStorage" />
</com.android.settingslib.RestrictedPreference>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 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_encrypted_screen"
android:title="@string/security_settings_title">
<PreferenceCategory
android:key="security_category_for_encrypted_device"
android:title="@string/crypt_keeper_settings_title">
<Preference
android:key="crypt_keeper_encrypt_title"
android:title="@string/crypt_keeper_encrypt_title"
android:summary="@string/crypt_keeper_encrypted_summary"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -69,7 +69,7 @@
<Preference android:key="manage_trust_agents"
android:title="@string/manage_trust_agents"
android:persistent="false"
android:fragment="com.android.settings.TrustAgentSettings"/>
android:fragment="com.android.settings.security.trustagent.TrustAgentSettings"/>
<Preference
android:key="screen_pinning_settings"

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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_unencrypted_screen"
android:title="@string/crypt_keeper_settings_title">
<PreferenceCategory
android:key="security_category_for_unencrypted_device"
android:title="@string/crypt_keeper_settings_title">
<Preference
android:key="encryption"
android:title="@string/crypt_keeper_encrypt_title"
android:fragment="com.android.settings.CryptKeeperSettings" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -32,11 +32,16 @@ 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.imei.ImeiInfoDualSimPreferenceController;
import com.android.settings.deviceinfo.imei.ImeiInfoPreferenceControllerV2;
import com.android.settings.deviceinfo.KernelVersionPreferenceController;
import com.android.settings.deviceinfo.ManualPreferenceController;
import com.android.settings.deviceinfo.RegulatoryInfoPreferenceController;
import com.android.settings.deviceinfo.SafetyInfoPreferenceController;
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;
@@ -120,18 +125,21 @@ public class DeviceInfoSettings extends DashboardFragment implements Indexable {
Activity activity, Fragment fragment, Lifecycle lifecycle) {
if (FeatureFlagUtils.isEnabled(DEVICE_INFO_V2_FEATURE_FLAG)) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
// Device name
// Phone number
// SIM status
controllers.add(new SimStatusPreferenceControllerV2(context, fragment));
controllers.add(new SimStatusDualSimPreferenceController(context, fragment));
controllers.add(new DeviceModelPreferenceController(context, fragment));
// IMEI
controllers.add(new ImeiInfoPreferenceControllerV2(context, fragment));
// Android version
controllers.add(new ImeiInfoDualSimPreferenceController(context, fragment));
controllers.add(new FirmwareVersionPreferenceControllerV2(context, fragment));
// IP address

View File

@@ -1,107 +0,0 @@
/*
* Copyright (C) 2014 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;
import android.content.ComponentName;
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.service.trust.TrustAgentService;
import android.util.AttributeSet;
import android.util.Slog;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
// TODO(b/34461256): Refactor TrustAgentUtils into TrustAgentManager.
public class TrustAgentUtils {
static final String TAG = "TrustAgentUtils";
private static final String TRUST_AGENT_META_DATA = TrustAgentService.TRUST_AGENT_META_DATA;
public static class TrustAgentComponentInfo {
ComponentName componentName;
String title;
String summary;
EnforcedAdmin admin = null;
}
public static ComponentName getComponentName(ResolveInfo resolveInfo) {
if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
}
public static TrustAgentComponentInfo getSettingsComponent(
PackageManager pm, ResolveInfo resolveInfo) {
if (resolveInfo == null || resolveInfo.serviceInfo == null
|| resolveInfo.serviceInfo.metaData == null) return null;
String cn = null;
TrustAgentComponentInfo trustAgentComponentInfo = new TrustAgentComponentInfo();
XmlResourceParser parser = null;
Exception caughtException = null;
try {
parser = resolveInfo.serviceInfo.loadXmlMetaData(pm, TRUST_AGENT_META_DATA);
if (parser == null) {
Slog.w(TAG, "Can't find " + TRUST_AGENT_META_DATA + " meta-data");
return null;
}
Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
}
String nodeName = parser.getName();
if (!"trust-agent".equals(nodeName)) {
Slog.w(TAG, "Meta-data does not start with trust-agent tag");
return null;
}
TypedArray sa =
res.obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
trustAgentComponentInfo.summary =
sa.getString(com.android.internal.R.styleable.TrustAgent_summary);
trustAgentComponentInfo.title =
sa.getString(com.android.internal.R.styleable.TrustAgent_title);
cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
sa.recycle();
} catch (PackageManager.NameNotFoundException e) {
caughtException = e;
} catch (IOException e) {
caughtException = e;
} catch (XmlPullParserException e) {
caughtException = e;
} finally {
if (parser != null) parser.close();
}
if (caughtException != null) {
Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
return null;
}
if (cn != null && cn.indexOf('/') < 0) {
cn = resolveInfo.serviceInfo.packageName + "/" + cn;
}
trustAgentComponentInfo.componentName = (cn == null) ? null : ComponentName.unflattenFromString(cn);
return trustAgentComponentInfo;
}
}

View File

@@ -28,8 +28,7 @@ import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.widget.SwitchBar;
import com.android.settings.widget.ToggleSwitch;
public abstract class ToggleFeaturePreferenceFragment
extends SettingsPreferenceFragment {
public abstract class ToggleFeaturePreferenceFragment extends SettingsPreferenceFragment {
protected SwitchBar mSwitchBar;
protected ToggleSwitch mToggleSwitch;
@@ -43,9 +42,7 @@ public abstract class ToggleFeaturePreferenceFragment
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final int resId = getPreferenceScreenResId();
if (usePreferenceScreenTitle() && resId > 0) {
addPreferencesFromResource(resId);
} else {
if (!usePreferenceScreenTitle() || resId <= 0) {
PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
getActivity());
setPreferenceScreen(preferenceScreen);

View File

@@ -30,12 +30,12 @@ import com.android.settings.applications.defaultapps.DefaultPaymentSettingsPrefe
import com.android.settings.applications.defaultapps.DefaultPhonePreferenceController;
import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController;
import com.android.settings.applications.defaultapps.DefaultWorkBrowserPreferenceController;
import com.android.settings.widget.WorkOnlyCategoryPreferenceController;
import com.android.settings.applications.defaultapps.DefaultWorkPhonePreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
@@ -75,7 +75,7 @@ public class DefaultAppSettings extends DashboardFragment {
workControllers.add(new DefaultWorkPhonePreferenceController(context));
workControllers.add(new DefaultWorkBrowserPreferenceController(context));
controllers.addAll(workControllers);
controllers.add(new WorkOnlyCategoryPreferenceController(
controllers.add(new PreferenceCategoryController(
context, KEY_DEFAULT_WORK_CATEGORY, workControllers));
controllers.add(new DefaultAssistPreferenceController(context, KEY_ASSIST_VOICE_INPUT,
false /* showSetting */));

View File

@@ -63,9 +63,7 @@ public class ManageDomainUrls extends SettingsPreferenceFragment
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setAnimationAllowed(true);
if (usePreferenceScreenTitle()) {
addPreferencesFromResource(R.xml.manage_domain_url_settings);
} else {
if (!usePreferenceScreenTitle()) {
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
}
mApplicationsState = ApplicationsState.getInstance(
@@ -74,6 +72,11 @@ public class ManageDomainUrls extends SettingsPreferenceFragment
setHasOptionsMenu(true);
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.manage_domain_url_settings;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

View File

@@ -18,7 +18,6 @@ package com.android.settings.core.gateway;
import com.android.settings.ApnEditor;
import com.android.settings.ApnSettings;
import com.android.settings.CryptKeeperSettings;
import com.android.settings.DateTimeSettings;
import com.android.settings.DeviceAdminSettings;
import com.android.settings.DeviceInfoSettings;
@@ -26,7 +25,6 @@ import com.android.settings.DisplaySettings;
import com.android.settings.IccLockSettings;
import com.android.settings.MasterClear;
import com.android.settings.PrivacySettings;
import com.android.settings.SecuritySettings;
import com.android.settings.Settings;
import com.android.settings.TestingSettings;
import com.android.settings.TetherSettings;
@@ -45,7 +43,6 @@ import com.android.settings.applications.DefaultAppSettings;
import com.android.settings.applications.DrawOverlayDetails;
import com.android.settings.applications.ExternalSourcesDetails;
import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.applications.ManageDomainUrls;
import com.android.settings.applications.NotificationApps;
import com.android.settings.applications.PictureInPictureDetails;
@@ -56,6 +53,7 @@ import com.android.settings.applications.UsageAccessDetails;
import com.android.settings.applications.VrListenerSettings;
import com.android.settings.applications.WriteSettingsDetails;
import com.android.settings.applications.assist.ManageAssist;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
import com.android.settings.bluetooth.BluetoothSettings;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
@@ -106,8 +104,8 @@ import com.android.settings.notification.NotificationAccessSettings;
import com.android.settings.notification.NotificationStation;
import com.android.settings.notification.SoundSettings;
import com.android.settings.notification.ZenAccessSettings;
import com.android.settings.notification.ZenModeBehaviorSettings;
import com.android.settings.notification.ZenModeAutomationSettings;
import com.android.settings.notification.ZenModeBehaviorSettings;
import com.android.settings.notification.ZenModeEventRuleSettings;
import com.android.settings.notification.ZenModeScheduleRuleSettings;
import com.android.settings.notification.ZenModeSettings;
@@ -115,7 +113,9 @@ import com.android.settings.password.ChooseLockPassword;
import com.android.settings.password.ChooseLockPattern;
import com.android.settings.print.PrintJobSettingsFragment;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.security.CryptKeeperSettings;
import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.SecuritySettings;
import com.android.settings.sim.SimSettings;
import com.android.settings.support.SupportDashboardActivity;
import com.android.settings.system.ResetDashboardFragment;

View File

@@ -19,7 +19,6 @@ package com.android.settings.dashboard;
import android.util.ArrayMap;
import com.android.settings.DisplaySettings;
import com.android.settings.SecuritySettings;
import com.android.settings.Settings;
import com.android.settings.accounts.AccountDetailDashboardFragment;
import com.android.settings.accounts.UserAndAccountDashboardFragment;
@@ -35,6 +34,7 @@ import com.android.settings.network.NetworkDashboardFragment;
import com.android.settings.notification.ConfigureNotificationSettings;
import com.android.settings.notification.SoundSettings;
import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.SecuritySettings;
import com.android.settings.system.SystemDashboardFragment;
import com.android.settingslib.drawer.CategoryKey;

View File

@@ -24,6 +24,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.service.settings.suggestions.Suggestion;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.support.v7.widget.LinearLayoutManager;
import android.util.Log;
import android.view.LayoutInflater;
@@ -50,6 +51,7 @@ import com.android.settingslib.drawer.SettingsDrawerActivity.CategoryListener;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.suggestions.SuggestionList;
import com.android.settingslib.suggestions.SuggestionParser;
import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.List;
@@ -181,12 +183,6 @@ public class DashboardSummary extends InstrumentedFragment
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.dashboard, container, false);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@@ -198,9 +194,10 @@ public class DashboardSummary extends InstrumentedFragment
}
@Override
public void onViewCreated(View view, Bundle bundle) {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
long startTime = System.currentTimeMillis();
mDashboard = view.findViewById(R.id.dashboard_container);
final View root = inflater.inflate(R.layout.dashboard, container, false);
mDashboard = root.findViewById(R.id.dashboard_container);
mLayoutManager = new LinearLayoutManager(getContext());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
if (bundle != null) {
@@ -218,19 +215,19 @@ public class DashboardSummary extends InstrumentedFragment
mSummaryLoader.setSummaryConsumer(mAdapter);
ActionBarShadowController.attachToRecyclerView(
getActivity().findViewById(R.id.search_bar_container), getLifecycle(), mDashboard);
rebuildUI();
if (DEBUG_TIMING) {
Log.d(TAG, "onViewCreated took "
Log.d(TAG, "onCreateView took "
+ (System.currentTimeMillis() - startTime) + " ms");
}
rebuildUI();
return root;
}
@VisibleForTesting
void rebuildUI() {
if (!mSuggestionFeatureProvider.isSuggestionEnabled(getContext())) {
Log.d(TAG, "Suggestion v1 feature is disabled, skipping suggestion v1");
updateCategory();
ThreadUtils.postOnBackgroundThread(() -> updateCategory());
} else {
new SuggestionLoader().execute();
// Set categories on their own if loading suggestions takes too long.
@@ -340,11 +337,12 @@ public class DashboardSummary extends InstrumentedFragment
}
}
@WorkerThread
void updateCategory() {
final DashboardCategory category = mDashboardFeatureProvider.getTilesForCategory(
CategoryKey.CATEGORY_HOMEPAGE);
mSummaryLoader.updateSummaryToCache(category);
mAdapter.setCategory(category);
ThreadUtils.postOnMainThread(() -> mAdapter.setCategory(category));
}
/**

View File

@@ -60,23 +60,6 @@ public class SummaryLoader {
private boolean mWorkerListening;
private ArraySet<BroadcastReceiver> mReceivers = new ArraySet<>();
public SummaryLoader(Activity activity, List<DashboardCategory> categories) {
mDashboardFeatureProvider = FeatureFactory.getFactory(activity)
.getDashboardFeatureProvider(activity);
mCategoryKey = null;
mWorkerThread = new HandlerThread("SummaryLoader", Process.THREAD_PRIORITY_BACKGROUND);
mWorkerThread.start();
mWorker = new Worker(mWorkerThread.getLooper());
mActivity = activity;
for (int i = 0; i < categories.size(); i++) {
List<Tile> tiles = categories.get(i).tiles;
for (int j = 0; j < tiles.size(); j++) {
Tile tile = tiles.get(j);
mWorker.obtainMessage(Worker.MSG_GET_PROVIDER, tile).sendToTarget();
}
}
}
public SummaryLoader(Activity activity, String categoryKey) {
mDashboardFeatureProvider = FeatureFactory.getFactory(activity)
.getDashboardFeatureProvider(activity);
@@ -85,17 +68,6 @@ public class SummaryLoader {
mWorkerThread.start();
mWorker = new Worker(mWorkerThread.getLooper());
mActivity = activity;
final DashboardCategory category =
mDashboardFeatureProvider.getTilesForCategory(categoryKey);
if (category == null || category.tiles == null) {
return;
}
List<Tile> tiles = category.tiles;
for (Tile tile : tiles) {
mWorker.obtainMessage(Worker.MSG_GET_PROVIDER, tile).sendToTarget();
}
}
public void release() {
@@ -153,15 +125,32 @@ public class SummaryLoader {
* Only call from the main thread.
*/
public void setListening(boolean listening) {
if (mListening == listening) return;
if (mListening == listening) {
return;
}
mListening = listening;
// Unregister listeners immediately.
for (int i = 0; i < mReceivers.size(); i++) {
mActivity.unregisterReceiver(mReceivers.valueAt(i));
}
mReceivers.clear();
mWorker.removeMessages(Worker.MSG_SET_LISTENING);
mWorker.obtainMessage(Worker.MSG_SET_LISTENING, listening ? 1 : 0, 0).sendToTarget();
if (!listening) {
// Stop listen
mWorker.obtainMessage(Worker.MSG_SET_LISTENING, 0 /* listening */).sendToTarget();
} else {
// Start listen
if (mSummaryProviderMap.isEmpty()) {
// Category not initialized yet, init before starting to listen
if (!mWorker.hasMessages(Worker.MSG_GET_CATEGORY_TILES_AND_SET_LISTENING)) {
mWorker.sendEmptyMessage(Worker.MSG_GET_CATEGORY_TILES_AND_SET_LISTENING);
}
} else {
// Category already initialized, start listening immediately
mWorker.obtainMessage(Worker.MSG_SET_LISTENING, 1 /* listening */).sendToTarget();
}
}
}
private SummaryProvider getSummaryProvider(Tile tile) {
@@ -236,9 +225,13 @@ public class SummaryLoader {
}
private synchronized void setListeningW(boolean listening) {
if (mWorkerListening == listening) return;
if (mWorkerListening == listening) {
return;
}
mWorkerListening = listening;
if (DEBUG) Log.d(TAG, "Listening " + listening);
if (DEBUG) {
Log.d(TAG, "Listening " + listening);
}
for (SummaryProvider p : mSummaryProviderMap.keySet()) {
try {
p.setListening(listening);
@@ -271,7 +264,6 @@ public class SummaryLoader {
}
public interface SummaryProvider {
void setListening(boolean listening);
}
@@ -285,8 +277,9 @@ public class SummaryLoader {
}
private class Worker extends Handler {
private static final int MSG_GET_PROVIDER = 1;
private static final int MSG_SET_LISTENING = 2;
private static final int MSG_GET_CATEGORY_TILES_AND_SET_LISTENING = 1;
private static final int MSG_GET_PROVIDER = 2;
private static final int MSG_SET_LISTENING = 3;
public Worker(Looper looper) {
super(looper);
@@ -295,6 +288,18 @@ public class SummaryLoader {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_GET_CATEGORY_TILES_AND_SET_LISTENING:
final DashboardCategory category =
mDashboardFeatureProvider.getTilesForCategory(mCategoryKey);
if (category == null || category.tiles == null) {
return;
}
final List<Tile> tiles = category.tiles;
for (Tile tile : tiles) {
makeProviderW(tile);
}
setListeningW(true);
break;
case MSG_GET_PROVIDER:
Tile tile = (Tile) msg.obj;
makeProviderW(tile);

View File

@@ -59,7 +59,9 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setAnimationAllowed(true);
addPreferencesFromResource(R.xml.unrestricted_data_access_settings);
if (!usePreferenceScreenTitle()) {
addPreferencesFromResource(R.xml.unrestricted_data_access_settings);
}
mApplicationsState = ApplicationsState.getInstance(
(Application) getContext().getApplicationContext());
mDataSaverBackend = new DataSaverBackend(getContext());
@@ -208,6 +210,11 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
return MetricsEvent.DATA_USAGE_UNRESTRICTED_ACCESS;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.unrestricted_data_access_settings;
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference instanceof AccessPreference) {

View File

@@ -27,13 +27,17 @@ import android.text.TextUtils;
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 {

View File

@@ -19,8 +19,13 @@ package com.android.settings.deviceinfo;
import android.content.Context;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.deviceinfo.imei.ImeiInfoPreferenceControllerV2;
import com.android.settingslib.deviceinfo.AbstractSimStatusImeiInfoPreferenceController;
/**
* deprecated in favour of {@link ImeiInfoPreferenceControllerV2}
*/
@Deprecated
public class ImeiInfoPreferenceController extends AbstractSimStatusImeiInfoPreferenceController
implements PreferenceControllerMixin {

View File

@@ -22,7 +22,6 @@ import android.support.v7.preference.PreferenceScreen;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
@@ -34,7 +33,12 @@ import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.deviceinfo.imei.ImeiInfoPreferenceControllerV2;
/**
* deprecated in favor of {@link ImeiInfoPreferenceControllerV2}
*/
@Deprecated
public class ImeiInformation extends SettingsPreferenceFragment {
private static final String KEY_PRL_VERSION = "prl_version";

View File

@@ -73,7 +73,9 @@ import java.util.List;
* # Operator info (area update info cell broadcast)
* # Signal Strength
*
* deprecated in favor of {@link com.android.settings.deviceinfo.simstatus.SimStatusDialogFragment}
*/
@Deprecated
public class SimStatus extends SettingsPreferenceFragment {
private static final String TAG = "SimStatus";

View File

@@ -19,8 +19,13 @@ package com.android.settings.deviceinfo;
import android.content.Context;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.deviceinfo.simstatus.SimStatusPreferenceControllerV2;
import com.android.settingslib.deviceinfo.AbstractSimStatusImeiInfoPreferenceController;
/**
* deprecated in favor of {@link SimStatusPreferenceControllerV2}
*/
@Deprecated
public class SimStatusPreferenceController extends AbstractSimStatusImeiInfoPreferenceController
implements PreferenceControllerMixin {

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,99 @@
/*
* 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.imei;
import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
import android.app.Fragment;
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.deviceinfo.AbstractSimStatusImeiInfoPreferenceController;
/**
* Controller that manages preference for single and dual sim devices.
*/
public abstract class AbstractImeiInfoPreferenceController extends
AbstractSimStatusImeiInfoPreferenceController implements PreferenceControllerMixin {
protected final boolean mIsMultiSim;
protected final TelephonyManager mTelephonyManager;
private Preference mPreference;
private Fragment mFragment;
public AbstractImeiInfoPreferenceController(Context context, Fragment fragment) {
super(context);
mFragment = fragment;
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
mIsMultiSim = mTelephonyManager.getPhoneCount() > 1;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
if (mPreference == null) {
return;
}
final int phoneType = mTelephonyManager.getPhoneType();
if (phoneType == PHONE_TYPE_CDMA) {
mPreference.setTitle(getTitleForCdmaPhone());
mPreference.setSummary(getMeid());
} else {
// GSM phone
mPreference.setTitle(getTitleForGsmPhone());
mPreference.setSummary(mTelephonyManager.getImei(getSimSlot()));
}
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return false;
}
ImeiInfoDialogFragment.show(mFragment, getSimSlot(), mPreference.getTitle().toString());
return true;
}
/**
* @return The preference title for phones based on CDMA technology.
*/
protected abstract String getTitleForCdmaPhone();
/**
* @return The preference title for phones based on GSM technology.
*/
protected abstract String getTitleForGsmPhone();
/**
* @return The sim slot to retrieve IMEI/CDMA information about.
*/
protected abstract int getSimSlot();
@VisibleForTesting
String getMeid() {
return mTelephonyManager.getMeid(getSimSlot());
}
}

View File

@@ -0,0 +1,160 @@
/*
* 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.imei;
import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.TtsSpan;
import com.android.internal.telephony.PhoneConstants;
import com.android.settings.R;
import java.util.List;
public class ImeiInfoDialogController {
@VisibleForTesting
static final int ID_PRL_VERSION_VALUE = R.id.prl_version_value;
private static final int ID_MIN_NUMBER_LABEL = R.id.min_number_label;
@VisibleForTesting
static final int ID_MIN_NUMBER_VALUE = R.id.min_number_value;
@VisibleForTesting
static final int ID_MEID_NUMBER_VALUE = R.id.meid_number_value;
@VisibleForTesting
static final int ID_ICC_ID_LABEL = R.id.icc_id_label;
@VisibleForTesting
static final int ID_ICC_ID_VALUE = R.id.icc_id_value;
@VisibleForTesting
static final int ID_IMEI_VALUE = R.id.imei_value;
@VisibleForTesting
static final int ID_IMEI_SV_VALUE = R.id.imei_sv_value;
@VisibleForTesting
static final int ID_CDMA_SETTINGS = R.id.cdma_settings;
@VisibleForTesting
static final int ID_GSM_SETTINGS = R.id.gsm_settings;
private static CharSequence getTextAsDigits(CharSequence text) {
if (TextUtils.isDigitsOnly(text)) {
final Spannable spannable = new SpannableStringBuilder(text);
final TtsSpan span = new TtsSpan.DigitsBuilder(text.toString()).build();
spannable.setSpan(span, 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
text = spannable;
}
return text;
}
private final ImeiInfoDialogFragment mDialog;
private final TelephonyManager mTelephonyManager;
private final SubscriptionInfo mSubscriptionInfo;
private final int mSlotId;
public ImeiInfoDialogController(@NonNull ImeiInfoDialogFragment dialog, int slotId) {
mDialog = dialog;
mSlotId = slotId;
final Context context = dialog.getContext();
mTelephonyManager = (TelephonyManager) context.getSystemService(
Context.TELEPHONY_SERVICE);
mSubscriptionInfo = getSubscriptionInfo(context, slotId);
}
/**
* Sets IMEI/MEID information based on whether the device is CDMA or GSM.
*/
public void populateImeiInfo() {
if (mSubscriptionInfo == null) {
return;
}
if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
updateDialogForCdmaPhone();
} else {
updateDialogForGsmPhone();
}
}
private void updateDialogForCdmaPhone() {
final Resources res = mDialog.getContext().getResources();
mDialog.setText(ID_MEID_NUMBER_VALUE, getMeid());
mDialog.setText(ID_MIN_NUMBER_VALUE,
mTelephonyManager.getCdmaMin(mSubscriptionInfo.getSubscriptionId()));
if (res.getBoolean(R.bool.config_msid_enable)) {
mDialog.setText(ID_MIN_NUMBER_LABEL,
res.getString(R.string.status_msid_number));
}
mDialog.setText(ID_PRL_VERSION_VALUE, getCdmaPrlVersion());
if (isCdmaLteEnabled()) {
// Show ICC ID and IMEI for LTE device
mDialog.setText(ID_ICC_ID_VALUE, mSubscriptionInfo.getIccId());
mDialog.setText(ID_IMEI_VALUE,
getTextAsDigits(mTelephonyManager.getImei(mSlotId)));
mDialog.setText(ID_IMEI_SV_VALUE,
getTextAsDigits(mTelephonyManager.getDeviceSoftwareVersion(mSlotId)));
} else {
// device is not GSM/UMTS, do not display GSM/UMTS features
mDialog.removeViewFromScreen(ID_GSM_SETTINGS);
mDialog.removeViewFromScreen(ID_ICC_ID_LABEL);
mDialog.removeViewFromScreen(ID_ICC_ID_VALUE);
}
}
private void updateDialogForGsmPhone() {
mDialog.setText(ID_IMEI_VALUE, getTextAsDigits(mTelephonyManager.getImei(mSlotId)));
mDialog.setText(ID_IMEI_SV_VALUE,
getTextAsDigits(mTelephonyManager.getDeviceSoftwareVersion(mSlotId)));
// device is not CDMA, do not display CDMA features
mDialog.removeViewFromScreen(ID_CDMA_SETTINGS);
mDialog.removeViewFromScreen(ID_ICC_ID_LABEL);
mDialog.removeViewFromScreen(ID_ICC_ID_VALUE);
}
private SubscriptionInfo getSubscriptionInfo(Context context, int slotId) {
final List<SubscriptionInfo> subscriptionInfoList = SubscriptionManager.from(context)
.getActiveSubscriptionInfoList();
if (subscriptionInfoList == null) {
return null;
}
return subscriptionInfoList.get(slotId);
}
@VisibleForTesting
String getCdmaPrlVersion() {
return mTelephonyManager.getCdmaPrlVersion();
}
@VisibleForTesting
boolean isCdmaLteEnabled() {
return mTelephonyManager.getLteOnCdmaMode(mSubscriptionInfo.getSubscriptionId())
== PhoneConstants.LTE_ON_CDMA_TRUE;
}
@VisibleForTesting
String getMeid() {
return mTelephonyManager.getMeid(mSlotId);
}
}

View File

@@ -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.imei;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
public class ImeiInfoDialogFragment extends InstrumentedDialogFragment {
@VisibleForTesting
static final String TAG = "ImeiInfoDialog";
private static final String SLOT_ID_BUNDLE_KEY = "arg_key_slot_id";
private static final String DIALOG_TITLE_BUNDLE_KEY = "arg_key_dialog_title";
private View mRootView;
public static void show(@NonNull Fragment host, int slotId, String dialogTitle) {
final FragmentManager manager = host.getChildFragmentManager();
if (manager.findFragmentByTag(TAG) == null) {
final Bundle bundle = new Bundle();
bundle.putInt(SLOT_ID_BUNDLE_KEY, slotId);
bundle.putString(DIALOG_TITLE_BUNDLE_KEY, dialogTitle);
final ImeiInfoDialogFragment dialog = new ImeiInfoDialogFragment();
dialog.setArguments(bundle);
dialog.show(manager, TAG);
}
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.DIALOG_IMEI_INFO;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle bundle = getArguments();
final int slotId = bundle.getInt(SLOT_ID_BUNDLE_KEY);
final String dialogTitle = bundle.getString(DIALOG_TITLE_BUNDLE_KEY);
final ImeiInfoDialogController controller = new ImeiInfoDialogController(this, slotId);
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(dialogTitle)
.setPositiveButton(android.R.string.ok, null);
mRootView = LayoutInflater.from(builder.getContext())
.inflate(R.layout.dialog_imei_info, null /* parent */);
controller.populateImeiInfo();
return builder.setView(mRootView).create();
}
public void removeViewFromScreen(int viewId) {
final View view = mRootView.findViewById(viewId);
if (view != null) {
view.setVisibility(View.GONE);
}
}
public void setText(int viewId, CharSequence text) {
final TextView textView = mRootView.findViewById(viewId);
if (TextUtils.isEmpty(text)) {
text = getResources().getString(R.string.device_info_default);
}
if (textView != null) {
textView.setText(text);
}
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.imei;
import android.app.Fragment;
import android.content.Context;
import com.android.settings.R;
public class ImeiInfoDualSimPreferenceController extends AbstractImeiInfoPreferenceController {
private static final String KEY_IMEI_INFO_DUAL_SIM = "imei_info_sim_slot_2";
private static final int SIM_SLOT = 1;
public ImeiInfoDualSimPreferenceController(Context context, Fragment fragment) {
super(context, fragment);
}
@Override
public boolean isAvailable() {
return super.isAvailable() && mIsMultiSim;
}
@Override
public String getPreferenceKey() {
return KEY_IMEI_INFO_DUAL_SIM;
}
@Override
protected String getTitleForCdmaPhone() {
return mContext.getResources().getString(R.string.meid_multi_sim_sim_slot_2);
}
@Override
protected String getTitleForGsmPhone() {
return mContext.getResources().getString(R.string.imei_multi_sim_slot_2);
}
@Override
protected int getSimSlot() {
return SIM_SLOT;
}
}

View File

@@ -0,0 +1,55 @@
/*
* 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.imei;
import android.app.Fragment;
import android.content.Context;
import com.android.settings.R;
public class ImeiInfoPreferenceControllerV2 extends AbstractImeiInfoPreferenceController {
public static final int SIM_SLOT = 0;
private static final String KEY_IMEI_INFO = "imei_info_sim_slot_1";
public ImeiInfoPreferenceControllerV2(Context context, Fragment fragment) {
super(context, fragment);
}
@Override
public String getPreferenceKey() {
return KEY_IMEI_INFO;
}
@Override
protected String getTitleForCdmaPhone() {
return mIsMultiSim ? mContext.getResources().getString(R.string.meid_multi_sim_sim_slot_1)
: mContext.getResources().getString(R.string.status_meid_number);
}
@Override
protected String getTitleForGsmPhone() {
return mIsMultiSim ? mContext.getResources().getString(R.string.imei_multi_sim_slot_1)
: mContext.getResources().getString(R.string.status_imei);
}
@Override
protected int getSimSlot() {
return SIM_SLOT;
}
}

View File

@@ -0,0 +1,98 @@
/*
* 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.simstatus;
import android.app.Fragment;
import android.content.Context;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.deviceinfo.AbstractSimStatusImeiInfoPreferenceController;
import java.util.List;
public abstract class AbstractSimStatusPreferenceController extends
AbstractSimStatusImeiInfoPreferenceController implements PreferenceControllerMixin {
protected final boolean mIsMultiSim;
protected final TelephonyManager mTelephonyManager;
private final SubscriptionManager mSubscriptionManager;
private final Fragment mFragment;
private Preference mPreference;
public AbstractSimStatusPreferenceController(Context context, Fragment fragment) {
super(context);
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
mSubscriptionManager = (SubscriptionManager) context.getSystemService(
Context.TELEPHONY_SUBSCRIPTION_SERVICE);
mFragment = fragment;
mIsMultiSim = mTelephonyManager.getPhoneCount() > 1;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
if (mPreference == null) {
return;
}
mPreference.setTitle(getPreferenceTitle());
mPreference.setSummary(getCarrierName());
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return false;
}
SimStatusDialogFragment.show(mFragment, getSimSlot(), getPreferenceTitle());
return true;
}
/**
* @return The preference title for the displayed preference.
*/
protected abstract String getPreferenceTitle();
/**
* @return The sim slot to retrieve sim status information about.
*/
protected abstract int getSimSlot();
private CharSequence getCarrierName() {
final List<SubscriptionInfo> subscriptionInfoList =
mSubscriptionManager.getActiveSubscriptionInfoList();
if (subscriptionInfoList != null) {
for (SubscriptionInfo info : subscriptionInfoList) {
if (info.getSimSlotIndex() == getSimSlot()) {
return info.getCarrierName();
}
}
}
return mContext.getText(R.string.device_info_not_available);
}
}

View File

@@ -0,0 +1,375 @@
/*
* 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.simstatus;
import static android.content.Context.TELEPHONY_SERVICE;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.UserHandle;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.telephony.CellBroadcastMessage;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import com.android.settings.R;
import com.android.settingslib.DeviceInfoUtils;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
import java.util.List;
public class SimStatusDialogController implements LifecycleObserver, OnResume, OnPause {
private final static String TAG = "SimStatusDialogCtrl";
@VisibleForTesting
final static int NETWORK_PROVIDER_VALUE_ID = R.id.operator_name_value;
@VisibleForTesting
final static int PHONE_NUMBER_VALUE_ID = R.id.number_value;
@VisibleForTesting
final static int CELLULAR_NETWORK_STATE = R.id.data_state_value;
@VisibleForTesting
final static int OPERATOR_INFO_LABEL_ID = R.id.latest_area_info_label;
@VisibleForTesting
final static int OPERATOR_INFO_VALUE_ID = R.id.latest_area_info_value;
@VisibleForTesting
final static int SERVICE_STATE_VALUE_ID = R.id.service_state_value;
@VisibleForTesting
final static int SIGNAL_STRENGTH_VALUE_ID = R.id.signal_strength_value;
@VisibleForTesting
final static int CELLULAR_NETWORK_TYPE_VALUE_ID = R.id.network_type_value;
@VisibleForTesting
final static int ROAMING_INFO_VALUE_ID = R.id.roaming_state_value;
private final static String CB_AREA_INFO_RECEIVED_ACTION =
"com.android.cellbroadcastreceiver.CB_AREA_INFO_RECEIVED";
private final static String GET_LATEST_CB_AREA_INFO_ACTION =
"com.android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO";
private final static String CELL_BROADCAST_RECEIVER_APP = "com.android.cellbroadcastreceiver";
private final SimStatusDialogFragment mDialog;
private final SubscriptionInfo mSubscriptionInfo;
private final TelephonyManager mTelephonyManager;
private final Resources mRes;
private final Context mContext;
private boolean mShowLatestAreaInfo;
private final BroadcastReceiver mAreaInfoReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (TextUtils.equals(action, CB_AREA_INFO_RECEIVED_ACTION)) {
final Bundle extras = intent.getExtras();
if (extras == null) {
return;
}
final CellBroadcastMessage cbMessage = (CellBroadcastMessage) extras.get("message");
if (cbMessage != null
&& mSubscriptionInfo.getSubscriptionId() == cbMessage.getSubId()) {
final String latestAreaInfo = cbMessage.getMessageBody();
mDialog.setText(OPERATOR_INFO_VALUE_ID, latestAreaInfo);
}
}
}
};
private PhoneStateListener mPhoneStateListener;
public SimStatusDialogController(@NonNull SimStatusDialogFragment dialog, Lifecycle lifecycle,
int slotId) {
mDialog = dialog;
mContext = dialog.getContext();
mSubscriptionInfo = getPhoneSubscriptionInfo(slotId);
mTelephonyManager = (TelephonyManager) mContext.getSystemService(
TELEPHONY_SERVICE);
mRes = mContext.getResources();
if (lifecycle != null) {
lifecycle.addObserver(this);
}
}
public void initialize() {
if (mSubscriptionInfo == null) {
return;
}
mPhoneStateListener = getPhoneStateListener();
final ServiceState serviceState = getCurrentServiceState();
updateNetworkProvider(serviceState);
updatePhoneNumber();
updateLatestAreaInfo();
updateServiceState(serviceState);
updateSignalStrength(getSignalStrength());
updateNetworkType();
updateRoamingStatus(serviceState);
}
@Override
public void onResume() {
if (mSubscriptionInfo == null) {
return;
}
mTelephonyManager.listen(mPhoneStateListener,
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
| PhoneStateListener.LISTEN_SERVICE_STATE);
if (mShowLatestAreaInfo) {
mContext.registerReceiver(mAreaInfoReceiver,
new IntentFilter(CB_AREA_INFO_RECEIVED_ACTION),
Manifest.permission.RECEIVE_EMERGENCY_BROADCAST, null /* scheduler */);
// Ask CellBroadcastReceiver to broadcast the latest area info received
final Intent getLatestIntent = new Intent(GET_LATEST_CB_AREA_INFO_ACTION);
getLatestIntent.setPackage(CELL_BROADCAST_RECEIVER_APP);
mContext.sendBroadcastAsUser(getLatestIntent, UserHandle.ALL,
Manifest.permission.RECEIVE_EMERGENCY_BROADCAST);
}
}
@Override
public void onPause() {
if (mSubscriptionInfo == null) {
return;
}
mTelephonyManager.listen(mPhoneStateListener,
PhoneStateListener.LISTEN_NONE);
if (mShowLatestAreaInfo) {
mContext.unregisterReceiver(mAreaInfoReceiver);
}
}
private void updateNetworkProvider(ServiceState serviceState) {
mDialog.setText(NETWORK_PROVIDER_VALUE_ID, serviceState.getOperatorAlphaLong());
}
private void updatePhoneNumber() {
// If formattedNumber is null or empty, it'll display as "Unknown".
mDialog.setText(PHONE_NUMBER_VALUE_ID, getPhoneNumber());
}
private void updateDataState(int state) {
String networkStateValue;
switch (state) {
case TelephonyManager.DATA_CONNECTED:
networkStateValue = mRes.getString(R.string.radioInfo_data_connected);
break;
case TelephonyManager.DATA_SUSPENDED:
networkStateValue = mRes.getString(R.string.radioInfo_data_suspended);
break;
case TelephonyManager.DATA_CONNECTING:
networkStateValue = mRes.getString(R.string.radioInfo_data_connecting);
break;
case TelephonyManager.DATA_DISCONNECTED:
networkStateValue = mRes.getString(R.string.radioInfo_data_disconnected);
break;
default:
networkStateValue = mRes.getString(R.string.radioInfo_unknown);
break;
}
mDialog.setText(CELLULAR_NETWORK_STATE, networkStateValue);
}
private void updateLatestAreaInfo() {
mShowLatestAreaInfo = Resources.getSystem().getBoolean(
com.android.internal.R.bool.config_showAreaUpdateInfoSettings)
&& mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA;
if (!mShowLatestAreaInfo) {
mDialog.removeSettingFromScreen(OPERATOR_INFO_LABEL_ID);
mDialog.removeSettingFromScreen(OPERATOR_INFO_VALUE_ID);
}
}
private void updateServiceState(ServiceState serviceState) {
final int state = serviceState.getState();
if (state == ServiceState.STATE_OUT_OF_SERVICE || state == ServiceState.STATE_POWER_OFF) {
resetSignalStrength();
}
String serviceStateValue;
switch (state) {
case ServiceState.STATE_IN_SERVICE:
serviceStateValue = mRes.getString(R.string.radioInfo_service_in);
break;
case ServiceState.STATE_OUT_OF_SERVICE:
case ServiceState.STATE_EMERGENCY_ONLY:
// Set summary string of service state to radioInfo_service_out when
// service state is both STATE_OUT_OF_SERVICE & STATE_EMERGENCY_ONLY
serviceStateValue = mRes.getString(R.string.radioInfo_service_out);
break;
case ServiceState.STATE_POWER_OFF:
serviceStateValue = mRes.getString(R.string.radioInfo_service_off);
break;
default:
serviceStateValue = mRes.getString(R.string.radioInfo_unknown);
break;
}
mDialog.setText(SERVICE_STATE_VALUE_ID, serviceStateValue);
}
private void updateSignalStrength(SignalStrength signalStrength) {
final int state = getCurrentServiceState().getState();
if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
(ServiceState.STATE_POWER_OFF == state)) {
return;
}
int signalDbm = getDbm(signalStrength);
int signalAsu = getAsuLevel(signalStrength);
if (signalDbm == -1) {
signalDbm = 0;
}
if (signalAsu == -1) {
signalAsu = 0;
}
mDialog.setText(SIGNAL_STRENGTH_VALUE_ID, mRes.getString(R.string.sim_signal_strength,
signalDbm, signalAsu));
}
private void resetSignalStrength() {
mDialog.setText(SIGNAL_STRENGTH_VALUE_ID, "0");
}
private void updateNetworkType() {
// Whether EDGE, UMTS, etc...
String networktype = null;
final int subId = mSubscriptionInfo.getSubscriptionId();
final int actualDataNetworkType = mTelephonyManager.getDataNetworkType(subId);
final int actualVoiceNetworkType = mTelephonyManager.getVoiceNetworkType(subId);
if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualDataNetworkType) {
networktype = mTelephonyManager.getNetworkTypeName(actualDataNetworkType);
} else if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualVoiceNetworkType) {
networktype = mTelephonyManager.getNetworkTypeName(actualVoiceNetworkType);
}
boolean show4GForLTE = false;
try {
final Context con = mContext.createPackageContext(
"com.android.systemui", 0 /* flags */);
final int id = con.getResources().getIdentifier("config_show4GForLTE",
"bool" /* default type */, "com.android.systemui" /* default package */);
show4GForLTE = con.getResources().getBoolean(id);
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "NameNotFoundException for show4GFotLTE");
}
if (TextUtils.equals(networktype, "LTE") && show4GForLTE) {
networktype = "4G";
}
mDialog.setText(CELLULAR_NETWORK_TYPE_VALUE_ID, networktype);
}
private void updateRoamingStatus(ServiceState serviceState) {
if (serviceState.getRoaming()) {
mDialog.setText(ROAMING_INFO_VALUE_ID, mRes.getString(R.string.radioInfo_roaming_in));
} else {
mDialog.setText(ROAMING_INFO_VALUE_ID, mRes.getString(R.string.radioInfo_roaming_not));
}
}
private SubscriptionInfo getPhoneSubscriptionInfo(int slotId) {
final List<SubscriptionInfo> subscriptionInfoList = SubscriptionManager.from(
mContext).getActiveSubscriptionInfoList();
if (subscriptionInfoList != null && subscriptionInfoList.size() > slotId) {
return subscriptionInfoList.get(slotId);
} else {
return null;
}
}
@VisibleForTesting
ServiceState getCurrentServiceState() {
return mTelephonyManager.getServiceStateForSubscriber(
mSubscriptionInfo.getSubscriptionId());
}
@VisibleForTesting
int getDbm(SignalStrength signalStrength) {
return signalStrength.getDbm();
}
@VisibleForTesting
int getAsuLevel(SignalStrength signalStrength) {
return signalStrength.getAsuLevel();
}
@VisibleForTesting
PhoneStateListener getPhoneStateListener() {
return new PhoneStateListener(
mSubscriptionInfo.getSubscriptionId()) {
@Override
public void onDataConnectionStateChanged(int state) {
updateDataState(state);
updateNetworkType();
}
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
updateSignalStrength(signalStrength);
}
@Override
public void onServiceStateChanged(ServiceState serviceState) {
updateNetworkProvider(serviceState);
updateServiceState(serviceState);
updateRoamingStatus(serviceState);
}
};
}
@VisibleForTesting
String getPhoneNumber() {
return DeviceInfoUtils.getFormattedPhoneNumber(mContext, mSubscriptionInfo);
}
@VisibleForTesting
SignalStrength getSignalStrength() {
return mTelephonyManager.getSignalStrength();
}
}

View File

@@ -0,0 +1,92 @@
/*
* 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.simstatus;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
public class SimStatusDialogFragment extends InstrumentedDialogFragment {
private static final String SIM_SLOT_BUNDLE_KEY = "arg_key_sim_slot";
private static final String DIALOG_TITLE_BUNDLE_KEY = "arg_key_dialog_title";
private static final String TAG = "SimStatusDialog";
private View mRootView;
private SimStatusDialogController mController;
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.DIALOG_SIM_STATUS;
}
public static void show(Fragment host, int slotId, String dialogTitle) {
final FragmentManager manager = host.getChildFragmentManager();
if (manager.findFragmentByTag(TAG) == null) {
final Bundle bundle = new Bundle();
bundle.putInt(SIM_SLOT_BUNDLE_KEY, slotId);
bundle.putString(DIALOG_TITLE_BUNDLE_KEY, dialogTitle);
final SimStatusDialogFragment dialog =
new SimStatusDialogFragment();
dialog.setArguments(bundle);
dialog.show(manager, TAG);
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle bundle = getArguments();
final int slotId = bundle.getInt(SIM_SLOT_BUNDLE_KEY);
final String dialogTitle = bundle.getString(DIALOG_TITLE_BUNDLE_KEY);
mController = new SimStatusDialogController(this, mLifecycle, slotId);
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(dialogTitle)
.setPositiveButton(android.R.string.ok, null /* onClickListener */);
mRootView = LayoutInflater.from(builder.getContext())
.inflate(R.layout.dialog_sim_status, null /* parent */);
mController.initialize();
return builder.setView(mRootView).create();
}
public void removeSettingFromScreen(int viewId) {
final View view = mRootView.findViewById(viewId);
if (view != null) {
view.setVisibility(View.GONE);
}
}
public void setText(int viewId, CharSequence text) {
final TextView textView = mRootView.findViewById(viewId);
if (TextUtils.isEmpty(text)) {
text = getResources().getString(R.string.device_info_default);
}
if (textView != null) {
textView.setText(text);
}
}
}

View File

@@ -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.deviceinfo.simstatus;
import android.app.Fragment;
import android.content.Context;
import com.android.settings.R;
public class SimStatusDualSimPreferenceController extends AbstractSimStatusPreferenceController {
private static final int SIM_SLOT = 1;
private static final String SIM_STATUS_DUAL_SIM_KEY = "sim_status_sim_2";
public SimStatusDualSimPreferenceController(Context context, Fragment fragment) {
super(context, fragment);
}
@Override
public boolean isAvailable() {
return super.isAvailable() && mIsMultiSim;
}
@Override
protected String getPreferenceTitle() {
return mContext.getResources().getString(R.string.sim_status_title_sim_slot_2);
}
@Override
protected int getSimSlot() {
return SIM_SLOT;
}
@Override
public String getPreferenceKey() {
return SIM_STATUS_DUAL_SIM_KEY;
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.simstatus;
import android.app.Fragment;
import android.content.Context;
import com.android.settings.R;
public class SimStatusPreferenceControllerV2 extends AbstractSimStatusPreferenceController {
public static final int SIM_SLOT = 0;
private static final String KEY_SIM_1_STATUS = "sim_status_sim_1";
public SimStatusPreferenceControllerV2(Context context, Fragment fragment) {
super(context, fragment);
}
@Override
protected String getPreferenceTitle() {
return mIsMultiSim ? mContext.getResources().getString(R.string.sim_status_title_sim_slot_1)
: mContext.getResources().getString(R.string.sim_status_title);
}
@Override
protected int getSimSlot() {
return SIM_SLOT;
}
@Override
public String getPreferenceKey() {
return KEY_SIM_1_STATUS;
}
}

View File

@@ -51,6 +51,11 @@ public class PaymentSettings extends SettingsPreferenceFragment implements Index
return MetricsEvent.NFC_PAYMENT;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.nfc_payment_settings;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -60,7 +65,6 @@ public class PaymentSettings extends SettingsPreferenceFragment implements Index
final PreferenceScreen screen;
if (usePreferenceScreenTitle()) {
addPreferencesFromResource(R.xml.nfc_payment_settings);
screen = getPreferenceScreen();
} else {
PreferenceManager manager = getPreferenceManager();

View File

@@ -25,7 +25,6 @@ import com.android.settings.DeviceInfoSettings;
import com.android.settings.DisplaySettings;
import com.android.settings.LegalSettings;
import com.android.settings.ScreenPinningSettings;
import com.android.settings.SecuritySettings;
import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
import com.android.settings.accessibility.MagnificationPreferenceFragment;
@@ -76,6 +75,7 @@ import com.android.settings.notification.ZenModeSettings;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.security.EncryptionAndCredential;
import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.SecuritySettings;
import com.android.settings.sim.SimSettings;
import com.android.settings.support.SupportDashboardActivity;
import com.android.settings.system.ResetDashboardFragment;

View File

@@ -0,0 +1,48 @@
/*
* 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 android.content.Context;
import android.os.UserManager;
import android.security.KeyStore;
import android.support.v7.preference.Preference;
import com.android.settings.R;
public class CredentialStoragePreferenceController extends
RestrictedEncryptionPreferenceController {
private static final String KEY_CREDENTIAL_STORAGE_TYPE = "credential_storage_type";
private final KeyStore mKeyStore;
public CredentialStoragePreferenceController(Context context) {
super(context, UserManager.DISALLOW_CONFIG_CREDENTIALS);
mKeyStore = KeyStore.getInstance();
}
@Override
public String getPreferenceKey() {
return KEY_CREDENTIAL_STORAGE_TYPE;
}
@Override
public void updateState(Preference preference) {
preference.setSummary(mKeyStore.isHardwareBacked()
? R.string.credential_storage_type_hardware
: R.string.credential_storage_type_software);
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings;
package com.android.settings.security;
import android.app.Activity;
import android.app.AlertDialog;
@@ -36,6 +36,9 @@ import android.view.ViewGroup;
import android.widget.Button;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.CryptKeeperConfirm;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ConfirmLockPattern;

View File

@@ -16,52 +16,29 @@
package com.android.settings.security;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.SearchIndexableResource;
import android.security.KeyStore;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
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.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreference;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Encryption and Credential settings.
* TODO: Extends this from {@link DashboardFragment} instead
*/
public class EncryptionAndCredential extends DashboardFragment {
private static final String TAG = "EncryptionAndCredential";
// Misc Settings
private static final String KEY_CREDENTIAL_STORAGE_TYPE = "credential_storage_type";
private static final String KEY_USER_CREDENTIALS = "user_credentials";
private static final String KEY_RESET_CREDENTIALS = "credentials_reset";
private static final String KEY_CREDENTIALS_INSTALL = "credentials_install";
private static final String KEY_CREDENTIALS_MANAGER = "credentials_management";
private static final int MY_USER_ID = UserHandle.myUserId();
private UserManager mUm;
private KeyStore mKeyStore;
private RestrictedPreference mResetCredentials;
private boolean mIsAdmin;
@Override
public int getMetricsCategory() {
return MetricsEvent.ENCRYPTION_AND_CREDENTIAL;
@@ -74,99 +51,28 @@ public class EncryptionAndCredential extends DashboardFragment {
@Override
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
return null;
return buildPreferenceControllers(context, getLifecycle());
}
@Override
protected int getPreferenceScreenResId() {
return 0;
return R.xml.encryption_and_credential;
}
/**
* Important!
*
* Don't forget to update the SecuritySearchIndexProvider if you are doing any change in the
* logic or adding/removing preferences here.
*/
private PreferenceScreen createPreferenceHierarchy() {
PreferenceScreen root = getPreferenceScreen();
if (root != null) {
root.removeAll();
}
addPreferencesFromResource(R.xml.encryption_and_credential);
root = getPreferenceScreen();
// Add options for device encryption
mIsAdmin = mUm.isAdminUser();
if (mIsAdmin) {
if (LockPatternUtils.isDeviceEncryptionEnabled()) {
// The device is currently encrypted.
addPreferencesFromResource(R.xml.security_settings_encrypted);
} else {
// This device supports encryption but isn't encrypted.
addPreferencesFromResource(R.xml.security_settings_unencrypted);
}
}
// Credential storage
mKeyStore = KeyStore.getInstance(); // needs to be initialized for onResume()
if (!RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
UserManager.DISALLOW_CONFIG_CREDENTIALS, MY_USER_ID)) {
RestrictedPreference userCredentials = (RestrictedPreference) root.findPreference(
KEY_USER_CREDENTIALS);
userCredentials.checkRestrictionAndSetDisabled(
UserManager.DISALLOW_CONFIG_CREDENTIALS);
RestrictedPreference credentialStorageType = (RestrictedPreference) root.findPreference(
KEY_CREDENTIAL_STORAGE_TYPE);
credentialStorageType.checkRestrictionAndSetDisabled(
UserManager.DISALLOW_CONFIG_CREDENTIALS);
RestrictedPreference installCredentials = (RestrictedPreference) root.findPreference(
KEY_CREDENTIALS_INSTALL);
installCredentials.checkRestrictionAndSetDisabled(
UserManager.DISALLOW_CONFIG_CREDENTIALS);
mResetCredentials = (RestrictedPreference) root.findPreference(KEY_RESET_CREDENTIALS);
mResetCredentials.checkRestrictionAndSetDisabled(
UserManager.DISALLOW_CONFIG_CREDENTIALS);
final int storageSummaryRes =
mKeyStore.isHardwareBacked() ? R.string.credential_storage_type_hardware
: R.string.credential_storage_type_software;
credentialStorageType.setSummary(storageSummaryRes);
} else {
PreferenceGroup credentialsManager = (PreferenceGroup)
root.findPreference(KEY_CREDENTIALS_MANAGER);
credentialsManager.removePreference(root.findPreference(KEY_RESET_CREDENTIALS));
credentialsManager.removePreference(root.findPreference(KEY_CREDENTIALS_INSTALL));
credentialsManager.removePreference(root.findPreference(KEY_CREDENTIAL_STORAGE_TYPE));
credentialsManager.removePreference(root.findPreference(KEY_USER_CREDENTIALS));
}
return root;
}
@Override
public void onResume() {
super.onResume();
// Make sure we reload the preference hierarchy since some of these settings
// depend on others...
createPreferenceHierarchy();
if (mResetCredentials != null && !mResetCredentials.isDisabledByAdmin()) {
mResetCredentials.setEnabled(!mKeyStore.isEmpty());
}
}
/**
* see confirmPatternThenDisableAndClear
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
createPreferenceHierarchy();
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
final EncryptionStatusPreferenceController encryptStatusController =
new EncryptionStatusPreferenceController(context);
controllers.add(encryptStatusController);
controllers.add(new PreferenceCategoryController(context,
"encryption_and_credentials_status_category",
Arrays.asList(encryptStatusController)));
controllers.add(new CredentialStoragePreferenceController(context));
controllers.add(new UserCredentialsPreferenceController(context));
controllers.add(new ResetCredentialsPreferenceController(context, lifecycle));
controllers.add(new InstallCredentialsPreferenceController(context));
return controllers;
}
@Override
@@ -185,14 +91,14 @@ public class EncryptionAndCredential extends DashboardFragment {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final List<SearchIndexableResource> index = new ArrayList<>();
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.encryption_and_credential;
return Arrays.asList(sir);
}
// Add everything. We will suppress some of them in getNonIndexableKeys()
index.add(getSearchResource(context, R.xml.encryption_and_credential));
index.add(getSearchResource(context, R.xml.security_settings_encrypted));
index.add(getSearchResource(context, R.xml.security_settings_unencrypted));
return index;
@Override
public List<AbstractPreferenceController> getPreferenceControllers(Context context) {
return buildPreferenceControllers(context, null /* lifecycle */);
}
@Override
@@ -200,46 +106,5 @@ public class EncryptionAndCredential extends DashboardFragment {
final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
return um.isAdminUser();
}
private SearchIndexableResource getSearchResource(Context context, int xmlResId) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = xmlResId;
return sir;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
if (!isPageSearchEnabled(context)) {
return keys;
}
final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) {
keys.add(KEY_CREDENTIALS_MANAGER);
keys.add(KEY_RESET_CREDENTIALS);
keys.add(KEY_CREDENTIALS_INSTALL);
keys.add(KEY_CREDENTIAL_STORAGE_TYPE);
keys.add(KEY_USER_CREDENTIALS);
}
final DevicePolicyManager dpm = (DevicePolicyManager)
context.getSystemService(Context.DEVICE_POLICY_SERVICE);
switch (dpm.getStorageEncryptionStatus()) {
case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
// The device is currently encrypted. Disable security_settings_unencrypted
keys.addAll(getNonIndexableKeysFromXml(
context, R.xml.security_settings_unencrypted));
break;
default:
// This device supports encryption but isn't encrypted.
keys.addAll(getNonIndexableKeysFromXml(
context, R.xml.security_settings_encrypted));
break;
}
return keys;
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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 android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
public class EncryptionStatusPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin {
private static final String PREF_KEY = "encryption_and_credentials_encryption_status";
private final UserManager mUserManager;
public EncryptionStatusPreferenceController(Context context) {
super(context);
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
}
@Override
public boolean isAvailable() {
return mUserManager.isAdminUser();
}
@Override
public String getPreferenceKey() {
return PREF_KEY;
}
@Override
public void updateState(Preference preference) {
final boolean encryptionEnabled = LockPatternUtils.isDeviceEncryptionEnabled();
if (encryptionEnabled) {
preference.setFragment(null);
preference.setSummary(R.string.crypt_keeper_encrypted_summary);
} else {
preference.setFragment(CryptKeeperSettings.class.getName());
preference.setSummary(R.string.summary_placeholder);
}
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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 android.content.Context;
import android.os.UserManager;
public class InstallCredentialsPreferenceController extends
RestrictedEncryptionPreferenceController {
private static final String KEY_CREDENTIALS_INSTALL = "credentials_install";
public InstallCredentialsPreferenceController(Context context) {
super(context, UserManager.DISALLOW_CONFIG_CREDENTIALS);
}
@Override
public String getPreferenceKey() {
return KEY_CREDENTIALS_INSTALL;
}
}

View File

@@ -0,0 +1,63 @@
/*
* 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 android.content.Context;
import android.os.UserManager;
import android.security.KeyStore;
import android.support.v7.preference.PreferenceScreen;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnResume;
public class ResetCredentialsPreferenceController extends RestrictedEncryptionPreferenceController
implements LifecycleObserver, OnResume {
private static final String KEY_RESET_CREDENTIALS = "credentials_reset";
private final KeyStore mKeyStore;
private RestrictedPreference mPreference;
public ResetCredentialsPreferenceController(Context context, Lifecycle lifecycle) {
super(context, UserManager.DISALLOW_CONFIG_CREDENTIALS);
mKeyStore = KeyStore.getInstance();
if (lifecycle != null) {
lifecycle.addObserver(this);
}
}
@Override
public String getPreferenceKey() {
return KEY_RESET_CREDENTIALS;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = (RestrictedPreference) screen.findPreference(getPreferenceKey());
}
@Override
public void onResume() {
if (mPreference != null && !mPreference.isDisabledByAdmin()) {
mPreference.setEnabled(!mKeyStore.isEmpty());
}
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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 android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
public abstract class RestrictedEncryptionPreferenceController extends
AbstractPreferenceController implements PreferenceControllerMixin {
protected final UserManager mUserManager;
private final UserHandle mUserHandle;
private final String mUserRestriction;
public RestrictedEncryptionPreferenceController(Context context, String userRestriction) {
super(context);
mUserHandle = UserHandle.of(UserHandle.myUserId());
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mUserRestriction = userRestriction;
}
@Override
public boolean isAvailable() {
return !mUserManager.hasBaseUserRestriction(mUserRestriction, mUserHandle);
}
}

View File

@@ -19,7 +19,7 @@ package com.android.settings.security;
import android.content.Context;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.trustagent.TrustAgentManager;
import com.android.settings.security.trustagent.TrustAgentManager;
import com.android.settingslib.drawer.DashboardCategory;

View File

@@ -30,8 +30,7 @@ import android.util.ArrayMap;
import android.util.Pair;
import com.android.settings.R;
import com.android.settings.trustagent.TrustAgentManager;
import com.android.settings.trustagent.TrustAgentManagerImpl;
import com.android.settings.security.trustagent.TrustAgentManager;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtils;
@@ -192,7 +191,7 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
@Override
public TrustAgentManager getTrustAgentManager() {
if (mTrustAgentManager == null) {
mTrustAgentManager = new TrustAgentManagerImpl();
mTrustAgentManager = new TrustAgentManager();
}
return mTrustAgentManager;
}

View File

@@ -14,9 +14,8 @@
* limitations under the License.
*/
package com.android.settings;
package com.android.settings.security;
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.app.Activity;
@@ -24,12 +23,9 @@ import android.app.AlertDialog;
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;
@@ -39,7 +35,6 @@ import android.os.UserManager;
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;
@@ -51,11 +46,12 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.TrustAgentUtils.TrustAgentComponentInfo;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.SummaryLoader;
@@ -71,9 +67,8 @@ import com.android.settings.password.ManagedLockPasswordProvider;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.security.OwnerInfoPreferenceController;
import com.android.settings.security.SecurityFeatureProvider;
import com.android.settings.trustagent.TrustAgentManager;
import com.android.settings.security.trustagent.TrustAgentManager;
import com.android.settings.security.trustagent.TrustAgentManager.TrustAgentComponentInfo;
import com.android.settings.widget.GearPreference;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreference;
@@ -92,8 +87,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
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";
@@ -127,11 +120,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
private static final String KEY_SECURITY_STATUS = "security_status";
private static final String SECURITY_STATUS_KEY_PREFIX = "security_status_";
// Package verifier Settings
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
static final String KEY_PACKAGE_VERIFIER_STATUS = "security_status_package_verifier";
private static final int PACKAGE_VERIFIER_STATE_ENABLED = 1;
// Device management settings
private static final String KEY_ENTERPRISE_PRIVACY = "enterprise_privacy";
private static final String KEY_MANAGE_DEVICE_ADMIN = "manage_device_admin";
@@ -141,9 +129,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
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;
@@ -225,9 +210,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
= new LockScreenNotificationPreferenceController(activity);
}
private static int getResIdForLockUnlockScreen(Context context,
LockPatternUtils lockPatternUtils, ManagedLockPasswordProvider managedPasswordProvider,
int userId) {
private static int getResIdForLockUnlockScreen(LockPatternUtils lockPatternUtils,
ManagedLockPasswordProvider managedPasswordProvider, int userId) {
final boolean isMyUser = userId == MY_USER_ID;
int resid = 0;
if (!lockPatternUtils.isSecure(userId)) {
@@ -281,7 +265,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
addPreferencesFromResource(R.xml.security_settings_status);
// Add options for lock/unlock screen
final int resid = getResIdForLockUnlockScreen(getActivity(), mLockPatternUtils,
final int resid = getResIdForLockUnlockScreen(mLockPatternUtils,
mManagedPasswordProvider, MY_USER_ID);
addPreferencesFromResource(resid);
@@ -293,9 +277,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
&& mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId)) {
addPreferencesFromResource(R.xml.security_settings_profile);
addPreferencesFromResource(R.xml.security_settings_unification);
final int profileResid = getResIdForLockUnlockScreen(
getActivity(), mLockPatternUtils, mManagedPasswordProvider,
mProfileChallengeUserId);
final int profileResid = getResIdForLockUnlockScreen(mLockPatternUtils,
mManagedPasswordProvider, mProfileChallengeUserId);
addPreferencesFromResource(profileResid);
maybeAddFingerprintPreference(root, mProfileChallengeUserId);
if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
@@ -474,11 +457,10 @@ public class SecuritySettings extends SettingsPreferenceFragment
// 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);
@@ -537,50 +519,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
return false;
}
private static ArrayList<TrustAgentComponentInfo> getActiveTrustAgents(Context context,
TrustAgentManager trustAgentManager, LockPatternUtils utils,
DevicePolicyManager dpm) {
PackageManager pm = context.getPackageManager();
ArrayList<TrustAgentComponentInfo> result = new ArrayList<TrustAgentComponentInfo>();
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 =
TrustAgentUtils.getSettingsComponent(pm, resolveInfo);
if (trustAgentComponentInfo.componentName == null ||
!enabledTrustAgents.contains(
TrustAgentUtils.getComponentName(resolveInfo)) ||
TextUtils.isEmpty(trustAgentComponentInfo.title)) continue;
if (admin != null && dpm.getTrustAgentConfiguration(
null, TrustAgentUtils.getComponentName(resolveInfo)) == null) {
trustAgentComponentInfo.admin = admin;
}
result.add(trustAgentComponentInfo);
if (ONLY_ONE_TRUST_AGENT) break;
}
}
return result;
}
private static CharSequence getActiveTrustAgentLabel(Context context,
TrustAgentManager trustAgentManager, LockPatternUtils utils,
DevicePolicyManager dpm) {
ArrayList<TrustAgentComponentInfo> agents = getActiveTrustAgents(context,
trustAgentManager, utils, dpm);
return agents.isEmpty() ? null : agents.get(0).title;
}
@Override
public void onGearClick(GearPreference p) {
if (KEY_UNLOCK_SET_OR_CHANGE.equals(p.getKey())) {
@@ -842,7 +780,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
|| lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
|| !isPasswordManaged(profileUserId, context, dpm))) {
// Add options for lock/unlock screen
final int resId = getResIdForLockUnlockScreen(context, lockPatternUtils,
final int resId = getResIdForLockUnlockScreen(lockPatternUtils,
managedPasswordProvider, MY_USER_ID);
index.add(getSearchResource(context, resId));
}
@@ -850,12 +788,12 @@ public class SecuritySettings extends SettingsPreferenceFragment
if (profileUserId != UserHandle.USER_NULL
&& lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
&& !isPasswordManaged(profileUserId, context, dpm)) {
index.add(getSearchResource(context, getResIdForLockUnlockScreen(context,
index.add(getSearchResource(context, getResIdForLockUnlockScreen(
lockPatternUtils, managedPasswordProvider, profileUserId)));
}
final SearchIndexableResource sir = getSearchResource(context,
SecuritySubSettings.getResIdForLockUnlockSubScreen(context, lockPatternUtils,
SecuritySubSettings.getResIdForLockUnlockSubScreen(lockPatternUtils,
managedPasswordProvider));
sir.className = SecuritySubSettings.class.getName();
index.add(sir);
@@ -929,8 +867,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
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);
@@ -978,216 +915,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
}
public static class SecuritySubSettings extends SettingsPreferenceFragment
implements OnPreferenceChangeListener, OwnerInfoPreferenceController.OwnerInfoCallback {
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 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 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(getActivity(),
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 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();
}
private static int getResIdForLockUnlockSubScreen(Context context,
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("SecuritySettings", "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;
}
}
public static class UnificationConfirmationDialog extends InstrumentedDialogFragment {
private static final String EXTRA_COMPLIANT = "compliant";

View File

@@ -0,0 +1,252 @@
/*
* 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.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;
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);
mTrustAgentManager =
FeatureFactory.getFactory(
getActivity()).getSecurityFeatureProvider().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);
final CharSequence trustAgentLabel = mTrustAgentManager.getActiveTrustAgentLabel(
getContext(), mLockPatternUtils);
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;
}
}
final CharSequence trustAgentLabel = mTrustAgentManager
.getActiveTrustAgentLabel(getContext(), mLockPatternUtils);
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;
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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 android.content.Context;
import android.os.UserManager;
public class UserCredentialsPreferenceController extends
RestrictedEncryptionPreferenceController {
private static final String KEY_USER_CREDENTIALS = "user_credentials";
public UserCredentialsPreferenceController(Context context) {
super(context, UserManager.DISALLOW_CONFIG_CREDENTIALS);
}
@Override
public String getPreferenceKey() {
return KEY_USER_CREDENTIALS;
}
}

View File

@@ -0,0 +1,204 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.security.trustagent;
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;
public String summary;
public RestrictedLockUtils.EnforcedAdmin admin = null;
}
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 =
android.Manifest.permission.PROVIDE_TRUST_AGENT;
/**
* Determines if the service associated with a resolved trust agent intent is allowed to provide
* trust on this device.
*
* @param resolveInfo The entry corresponding to the matched trust agent intent.
* @param pm The package manager to be used to check for permissions.
* @return {@code true} if the associated service is allowed to provide a trust agent, and
* {@code false} if otherwise.
*/
public boolean shouldProvideTrust(ResolveInfo resolveInfo, PackageManager pm) {
final String packageName = resolveInfo.serviceInfo.packageName;
if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
!= PackageManager.PERMISSION_GRANTED) {
Log.w(TAG, "Skipping agent because package " + packageName
+ " does not have permission " + PERMISSION_PROVIDE_AGENT + ".");
return false;
}
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);
}
private TrustAgentComponentInfo getSettingsComponent(PackageManager pm,
ResolveInfo resolveInfo) {
if (resolveInfo == null || resolveInfo.serviceInfo == null
|| resolveInfo.serviceInfo.metaData == null) {
return null;
}
String cn = null;
TrustAgentComponentInfo trustAgentComponentInfo = new TrustAgentComponentInfo();
XmlResourceParser parser = null;
Exception caughtException = null;
try {
parser = resolveInfo.serviceInfo.loadXmlMetaData(pm, TRUST_AGENT_META_DATA);
if (parser == null) {
Slog.w(TAG, "Can't find " + TRUST_AGENT_META_DATA + " meta-data");
return null;
}
Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
}
String nodeName = parser.getName();
if (!"trust-agent".equals(nodeName)) {
Slog.w(TAG, "Meta-data does not start with trust-agent tag");
return null;
}
TypedArray sa =
res.obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
trustAgentComponentInfo.summary =
sa.getString(com.android.internal.R.styleable.TrustAgent_summary);
trustAgentComponentInfo.title =
sa.getString(com.android.internal.R.styleable.TrustAgent_title);
cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
sa.recycle();
} catch (PackageManager.NameNotFoundException e) {
caughtException = e;
} catch (IOException e) {
caughtException = e;
} catch (XmlPullParserException e) {
caughtException = e;
} finally {
if (parser != null) parser.close();
}
if (caughtException != null) {
Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
return null;
}
if (cn != null && cn.indexOf('/') < 0) {
cn = resolveInfo.serviceInfo.packageName + "/" + cn;
}
trustAgentComponentInfo.componentName =
(cn == null) ? null : ComponentName.unflattenFromString(cn);
return trustAgentComponentInfo;
}
}

View File

@@ -14,7 +14,9 @@
* limitations under the License.
*/
package com.android.settings;
package com.android.settings.security.trustagent;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
@@ -34,15 +36,14 @@ import android.util.ArraySet;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.trustagent.TrustAgentManager;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import java.util.List;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
public class TrustAgentSettings extends SettingsPreferenceFragment implements
Preference.OnPreferenceChangeListener {
private static final String SERVICE_INTERFACE = TrustAgentService.SERVICE_INTERFACE;
@@ -97,7 +98,7 @@ public class TrustAgentSettings extends SettingsPreferenceFragment implements
super.onResume();
removePreference("dummy_preference");
updateAgents();
};
}
private void updateAgents() {
final Context context = getActivity();
@@ -152,7 +153,7 @@ public class TrustAgentSettings extends SettingsPreferenceFragment implements
UserHandle.myUserId());
}
ArrayMap<ComponentName, AgentInfo> findAvailableTrustAgents() {
private ArrayMap<ComponentName, AgentInfo> findAvailableTrustAgents() {
PackageManager pm = getActivity().getPackageManager();
Intent trustAgentIntent = new Intent(SERVICE_INTERFACE);
List<ResolveInfo> resolveInfos = pm.queryIntentServices(trustAgentIntent,
@@ -169,7 +170,7 @@ public class TrustAgentSettings extends SettingsPreferenceFragment implements
if (!mTrustAgentManager.shouldProvideTrust(resolveInfo, pm)) {
continue;
}
ComponentName name = TrustAgentUtils.getComponentName(resolveInfo);
ComponentName name = mTrustAgentManager.getComponentName(resolveInfo);
AgentInfo agentInfo = new AgentInfo();
agentInfo.label = resolveInfo.loadLabel(pm);
agentInfo.icon = resolveInfo.loadIcon(pm);

View File

@@ -1,38 +0,0 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.trustagent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
/** A manager for trust agent state. */
public interface TrustAgentManager {
String PERMISSION_PROVIDE_AGENT = android.Manifest.permission.PROVIDE_TRUST_AGENT;
/**
* Determines if the service associated with a resolved trust agent intent is allowed to provide
* trust on this device.
*
* @param resolveInfo The entry corresponding to the matched trust agent intent.
* @param pm The package manager to be used to check for permissions.
* @return {@code true} if the associated service is allowed to provide a trust agent, and
* {@code false} if otherwise.
*/
boolean shouldProvideTrust(ResolveInfo resolveInfo, PackageManager pm);
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.trustagent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.util.Log;
/** Implementation for {@code SecurityFeatureProvider}. */
public class TrustAgentManagerImpl implements TrustAgentManager {
private static final String TAG = "TrustAgentFeature";
@Override
public boolean shouldProvideTrust(ResolveInfo resolveInfo, PackageManager pm) {
final String packageName = resolveInfo.serviceInfo.packageName;
if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
!= PackageManager.PERMISSION_GRANTED) {
Log.w(TAG, "Skipping agent because package " + packageName
+ " does not have permission " + PERMISSION_PROVIDE_AGENT + ".");
return false;
}
return true;
}
}

View File

@@ -23,13 +23,18 @@ import com.android.settingslib.core.AbstractPreferenceController;
import java.util.List;
public class WorkOnlyCategoryPreferenceController extends AbstractPreferenceController
/**
* A controller for generic Preference categories. If all controllers for its children reports
* not-available, this controller will also report not-available, and subsequently will be hidden by
* UI.
*/
public class PreferenceCategoryController extends AbstractPreferenceController
implements PreferenceControllerMixin {
private final String mKey;
private final List<AbstractPreferenceController> mChildren;
public WorkOnlyCategoryPreferenceController(Context context,
public PreferenceCategoryController(Context context,
String key, List<AbstractPreferenceController> childrenControllers) {
super(context);
mKey = key;

View File

@@ -22,7 +22,9 @@ import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.ActionListener;
import android.os.Bundle;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import com.android.settings.SetupWizardUtils;
@@ -40,6 +42,15 @@ public class WifiDialogActivity extends Activity implements WifiDialog.WifiDialo
private static final String KEY_ACCESS_POINT_STATE = "access_point_state";
private static final String KEY_WIFI_CONFIGURATION = "wifi_configuration";
/**
* Boolean extra indicating whether this activity should connect to an access point on the
* caller's behalf. If this is set to false, the caller should check
* {@link #KEY_WIFI_CONFIGURATION} in the result data and save that using
* {@link WifiManager#connect(WifiConfiguration, ActionListener)}. Default is true.
*/
@VisibleForTesting
static final String KEY_CONNECT_FOR_CALLER = "connect_for_caller";
@Override
protected void onCreate(Bundle savedInstanceState) {
final Intent intent = getIntent();
@@ -55,7 +66,8 @@ public class WifiDialogActivity extends Activity implements WifiDialog.WifiDialo
accessPoint = new AccessPoint(this, accessPointState);
}
WifiDialog dialog = WifiDialog.createModal(this, this, accessPoint, WifiConfigUiBase.MODE_CONNECT);
WifiDialog dialog = WifiDialog.createModal(
this, this, accessPoint, WifiConfigUiBase.MODE_CONNECT);
dialog.show();
dialog.setOnDismissListener(this);
}
@@ -102,17 +114,19 @@ public class WifiDialogActivity extends Activity implements WifiDialog.WifiDialo
final AccessPoint accessPoint = dialog.getController().getAccessPoint();
final WifiManager wifiManager = getSystemService(WifiManager.class);
if (config == null) {
if (accessPoint != null && accessPoint.isSaved()) {
wifiManager.connect(accessPoint.getConfig(), null /* listener */);
}
} else {
wifiManager.save(config, null /* listener */);
if (accessPoint != null) {
// accessPoint is null for "Add network"
NetworkInfo networkInfo = accessPoint.getNetworkInfo();
if (networkInfo == null || !networkInfo.isConnected()) {
wifiManager.connect(config, null /* listener */);
if (getIntent().getBooleanExtra(KEY_CONNECT_FOR_CALLER, true)) {
if (config == null) {
if (accessPoint != null && accessPoint.isSaved()) {
wifiManager.connect(accessPoint.getConfig(), null /* listener */);
}
} else {
wifiManager.save(config, null /* listener */);
if (accessPoint != null) {
// accessPoint is null for "Add network"
NetworkInfo networkInfo = accessPoint.getNetworkInfo();
if (networkInfo == null || !networkInfo.isConnected()) {
wifiManager.connect(config, null /* listener */);
}
}
}
}

View File

@@ -71,13 +71,13 @@ com.android.settings.applications.ExternalSourcesDetails
com.android.settings.applications.PictureInPictureSettings
com.android.settings.applications.PictureInPictureDetails
com.android.settings.ApnSettings
com.android.settings.SecuritySettings$SecuritySubSettings
com.android.settings.security.SecuritySubSettings
com.android.settings.PrivacySettings
com.android.settings.WifiCallingSettings
com.android.settings.WifiCallingSettingsForSub
com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment
com.android.settings.SetupRedactionInterstitial$SetupRedactionInterstitialFragment
com.android.settings.TrustAgentSettings
com.android.settings.security.trustagent.TrustAgentSettings
com.android.settings.password.ChooseLockGeneric$ChooseLockGenericFragment
com.android.settings.IccLockSettings
com.android.settings.TetherSettings

View File

@@ -16,10 +16,18 @@
package com.android.settings;
import android.os.Build;
/**
* Constants for Robolectric config
*/
public class TestConfig {
/**
* @deprecated New tests should use {@link #SDK_VERSION_O}
*/
@Deprecated
public static final int SDK_VERSION = 23;
public static final int SDK_VERSION_O = Build.VERSION_CODES.O;
public static final String MANIFEST_PATH = "packages/apps/Settings/AndroidManifest.xml";
}

View File

@@ -0,0 +1,99 @@
/*
* 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.accessibility;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.os.Bundle;
import android.support.annotation.XmlRes;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.widget.SwitchBar;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
import org.robolectric.util.FragmentTestUtil;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
})
public class ToggleFeaturePreferenceFragmentTest {
private ToggleFeaturePreferenceFragmentTestable mFragment;
@Test
public void createFragment_shouldOnlyAddPreferencesOnce() {
mFragment = spy(new ToggleFeaturePreferenceFragmentTestable());
FragmentTestUtil.startFragment(mFragment);
// execute exactly once
verify(mFragment).addPreferencesFromResource(R.xml.placeholder_prefs);
}
public static class ToggleFeaturePreferenceFragmentTestable
extends ToggleFeaturePreferenceFragment {
@Override
protected void onPreferenceToggled(String preferenceKey, boolean enabled) {}
@Override
public int getMetricsCategory() {
return 0;
}
@Override
public int getPreferenceScreenResId() {
return R.xml.placeholder_prefs;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return mock(View.class);
}
@Override
public void addPreferencesFromResource(@XmlRes int preferencesResId) {
// do nothing
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// do nothing
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
mSwitchBar = mock(SwitchBar.class);
super.onActivityCreated(savedInstanceState);
}
}
}

View File

@@ -16,6 +16,10 @@
package com.android.settings.dashboard;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -23,6 +27,7 @@ import android.content.Intent;
import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
@@ -35,12 +40,6 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SummaryLoaderTest {
@@ -65,14 +64,14 @@ public class SummaryLoaderTest {
mCallbackInvoked = false;
final Activity activity = Robolectric.buildActivity(Activity.class).get();
final List<DashboardCategory> categories = new ArrayList<>();
mSummaryLoader = new SummaryLoader(activity, categories);
mSummaryLoader.setSummaryConsumer(new SummaryLoader.SummaryConsumer() {
@Override
public void notifySummaryChanged(Tile tile) {
mCallbackInvoked = true;
}
});
mSummaryLoader = new SummaryLoader(activity, CategoryKey.CATEGORY_HOMEPAGE);
mSummaryLoader.setSummaryConsumer(tile -> mCallbackInvoked = true);
}
@Test
public void newInstance_shouldNotLoadCategory() {
verifyZeroInteractions(mFeatureFactory.dashboardFeatureProvider);
}
@Test

View File

@@ -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();
}
}

View File

@@ -0,0 +1,143 @@
/*
* 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.imei;
import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
import static android.telephony.TelephonyManager.PHONE_TYPE_GSM;
import static org.mockito.ArgumentMatchers.anyInt;
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.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.TelephonyManager;
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;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AbstractImeiInfoPreferenceControllerTest {
@Mock
private Preference mPreference;
@Mock
private PreferenceScreen mScreen;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private UserManager mUserManager;
@Mock
private Fragment mFragment;
private Context mContext;
private AbstractImeiInfoPreferenceControllerImpl mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
mController = new AbstractImeiInfoPreferenceControllerImpl(mContext, mFragment);
ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
}
@Test
public void displayPreference_cdmaPhone_shouldSetCdmaTitleAndMeid() {
mController = spy(mController);
final String meid = "125132215123";
when(mTelephonyManager.getPhoneType()).thenReturn(PHONE_TYPE_CDMA);
doReturn(meid).when(mController).getMeid();
mController.displayPreference(mScreen);
verify(mPreference).setTitle(mController.getTitleForCdmaPhone());
verify(mPreference).setSummary(meid);
}
@Test
public void displayPreference_gsmPhone_shouldSetGsmTitleAndImei() {
final String imei = "125132215123";
when(mTelephonyManager.getPhoneType()).thenReturn(PHONE_TYPE_GSM);
when(mTelephonyManager.getImei(anyInt())).thenReturn(imei);
mController.displayPreference(mScreen);
verify(mPreference).setTitle(mController.getTitleForGsmPhone());
verify(mPreference).setSummary(imei);
}
@Test
public void handlePreferenceTreeClick_shouldStartDialogFragment() {
when(mFragment.getChildFragmentManager()).thenReturn(
mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS));
when(mPreference.getTitle()).thenReturn("SomeTitle");
mController.displayPreference(mScreen);
mController.handlePreferenceTreeClick(mPreference);
verify(mFragment).getChildFragmentManager();
}
public class AbstractImeiInfoPreferenceControllerImpl extends
AbstractImeiInfoPreferenceController {
public AbstractImeiInfoPreferenceControllerImpl(Context context, Fragment fragment) {
super(context, fragment);
}
@Override
public String getPreferenceKey() {
return "foobar";
}
@Override
protected String getTitleForCdmaPhone() {
return "foo";
}
@Override
protected String getTitleForGsmPhone() {
return "bar";
}
@Override
protected int getSimSlot() {
return 0;
}
}
}

View File

@@ -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.deviceinfo.imei;
import static com.android.settings.deviceinfo.imei.ImeiInfoDialogController.ID_CDMA_SETTINGS;
import static com.android.settings.deviceinfo.imei.ImeiInfoDialogController.ID_GSM_SETTINGS;
import static com.android.settings.deviceinfo.imei.ImeiInfoDialogController.ID_ICC_ID_LABEL;
import static com.android.settings.deviceinfo.imei.ImeiInfoDialogController.ID_ICC_ID_VALUE;
import static com.android.settings.deviceinfo.imei.ImeiInfoDialogController.ID_IMEI_SV_VALUE;
import static com.android.settings.deviceinfo.imei.ImeiInfoDialogController.ID_IMEI_VALUE;
import static com.android.settings.deviceinfo.imei.ImeiInfoDialogController.ID_MEID_NUMBER_VALUE;
import static com.android.settings.deviceinfo.imei.ImeiInfoDialogController.ID_MIN_NUMBER_VALUE;
import static com.android.settings.deviceinfo.imei.ImeiInfoDialogController.ID_PRL_VERSION_VALUE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
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;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ImeiInfoDialogControllerTest {
private static final String PRL_VERSION = "some_prl_version";
private static final String MEID_NUMBER = "12871234124";
private static final String IMEI_NUMBER = "2341982751254";
private static final String MIN_NUMBER = "123417851315";
private static final String ICCID_NUMBER = "3845672472";
private static final String IMEI_SV_NUMBER = "12";
@Mock
private ImeiInfoDialogFragment mDialog;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private SubscriptionInfo mSubscriptionInfo;
private Context mContext;
private ImeiInfoDialogController mController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
when(mDialog.getContext()).thenReturn(mContext);
mController = spy(new ImeiInfoDialogController(mDialog, 0 /* phone id */));
ReflectionHelpers.setField(mController, "mSubscriptionInfo", mSubscriptionInfo);
doReturn(PRL_VERSION).when(mController).getCdmaPrlVersion();
doReturn(MEID_NUMBER).when(mController).getMeid();
when(mTelephonyManager.getCdmaMin(anyInt())).thenReturn(MIN_NUMBER);
when(mSubscriptionInfo.getIccId()).thenReturn(ICCID_NUMBER);
when(mTelephonyManager.getDeviceSoftwareVersion(anyInt())).thenReturn(IMEI_SV_NUMBER);
when(mTelephonyManager.getImei(anyInt())).thenReturn(IMEI_NUMBER);
}
@Test
public void populateImeiInfo_cdmaLteEnabled_shouldSetMeidAndImeiAndMin() {
doReturn(true).when(mController).isCdmaLteEnabled();
when(mTelephonyManager.getPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA);
mController.populateImeiInfo();
verify(mDialog).setText(ID_MEID_NUMBER_VALUE, MEID_NUMBER);
verify(mDialog).setText(ID_MIN_NUMBER_VALUE, MIN_NUMBER);
verify(mDialog).setText(ID_PRL_VERSION_VALUE, PRL_VERSION);
verify(mDialog).setText(ID_ICC_ID_VALUE, ICCID_NUMBER);
verify(mDialog).setText(eq(ID_IMEI_VALUE), any());
verify(mDialog).setText(eq(ID_IMEI_SV_VALUE), any());
}
@Test
public void populateImeiInfo_cdmaLteDisabled_shouldSetMeidAndMinAndRemoveGsmSettings() {
doReturn(false).when(mController).isCdmaLteEnabled();
when(mTelephonyManager.getPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA);
mController.populateImeiInfo();
verify(mDialog).setText(ID_MEID_NUMBER_VALUE, MEID_NUMBER);
verify(mDialog).setText(ID_MIN_NUMBER_VALUE, MIN_NUMBER);
verify(mDialog).setText(ID_PRL_VERSION_VALUE, PRL_VERSION);
verify(mDialog).removeViewFromScreen(ID_GSM_SETTINGS);
verify(mDialog).removeViewFromScreen(ID_ICC_ID_VALUE);
verify(mDialog).removeViewFromScreen(ID_ICC_ID_LABEL);
}
@Test
public void populateImeinfo_gsm_shouldSetImeiAndRemoveCdmaSettings() {
when(mTelephonyManager.getPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_GSM);
mController.populateImeiInfo();
verify(mDialog).setText(eq(ID_IMEI_VALUE), any());
verify(mDialog).setText(eq(ID_IMEI_SV_VALUE), any());
verify(mDialog).removeViewFromScreen(ID_CDMA_SETTINGS);
verify(mDialog).removeViewFromScreen(ID_ICC_ID_VALUE);
verify(mDialog).removeViewFromScreen(ID_ICC_ID_LABEL);
}
}

View File

@@ -0,0 +1,89 @@
/*
* 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.imei;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.Fragment;
import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.TelephonyManager;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ImeiInfoDualSimPreferenceControllerTest {
@Mock
private Preference mPreference;
@Mock
private PreferenceScreen mScreen;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private UserManager mUserManager;
@Mock
private Fragment mFragment;
private Context mContext;
private ImeiInfoDualSimPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
mController = new ImeiInfoDualSimPreferenceController(mContext, mFragment);
ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
}
@Test
public void getTitleForCdmaPhone_shouldReturnCdmaMultiSimString() {
ReflectionHelpers.setField(mController, "mIsMultiSim", true);
assertThat(mController.getTitleForCdmaPhone()).isEqualTo(mContext.getResources().getString(
R.string.meid_multi_sim_sim_slot_2));
}
@Test
public void getTitleForGsmPhone_shouldReturnGsmMultiSimString() {
ReflectionHelpers.setField(mController, "mIsMultiSim", true);
assertThat(mController.getTitleForGsmPhone()).isEqualTo(mContext.getResources().getString(
R.string.imei_multi_sim_slot_2));
}
}

View File

@@ -0,0 +1,105 @@
/*
* 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.imei;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.Fragment;
import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.TelephonyManager;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ImeiInfoPreferenceControllerV2Test {
@Mock
private Preference mPreference;
@Mock
private PreferenceScreen mScreen;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private UserManager mUserManager;
@Mock
private Fragment mFragment;
private Context mContext;
private ImeiInfoPreferenceControllerV2 mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
mController = new ImeiInfoPreferenceControllerV2(mContext, mFragment);
ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
}
@Test
public void getTitleForCdmaPhone_noMultiSim_shouldReturnCdmaNoMultiSimString() {
ReflectionHelpers.setField(mController, "mIsMultiSim", false);
assertThat(mController.getTitleForCdmaPhone()).isEqualTo(mContext.getResources().getString(
R.string.status_meid_number));
}
@Test
public void getTitleForCdmaPhone_multiSim_shouldReturnCdmaMultiSimString() {
ReflectionHelpers.setField(mController, "mIsMultiSim", true);
assertThat(mController.getTitleForCdmaPhone()).isEqualTo(mContext.getResources().getString(
R.string.meid_multi_sim_sim_slot_1));
}
@Test
public void getTitleForGsmPhone_noMultiSim_shouldReturnGsmNoMultiSimString() {
ReflectionHelpers.setField(mController, "mIsMultiSim", false);
assertThat(mController.getTitleForGsmPhone()).isEqualTo(mContext.getResources().getString(
R.string.status_imei));
}
@Test
public void getTitleForGsmPhone_multiSim_shouldReturnGsmMultiSimString() {
ReflectionHelpers.setField(mController, "mIsMultiSim", true);
assertThat(mController.getTitleForGsmPhone()).isEqualTo(mContext.getResources().getString(
R.string.imei_multi_sim_slot_1));
}
}

View File

@@ -0,0 +1,113 @@
/*
* 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.simstatus;
import static org.mockito.ArgumentMatchers.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.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.os.UserManager;
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 AbstractSimStatusPreferenceControllerTest {
@Mock
private Preference mPreference;
@Mock
private PreferenceScreen mScreen;
@Mock
private UserManager mUserManager;
@Mock
private Fragment mFragment;
private Context mContext;
private AbstractSimStatusPreferenceControllerImpl mController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
mController = new AbstractSimStatusPreferenceControllerImpl(mContext, mFragment);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
}
@Test
public void displayPreference_shouldSetTitleAndSummary() {
mController.displayPreference(mScreen);
verify(mPreference).setTitle(mController.getPreferenceTitle());
verify(mPreference).setSummary(anyString());
}
@Test
public void handlePreferenceTreeClick_shouldStartDialogFragment() {
when(mFragment.getChildFragmentManager()).thenReturn(
mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS));
when(mPreference.getTitle()).thenReturn("foo");
mController.displayPreference(mScreen);
mController.handlePreferenceTreeClick(mPreference);
verify(mFragment).getChildFragmentManager();
}
public class AbstractSimStatusPreferenceControllerImpl extends
AbstractSimStatusPreferenceController {
public AbstractSimStatusPreferenceControllerImpl(Context context, Fragment fragment) {
super(context, fragment);
}
@Override
public String getPreferenceKey() {
return "foo";
}
@Override
protected String getPreferenceTitle() {
return "bar";
}
@Override
protected int getSimSlot() {
return 0;
}
}
}

View File

@@ -0,0 +1,202 @@
/*
* 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.simstatus;
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
.CELLULAR_NETWORK_TYPE_VALUE_ID;
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
.NETWORK_PROVIDER_VALUE_ID;
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
.OPERATOR_INFO_LABEL_ID;
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
.OPERATOR_INFO_VALUE_ID;
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
.PHONE_NUMBER_VALUE_ID;
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
.ROAMING_INFO_VALUE_ID;
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
.SERVICE_STATE_VALUE_ID;
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
.SIGNAL_STRENGTH_VALUE_ID;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SimStatusDialogControllerTest {
@Mock
private SimStatusDialogFragment mDialog;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private SubscriptionInfo mSubscriptionInfo;
@Mock
private ServiceState mServiceState;
@Mock
private PhoneStateListener mPhoneStateListener;
@Mock
private SignalStrength mSignalStrength;
private SimStatusDialogController mController;
private Context mContext;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
when(mDialog.getContext()).thenReturn(mContext);
mController = spy(
new SimStatusDialogController(mDialog, new Lifecycle(), 0 /* phone id */));
doReturn(mServiceState).when(mController).getCurrentServiceState();
doReturn(0).when(mController).getDbm(any());
doReturn(0).when(mController).getAsuLevel(any());
doReturn(mPhoneStateListener).when(mController).getPhoneStateListener();
doReturn("").when(mController).getPhoneNumber();
doReturn(mSignalStrength).when(mController).getSignalStrength();
ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
ReflectionHelpers.setField(mController, "mSubscriptionInfo", mSubscriptionInfo);
}
@Test
public void initialize_updateNetworkProviderWithFoobarCarrier_shouldUpdateCarrierWithFoobar() {
final String carrierName = "foobar";
when(mServiceState.getOperatorAlphaLong()).thenReturn(carrierName);
mController.initialize();
verify(mDialog).setText(NETWORK_PROVIDER_VALUE_ID, carrierName);
}
@Test
public void initialize_updatePhoneNumberWith1111111111_shouldUpdatePhoneNumber() {
final String phoneNumber = "1111111111";
doReturn(phoneNumber).when(mController).getPhoneNumber();
mController.initialize();
verify(mDialog).setText(PHONE_NUMBER_VALUE_ID, phoneNumber);
}
@Test
public void initialize_updateLatestAreaInfoWithCdmaPhone_shouldRemoveOperatorInfoSetting() {
when(mTelephonyManager.getPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA);
mController.initialize();
verify(mDialog).removeSettingFromScreen(OPERATOR_INFO_LABEL_ID);
verify(mDialog).removeSettingFromScreen(OPERATOR_INFO_VALUE_ID);
}
@Test
public void initialize_updateServiceStateWithInService_shouldUpdateTextToBeCInService() {
when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
mController.initialize();
final String inServiceText = mContext.getResources().getString(
R.string.radioInfo_service_in);
verify(mDialog).setText(SERVICE_STATE_VALUE_ID, inServiceText);
}
@Test
public void initialize_updateDataStateWithPowerOff_shouldUpdateSettingAndResetSignalStrength() {
when(mServiceState.getState()).thenReturn(ServiceState.STATE_POWER_OFF);
mController.initialize();
final String offServiceText = mContext.getResources().getString(
R.string.radioInfo_service_off);
verify(mDialog).setText(SERVICE_STATE_VALUE_ID, offServiceText);
verify(mDialog).setText(SIGNAL_STRENGTH_VALUE_ID, "0");
}
@Test
public void initialize_updateSignalStrengthWith50_shouldUpdateSignalStrengthTo50() {
final int signalDbm = 50;
final int signalAsu = 50;
doReturn(signalDbm).when(mController).getDbm(mSignalStrength);
doReturn(signalAsu).when(mController).getAsuLevel(mSignalStrength);
mController.initialize();
final String signalStrengthString = mContext.getResources().getString(
R.string.sim_signal_strength, signalDbm, signalAsu);
verify(mDialog).setText(SIGNAL_STRENGTH_VALUE_ID, signalStrengthString);
}
@Test
public void initialize_updateNetworkTypeWithEdge_shouldUpdateSettingToEdge() {
when(mTelephonyManager.getDataNetworkType(anyInt())).thenReturn(
TelephonyManager.NETWORK_TYPE_EDGE);
mController.initialize();
verify(mDialog).setText(CELLULAR_NETWORK_TYPE_VALUE_ID,
TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_EDGE));
}
@Test
public void initialize_updateRoamingStatusIsRoaming_shouldSetSettingToRoaming() {
when(mServiceState.getRoaming()).thenReturn(true);
mController.initialize();
final String roamingOnString = mContext.getResources().getString(
R.string.radioInfo_roaming_in);
verify(mDialog).setText(ROAMING_INFO_VALUE_ID, roamingOnString);
}
@Test
public void initialize_updateRoamingStatusNotRoaming_shouldSetSettingToRoamingOff() {
when(mServiceState.getRoaming()).thenReturn(false);
mController.initialize();
final String roamingOffString = mContext.getResources().getString(
R.string.radioInfo_roaming_not);
verify(mDialog).setText(ROAMING_INFO_VALUE_ID, roamingOffString);
}
}

View File

@@ -0,0 +1,93 @@
/*
* 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.simstatus;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.Fragment;
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.TelephonyManager;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.google.common.truth.Truth;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SimStatusDualSimPreferenceControllerTest {
@Mock
private Preference mPreference;
@Mock
private PreferenceScreen mScreen;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private UserManager mUserManager;
@Mock
private ConnectivityManager mConnectivityManager;
@Mock
private Fragment mFragment;
private Context mContext;
private SimStatusDualSimPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
doReturn(mConnectivityManager).when(mContext).getSystemService(ConnectivityManager.class);
when(mUserManager.isAdminUser()).thenReturn(true);
when(mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(
true);
mController = new SimStatusDualSimPreferenceController(mContext, mFragment);
ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
}
@Test
public void isAvailable_multiSim_shouldBeTrue() {
ReflectionHelpers.setField(mController, "mIsMultiSim", true);
Truth.assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_notMultiSim_shouldBeFalse() {
ReflectionHelpers.setField(mController, "mIsMultiSim", false);
Truth.assertThat(mController.isAvailable()).isFalse();
}
}

View File

@@ -0,0 +1,89 @@
/*
* 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.simstatus;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.Fragment;
import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.TelephonyManager;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SimStatusPreferenceControllerV2Test {
@Mock
private Preference mPreference;
@Mock
private PreferenceScreen mScreen;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private UserManager mUserManager;
@Mock
private Fragment mFragment;
private Context mContext;
private SimStatusPreferenceControllerV2 mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
mController = new SimStatusPreferenceControllerV2(mContext, mFragment);
ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
}
@Test
public void getPreferenceTitle_noMultiSim_shouldReturnSingleSimString() {
ReflectionHelpers.setField(mController, "mIsMultiSim", false);
assertThat(mController.getPreferenceTitle()).isEqualTo(mContext.getResources().getString(
R.string.sim_status_title));
}
@Test
public void getPreferenceTitle_multiSim_shouldReturnMultiSimString() {
ReflectionHelpers.setField(mController, "mIsMultiSim", true);
assertThat(mController.getPreferenceTitle()).isEqualTo(mContext.getResources().getString(
R.string.sim_status_title_sim_slot_1));
}
}

View File

@@ -0,0 +1,72 @@
/*
* 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 com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.support.v7.preference.Preference;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowKeyStore;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
shadows = {
ShadowKeyStore.class
})
public class CredentialStoragePreferenceControllerTest {
private Context mContext;
private CredentialStoragePreferenceController mController;
private Preference mPreference;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new CredentialStoragePreferenceController(mContext);
mPreference = new Preference(mContext);
}
@Test
public void updateState_hardwareBacked_showHardwareSummary() {
ShadowKeyStore.setHardwareBacked(true);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getText(R.string.credential_storage_type_hardware));
}
@Test
public void updateState_hardwareBacked_showSoftwareSummary() {
ShadowKeyStore.setHardwareBacked(false);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getText(R.string.credential_storage_type_software));
}
}

View File

@@ -16,8 +16,6 @@
package com.android.settings.security;
import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
import static com.android.settings.security.EncryptionAndCredential.SEARCH_INDEX_DATA_PROVIDER;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
@@ -28,7 +26,6 @@ import android.os.UserManager;
import android.provider.SearchIndexableResource;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -71,16 +68,6 @@ public class EncryptionAndCredentialTest {
assertThat(fragment.getMetricsCategory()).isEqualTo(MetricsEvent.ENCRYPTION_AND_CREDENTIAL);
}
// Search provider tests
@Test
public void getXmlResourcesToIndex_shouldReturnAllXmls() {
final List<SearchIndexableResource> index =
SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(
mContext, true /* enabled */);
assertThat(index).hasSize(3);
}
@Test
public void getNonIndexableKeys_pageIsDisabled_shouldReturnAllKeysAsNonIndexable() {
when(mUserManager.isAdminUser()).thenReturn(false);
@@ -96,32 +83,4 @@ public class EncryptionAndCredentialTest {
assertThat(keys).containsExactlyElementsIn(expectedKeys);
}
@Test
public void getNonIndexableKeys_deviceEncrypted_shouldReturnUnencryptedKeys() {
when(mUserManager.isAdminUser()).thenReturn(true);
when(mDevicePolicyManager.getStorageEncryptionStatus()).thenReturn(
ENCRYPTION_STATUS_ACTIVE);
final List<String> expectedKeys = new ArrayList<>();
expectedKeys.addAll(((BaseSearchIndexProvider) SEARCH_INDEX_DATA_PROVIDER)
.getNonIndexableKeysFromXml(mContext, R.xml.security_settings_unencrypted));
final List<String> keys = SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
assertThat(keys).containsExactlyElementsIn(expectedKeys);
}
@Test
public void getNonIndexableKeys_deviceNotEncrypted_shouldReturnEncryptedKeys() {
when(mUserManager.isAdminUser()).thenReturn(true);
when(mDevicePolicyManager.getStorageEncryptionStatus())
.thenReturn(ENCRYPTION_STATUS_INACTIVE);
final List<String> expectedKeys = new ArrayList<>();
expectedKeys.addAll(((BaseSearchIndexProvider) SEARCH_INDEX_DATA_PROVIDER)
.getNonIndexableKeysFromXml(mContext, R.xml.security_settings_encrypted));
final List<String> keys = SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
assertThat(keys).containsExactlyElementsIn(expectedKeys);
}
}

View File

@@ -0,0 +1,90 @@
/*
* 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 com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.support.v7.preference.Preference;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowUserManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
shadows = {
ShadowUserManager.class,
ShadowLockPatternUtils.class
})
public class EncryptionStatusPreferenceControllerTest {
private Context mContext;
private EncryptionStatusPreferenceController mController;
private Preference mPreference;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new EncryptionStatusPreferenceController(mContext);
mPreference = new Preference(mContext);
}
@Test
public void isAvailable_admin_true() {
ShadowUserManager.getShadow().setIsAdminUser(true);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_notAdmin_false() {
ShadowUserManager.getShadow().setIsAdminUser(false);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void updateSummary_encrypted_shouldSayEncrypted() {
ShadowLockPatternUtils.setDeviceEncryptionEnabled(true);
mController.updateState(mPreference);
assertThat(mPreference.getFragment()).isNull();
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getText(R.string.crypt_keeper_encrypted_summary));
}
@Test
public void updateSummary_unencrypted_shouldHasEncryptionFragment() {
ShadowLockPatternUtils.setDeviceEncryptionEnabled(false);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getText(R.string.summary_placeholder));
assertThat(mPreference.getFragment()).isEqualTo(CryptKeeperSettings.class.getName());
}
}

View File

@@ -0,0 +1,86 @@
/*
* 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 com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.UserManager;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
shadows = {
ShadowUserManager.class
})
public class RestrictedEncryptionPreferenceControllerTest {
private Context mContext;
private ShadowUserManager mUserManager;
private CredentialStoragePreferenceController mCredentialStoragePreferenceController;
private InstallCredentialsPreferenceController mInstallCredentialsPreferenceController;
private ResetCredentialsPreferenceController mResetCredentialsPreferenceController;
private UserCredentialsPreferenceController mUserCredentialsPreferenceController;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mCredentialStoragePreferenceController =
new CredentialStoragePreferenceController(mContext);
mInstallCredentialsPreferenceController =
new InstallCredentialsPreferenceController(mContext);
mResetCredentialsPreferenceController =
new ResetCredentialsPreferenceController(mContext, new Lifecycle());
mUserCredentialsPreferenceController =
new UserCredentialsPreferenceController(mContext);
mUserManager = ShadowUserManager.getShadow();
}
@After
public void tearDown() {
mUserManager.reset();
}
@Test
public void isAvailable_noRestriction_shouldReturnTrue() {
assertThat(mCredentialStoragePreferenceController.isAvailable()).isTrue();
assertThat(mInstallCredentialsPreferenceController.isAvailable()).isTrue();
assertThat(mResetCredentialsPreferenceController.isAvailable()).isTrue();
assertThat(mUserCredentialsPreferenceController.isAvailable()).isTrue();
}
@Test
public void isAvailable_hasRestriction_shouldReturnFalse() {
mUserManager.addBaseUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS);
assertThat(mCredentialStoragePreferenceController.isAvailable()).isFalse();
assertThat(mInstallCredentialsPreferenceController.isAvailable()).isFalse();
assertThat(mResetCredentialsPreferenceController.isAvailable()).isFalse();
assertThat(mUserCredentialsPreferenceController.isAvailable()).isFalse();
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings;
package com.android.settings.security;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyInt;
@@ -35,6 +35,8 @@ import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -56,11 +58,10 @@ import org.robolectric.util.ReflectionHelpers;
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(
manifest = TestConfig.MANIFEST_PATH,
sdk = TestConfig.SDK_VERSION,
shadows = {ShadowLockPatternUtils.class}
)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
shadows = {
ShadowLockPatternUtils.class
})
public class SecuritySettingsTest {
@@ -104,7 +105,7 @@ public class SecuritySettingsTest {
public void testSummaryProvider_noFpFeature_shouldSetSummaryWithNoFingerprint() {
final FingerprintManager fpm = mock(FingerprintManager.class);
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(false);
.thenReturn(false);
mSummaryProvider.setListening(true);
@@ -115,7 +116,7 @@ public class SecuritySettingsTest {
public void testSummaryProvider_noFpHardware_shouldSetSummaryWithNoFingerprint() {
final FingerprintManager fpm = mock(FingerprintManager.class);
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(true);
.thenReturn(true);
// Cast to Object to workaround a robolectric casting bug
when((Object) mContext.getSystemService(FingerprintManager.class)).thenReturn(fpm);
@@ -147,7 +148,7 @@ public class SecuritySettingsTest {
securitySettings.initTrustAgentPreference(screen, 2);
verify(preference).setSummary(context.getResources().getQuantityString(
R.plurals.manage_trust_agents_summary_on, 2, 2));
R.plurals.manage_trust_agents_summary_on, 2, 2));
}
@Test
@@ -155,13 +156,13 @@ public class SecuritySettingsTest {
final Preference preference = mock(Preference.class);
final PreferenceGroup group = mock(PreferenceGroup.class);
when(group.findPreference(SecuritySettings.KEY_LOCKSCREEN_PREFERENCES))
.thenReturn(preference);
.thenReturn(preference);
final LockScreenNotificationPreferenceController controller =
mock(LockScreenNotificationPreferenceController.class);
mock(LockScreenNotificationPreferenceController.class);
final SecuritySettings securitySettings = new SecuritySettings();
ReflectionHelpers.setField(securitySettings,
"mLockScreenNotificationPreferenceController", controller);
"mLockScreenNotificationPreferenceController", controller);
when(controller.getSummaryResource()).thenReturn(1234);
securitySettings.setLockscreenPreferencesSummary(group);

View File

@@ -14,14 +14,17 @@
* limitations under the License.
*/
package com.android.settings.trustagent;
package com.android.settings.security.trustagent;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.PackageManager;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
@@ -30,51 +33,48 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class TrustAgentFeatureProviderImplTest {
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class TrustAgentManagerTest {
private static final String CANNED_PACKAGE_NAME = "com.test.package";
@Mock
private PackageManager mPackageManager;
private TrustAgentManagerImpl mImpl;
private TrustAgentManager mTrustAgentManager;
@Before
public void setUp() throws PackageManager.NameNotFoundException {
MockitoAnnotations.initMocks(this);
mImpl = new TrustAgentManagerImpl();
mTrustAgentManager = new TrustAgentManager();
}
@Test
public void shouldProvideTrust_doesProvideTrustWithPermission() {
when(mPackageManager.checkPermission(TrustAgentManager.PERMISSION_PROVIDE_AGENT,
CANNED_PACKAGE_NAME)).thenReturn(PackageManager.PERMISSION_GRANTED);
CANNED_PACKAGE_NAME)).thenReturn(PackageManager.PERMISSION_GRANTED);
ServiceInfo serviceInfo = new ServiceInfo();
serviceInfo.packageName = CANNED_PACKAGE_NAME;
ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.serviceInfo = serviceInfo;
assertTrue(mImpl.shouldProvideTrust(resolveInfo, mPackageManager));
assertThat(mTrustAgentManager.shouldProvideTrust(resolveInfo, mPackageManager))
.isTrue();
}
@Test
public void shouldProvideTrust_doesNotProvideTrustWithoutPermission() {
when(mPackageManager.checkPermission(TrustAgentManager.PERMISSION_PROVIDE_AGENT,
CANNED_PACKAGE_NAME)).thenReturn(PackageManager.PERMISSION_DENIED);
CANNED_PACKAGE_NAME)).thenReturn(PackageManager.PERMISSION_DENIED);
ServiceInfo serviceInfo = new ServiceInfo();
serviceInfo.packageName = CANNED_PACKAGE_NAME;
ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.serviceInfo = serviceInfo;
assertFalse(mImpl.shouldProvideTrust(resolveInfo, mPackageManager));
assertThat(mTrustAgentManager.shouldProvideTrust(resolveInfo, mPackageManager))
.isFalse();
}
}

View File

@@ -0,0 +1,43 @@
/*
* 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.security.KeyStore;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
@Implements(KeyStore.class)
public class ShadowKeyStore {
private static boolean sIsHardwareBacked;
@Resetter
public void reset() {
sIsHardwareBacked = false;
}
@Implementation
public boolean isHardwareBacked() {
return sIsHardwareBacked;
}
public static void setHardwareBacked(boolean hardwareBacked) {
sIsHardwareBacked = hardwareBacked;
}
}

View File

@@ -27,6 +27,8 @@ import org.robolectric.annotation.Implements;
public class ShadowLockPatternUtils {
private int mPasswordQuality = 1;
private static boolean sDeviceEncryptionEnabled;
@Implementation
public boolean isSecure(int id) {
return true;
@@ -42,6 +44,15 @@ public class ShadowLockPatternUtils {
return mPasswordQuality;
}
@Implementation
public static boolean isDeviceEncryptionEnabled() {
return sDeviceEncryptionEnabled;
}
public static void setDeviceEncryptionEnabled(boolean deviceEncryptionEnabled) {
sDeviceEncryptionEnabled = deviceEncryptionEnabled;
}
// Non-Android accessor.
public int getPasswordQuality() {
return mPasswordQuality;

View File

@@ -19,30 +19,36 @@ package com.android.settings.testutils.shadow;
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.SparseArray;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
import org.robolectric.shadow.api.Shadow;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* This class provides the API 24 implementation of UserManager.get(Context).
*/
@Implements(UserManager.class)
public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager {
private SparseArray<UserInfo> mUserInfos = new SparseArray<>();
private boolean mAdminUser;
private List<String> mRestrictions = new ArrayList<>();
public void setIsAdminUser(boolean isAdminUser) {
mAdminUser = isAdminUser;
}
@Resetter
public void reset() {
mRestrictions.clear();
}
@Implementation
public boolean isAdminUser() {
return mAdminUser;
@@ -72,6 +78,15 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
return (UserManager) context.getSystemService(Context.USER_SERVICE);
}
@Implementation
public boolean hasBaseUserRestriction(String restrictionKey, UserHandle userHandle) {
return mRestrictions.contains(restrictionKey);
}
public void addBaseUserRestriction(String restriction) {
mRestrictions.add(restriction);
}
public static ShadowUserManager getShadow() {
return (ShadowUserManager) Shadow.extract(
RuntimeEnvironment.application.getSystemService(UserManager.class));

View File

@@ -0,0 +1,49 @@
/*
* 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 static org.robolectric.RuntimeEnvironment.application;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;
@Implements(WifiManager.class)
public class ShadowWifiManager extends org.robolectric.shadows.ShadowWifiManager {
public WifiConfiguration savedWifiConfig;
@HiddenApi // @SystemApi
@Implementation
public void connect(WifiConfiguration config, WifiManager.ActionListener listener) {
savedWifiConfig = config;
}
@HiddenApi
@Implementation
public void save(WifiConfiguration config, WifiManager.ActionListener listener) {
savedWifiConfig = config;
}
public static ShadowWifiManager get() {
return Shadow.extract(application.getSystemService(WifiManager.class));
}
}

View File

@@ -37,17 +37,17 @@ import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class WorkOnlyCategoryPreferenceControllerTest {
public class PreferenceCategoryControllerTest {
private Context mContext;
private WorkOnlyCategoryPreferenceController mController;
private PreferenceCategoryController mController;
private List<AbstractPreferenceController> mChildren;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mChildren = new ArrayList<>();
mController = new WorkOnlyCategoryPreferenceController(mContext, "pref_key", mChildren);
mController = new PreferenceCategoryController(mContext, "pref_key", mChildren);
}
@Test

View File

@@ -0,0 +1,97 @@
/*
* 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.wifi;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import android.content.Intent;
import android.net.wifi.WifiConfiguration;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowConnectivityManager;
import com.android.settings.testutils.shadow.ShadowWifiManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowAlertDialog;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(
manifest = TestConfig.MANIFEST_PATH,
sdk = TestConfig.SDK_VERSION_O,
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
ShadowConnectivityManager.class,
ShadowWifiManager.class
}
)
public class WifiDialogActivityTest {
public static final String AP1_SSID = "\"ap1\"";
@Mock
private WifiConfigController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = AP1_SSID;
doReturn(wifiConfig).when(mController).getConfig();
}
@Test
public void onSubmit_shouldConnectToNetwork() {
WifiDialogActivity activity = Robolectric.setupActivity(WifiDialogActivity.class);
WifiDialog dialog = (WifiDialog) ShadowAlertDialog.getLatestAlertDialog();
assertThat(dialog).isNotNull();
ReflectionHelpers.setField(dialog, "mController", mController);
activity.onSubmit(dialog);
assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP1_SSID);
}
@Test
public void onSubmit_shouldNotConnectToNetwork_whenConnectForCallerIsFalse() {
WifiDialogActivity activity =
Robolectric.buildActivity(
WifiDialogActivity.class,
new Intent().putExtra(WifiDialogActivity.KEY_CONNECT_FOR_CALLER, false))
.setup().get();
WifiDialog dialog = (WifiDialog) ShadowAlertDialog.getLatestAlertDialog();
assertThat(dialog).isNotNull();
ReflectionHelpers.setField(dialog, "mController", mController);
activity.onSubmit(dialog);
assertThat(ShadowWifiManager.get().savedWifiConfig).isNull();
}
}