Snap for 4434599 from c8b6833e13 to pi-release
Change-Id: I6d6b2300d39faa7222da47cb654356b6cd749132
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
89
res/layout/dialog_firmware_version.xml
Normal file
89
res/layout/dialog_firmware_version.xml
Normal 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>
|
||||
114
res/layout/dialog_imei_info.xml
Normal file
114
res/layout/dialog_imei_info.xml
Normal 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>
|
||||
132
res/layout/dialog_sim_status.xml
Normal file
132
res/layout/dialog_sim_status.xml
Normal 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>
|
||||
@@ -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-->
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
252
src/com/android/settings/security/SecuritySubSettings.java
Normal file
252
src/com/android/settings/security/SecuritySubSettings.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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 */);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user