Merge changes Ibf5dc65b,I0cea3f76,I0dda78b4
* changes:
Phone number in about phone v2
Dynamic preferences for sim status
Dynamic preferences for IMEI
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 062ebdc..d65d92d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -83,6 +83,7 @@
<uses-permission android:name="android.permission.PEERS_MAC_ADDRESS"/>
<uses-permission android:name="android.permission.MANAGE_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.DELETE_PACKAGES"/>
+ <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.MANAGE_APP_OPS_RESTRICTIONS"/>
<uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS"/>
<uses-permission android:name="android.permission.READ_PRINT_SERVICES" />
@@ -223,6 +224,10 @@
android:theme="@android:style/Theme.NoDisplay"
android:excludeFromRecents="true"
android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.settings.SEARCH_RESULT_TRAMPOLINE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
</activity>
<!-- Top-level settings -->
diff --git a/res/drawable/ic_package_verifier_disabled.xml b/res/drawable/ic_package_verifier_disabled.xml
index 59e713a..fa148d1 100644
--- a/res/drawable/ic_package_verifier_disabled.xml
+++ b/res/drawable/ic_package_verifier_disabled.xml
@@ -14,14 +14,20 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
+ android:width="22dp"
+ android:height="22dp"
+ android:viewportWidth="22"
+ android:viewportHeight="22">
<path
- android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
- <path
- android:fillColor="#F09300"
- android:pathData="M13.45,11l2.12-2.12L14.16,7.5,12,9.62,9.91,7.5,8.5,8.91,10.62,11,8.5,13.16l1.41,1.41L12,12.45l2.12,2.12,1.41-1.41Zm8.1-7.11A16.54,16.54,0,0,1,22,7.77a16.65,16.65,0,0,1-.47,4,16.56,16.56,0,0,1-3.79,7.14A16.66,16.66,0,0,1,12,23,16.61,16.61,0,0,1,2.45,3.93,33.57,33.57,0,0,1,12,1a33.57,33.57,0,0,1,9.55,2.93Z" />
+ android:fillColor="#F5A623"
+ android:fillType="evenOdd"
+ android:pathData="M20.5515334,2.919 C15.9049774,0.613 11,0 11,0 C11,0 6.09502262,0.613
+1.44846657,2.919 C1.15485168,4.149 1,5.432 1,6.752 C1,8.109 1.16490699,9.429
+1.47561589,10.693 C2.13624937,13.382 3.45852187,15.813 5.26143791,17.807
+C6.84313725,19.559 8.79788839,20.973 11,21.926 C13.2021116,20.973
+15.1568627,19.559 16.7395676,17.807 C18.5414781,15.813 19.8637506,13.382
+20.5253896,10.693 C20.835093,9.429 21,8.109 21,6.752 C21,5.432 20.8461538,4.149
+20.5515334,2.919 M12,15.5 L10,15.5 L10,13.5 L12,13.5 L12,15.5 L12,15.5 Z M12,12
+L10,12 L10,6 L12,6 L12,12 L12,12 Z" />
</vector>
diff --git a/res/drawable/ic_package_verifier_enabled.xml b/res/drawable/ic_package_verifier_enabled.xml
index 9a2dee5..b954258 100644
--- a/res/drawable/ic_package_verifier_enabled.xml
+++ b/res/drawable/ic_package_verifier_enabled.xml
@@ -14,14 +14,22 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
+ android:width="22dp"
+ android:height="22dp"
+ android:viewportWidth="22"
+ android:viewportHeight="22">
<path
- android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
- <path
android:fillColor="#4285F4"
- android:pathData="M21.55,3.93A16.54,16.54,0,0,1,22,7.77a16.65,16.65,0,0,1-.47,4,16.56,16.56,0,0,1-3.79,7.14A16.66,16.66,0,0,1,12,23,16.61,16.61,0,0,1,2.45,3.93,33.57,33.57,0,0,1,12,1,33.57,33.57,0,0,1,21.55,3.93ZM15.27,8.41,9.61,14.07,11,15.49l5.66-5.66ZM9.61,11.24,8.2,12.66l1.41,1.41L11,12.66Z" />
+ android:fillType="evenOdd"
+ android:pathData="M20.5515334,2.92885159 C20.8461538,4.16300283 21,5.45033294 21,6.77478792
+C21,8.13636778 20.835093,9.46082277 20.5253896,10.7290888 C19.8637506,13.4271641
+18.5414781,15.8663687 16.7395676,17.8670984 C15.1568627,19.6250114
+13.2021116,21.0437836 11,22 C8.79788839,21.0437836 6.84313725,19.6250114
+5.26143791,17.8670984 C3.45852187,15.8663687 2.13624937,13.4271641
+1.47561589,10.7290888 C1.16490699,9.46082277 1,8.13636778 1,6.77478792
+C1,5.45033294 1.15485168,4.16300283 1.44846657,2.92885159
+C6.09502262,0.615068868 11,0 11,0 C11,0 15.9049774,0.615068868
+20.5515334,2.92885159 Z M15.6984615,6 L9.61538462,12.2961783 L7,10
+L5.69846154,11.3471338 L9.61538462,15 L17,7.3566879 L15.6984615,6 Z" />
</vector>
diff --git a/res/drawable/ic_package_verifier_removed.xml b/res/drawable/ic_package_verifier_removed.xml
new file mode 100644
index 0000000..e225ee5
--- /dev/null
+++ b/res/drawable/ic_package_verifier_removed.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="22dp"
+ android:height="22dp"
+ android:viewportWidth="22"
+ android:viewportHeight="22">
+
+ <group
+ android:translateX="-1"
+ android:translateY="-1">
+ <path
+ android:fillType="evenOdd"
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#D84336"
+ android:fillType="evenOdd"
+ android:pathData="M21.5515334,3.92885159 C21.8461538,5.16300283 22,6.45033294 22,7.77478792
+C22,9.13636778 21.835093,10.4608228 21.5253896,11.7290888 C20.8637506,14.4271641
+19.5414781,16.8663687 17.7395676,18.8670984 C16.1568627,20.6250114
+14.2021116,22.0437836 12,23 C9.79788839,22.0437836 7.84313725,20.6250114
+6.26143791,18.8670984 C4.45852187,16.8663687 3.13624937,14.4271641
+2.47561589,11.7290888 C2.16490699,10.4608228 2,9.13636778 2,7.77478792
+C2,6.45033294 2.15485168,5.16300283 2.44846657,3.92885159 C7.09502262,1.61506887
+12,1 12,1 C12,1 16.9049774,1.61506887 21.5515334,3.92885159 Z M14.6469246,7
+L11.9600359,9.71972847 L9.272253,7 L8.00878156,8.28072408 L10.6956703,11.0004526
+L8,13.720181 L9.26347144,15 L11.9600359,12.2802715 L14.7347402,15 L16,13.720181
+L13.2252957,11.0004526 L15.9121844,8.28072408 L14.6469246,7 Z" />
+ </group>
+</vector>
diff --git a/res/drawable/ic_print.xml b/res/drawable/ic_print.xml
deleted file mode 100644
index 647838d..0000000
--- a/res/drawable/ic_print.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@*android:drawable/ic_print"
- android:tint="@*android:color/material_deep_teal_500" />
diff --git a/res/drawable/ic_print_error.xml b/res/drawable/ic_print_error.xml
deleted file mode 100644
index 560aaab..0000000
--- a/res/drawable/ic_print_error.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@*android:drawable/ic_print_error"
- android:tint="@*android:color/material_deep_teal_500" />
diff --git a/res/layout/dialog_hardware_info.xml b/res/layout/dialog_hardware_info.xml
index 9431961..7ea4783 100644
--- a/res/layout/dialog_hardware_info.xml
+++ b/res/layout/dialog_hardware_info.xml
@@ -26,46 +26,40 @@
android:padding="24dp">
<TextView
+ style="@style/device_info_dialog_label"
android:id="@+id/model_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary"
android:text="@string/model_info" />
<TextView
+ style="@style/device_info_dialog_value"
android:id="@+id/model_value"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="24dp"
- android:textAppearance="@android:style/TextAppearance.Material.Body2" />
+ android:layout_height="wrap_content" />
<TextView
+ style="@style/device_info_dialog_label"
android:id="@+id/serial_number_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary"
android:text="@string/status_serial_number" />
<TextView
+ style="@style/device_info_dialog_value"
android:id="@+id/serial_number_value"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="24dp"
- android:textAppearance="@android:style/TextAppearance.Material.Body2" />
+ android:layout_height="wrap_content" />
<TextView
+ style="@style/device_info_dialog_label"
android:id="@+id/hardware_rev_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary"
android:text="@string/hardware_revision" />
<TextView
+ style="@style/device_info_dialog_value"
android:id="@+id/hardware_rev_value"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="24dp"
- android:textAppearance="@android:style/TextAppearance.Material.Body2" />
+ android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
\ No newline at end of file
diff --git a/res/layout/private_dns_mode_dialog.xml b/res/layout/private_dns_mode_dialog.xml
index 4347055..16152a4 100644
--- a/res/layout/private_dns_mode_dialog.xml
+++ b/res/layout/private_dns_mode_dialog.xml
@@ -16,6 +16,7 @@
<RadioGroup
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/private_dns_radio_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dip">
@@ -25,24 +26,21 @@
android:text="@string/private_dns_mode_off"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="8dip"
- />
+ android:layout_margin="8dip"/>
<RadioButton
android:id="@+id/private_dns_mode_opportunistic"
android:text="@string/private_dns_mode_opportunistic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="8dip"
- />
+ android:layout_margin="8dip"/>
<RadioButton
android:id="@+id/private_dns_mode_provider"
android:text="@string/private_dns_mode_provider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="8dip"
- />
+ android:layout_margin="8dip"/>
<EditText
android:id="@+id/private_dns_mode_provider_hostname"
@@ -52,8 +50,7 @@
android:inputType="textFilter|textUri"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginStart="8dip"
- android:layout_marginEnd="8dip"
- />
+ android:layout_marginStart="40dip"
+ android:layout_marginEnd="8dip"/>
</RadioGroup>
diff --git a/res/values-ar/arrays.xml b/res/values-ar/arrays.xml
index 69be316..311e5d4 100644
--- a/res/values-ar/arrays.xml
+++ b/res/values-ar/arrays.xml
@@ -217,7 +217,7 @@
<item msgid="7471182818083460781">"IS95A"</item>
</string-array>
<string-array name="mvno_type_entries">
- <item msgid="4367119357633573465">"None"</item>
+ <item msgid="4367119357633573465">"بدون"</item>
<item msgid="6062567900587138000">"SPN"</item>
<item msgid="2454085083342423481">"IMSI"</item>
<item msgid="2681427309183221543">"GID"</item>
diff --git a/res/values/config.xml b/res/values/config.xml
index 4ba73cc..097350b 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -41,9 +41,6 @@
<!-- Whether to show Connectivity Monitor switch in Developer Options -->
<bool name="config_show_connectivity_monitor">false</bool>
- <!-- Whether to show Camera HAL HDR+ switch in Developer Options -->
- <bool name="config_show_camera_hal_hdrplus">false</bool>
-
<!-- Whether to show Camera laser sensor switch in Developer Options -->
<bool name="config_show_camera_laser_sensor">false</bool>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index de75fc7..bc43892 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1572,9 +1572,9 @@
<!-- Bluetooth settings. Message for disconnecting from the PAN profile (user role). [CHAR LIMIT=80] -->
<string name="bluetooth_disconnect_pan_user_profile">Internet access via <xliff:g id="device_name">%1$s</xliff:g> will be disconnected.</string>
<!-- Bluetooth settings. Message for disconnecting from the PAN profile (NAP role). [CHAR LIMIT=80] -->
- <string name="bluetooth_disconnect_pan_nap_profile" product="tablet"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from sharing this tablet\u2019s Internet connection.</string>
+ <string name="bluetooth_disconnect_pan_nap_profile" product="tablet"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from sharing this tablet\u2019s internet connection.</string>
<!-- Bluetooth settings. Message for disconnecting from the PAN profile (NAP role). [CHAR LIMIT=80] -->
- <string name="bluetooth_disconnect_pan_nap_profile" product="default"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from sharing this phone\u2019s Internet connection.</string>
+ <string name="bluetooth_disconnect_pan_nap_profile" product="default"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from sharing this phone\u2019s internet connection.</string>
<!-- Bluetooth settings. Connection options screen. The title of the screen. [CHAR LIMIT=40] -->
<string name="bluetooth_device_advanced_title">Paired Bluetooth device</string>
@@ -1590,9 +1590,9 @@
<!-- Bluetooth settings. Connection options screen. Title for checkbox to enable incoming file transfers [CHAR LIMIT=30] -->
<string name="bluetooth_device_advanced_enable_opp_title">Allow incoming file transfers</string>
<!-- Bluetooth settings. Connection options screen. The summary for the checkbox preference when PAN is connected (user role). [CHAR LIMIT=25]-->
- <string name="bluetooth_pan_user_profile_summary_connected">Connected to device for Internet access</string>
+ <string name="bluetooth_pan_user_profile_summary_connected">Connected to device for internet access</string>
<!-- Bluetooth settings. Connection options screen. The summary for the checkbox preference when PAN is connected (NAP role). [CHAR LIMIT=25]-->
- <string name="bluetooth_pan_nap_profile_summary_connected">Sharing local Internet connection with device</string>
+ <string name="bluetooth_pan_nap_profile_summary_connected">Sharing local internet connection with device</string>
<!-- Bluetooth settings. Dock Setting Title -->
<string name="bluetooth_dock_settings">Dock Settings</string>
@@ -1726,9 +1726,9 @@
<!-- Checkbox title for option to toggle poor network detection -->
<string name="wifi_poor_network_detection">Avoid poor connections</string>
<!-- Checkbox summary for option to toggle poor network detection -->
- <string name="wifi_poor_network_detection_summary">Don\u2019t use a Wi\u2011Fi network unless it has a good Internet connection</string>
+ <string name="wifi_poor_network_detection_summary">Don\u2019t use a Wi\u2011Fi network unless it has a good internet connection</string>
<!-- Checkbox summary for option to toggle poor network detection [CHAR LIMIT=60] -->
- <string name="wifi_avoid_poor_network_detection_summary">Only use networks that have a good Internet connection</string>
+ <string name="wifi_avoid_poor_network_detection_summary">Only use networks that have a good internet connection</string>
<!-- Checkbox title for option to connect to open Wi-Fi automatically [CHAR LIMIT=40] -->
<string name="use_open_wifi_automatically_title">Connect to open networks</string>
<!-- Checkbox summary for option to connect to open Wi-Fi automatically [CHAR LIMIT=100] -->
@@ -1770,11 +1770,11 @@
<!-- Checkbox summary for option to toggle suspend power optimizations [CHAR LIMIT=30] -->
<string name="wifi_limit_optimizations_summary">Limit battery used by Wi\u2011Fi</string>
<!-- Checkbox title. Should we switch to using cellular data if Wi-Fi is still connected but the Wi-Fi network we're connected to no longer has Internet access (e.g., due to an outage)? -->
- <string name="wifi_switch_away_when_unvalidated">Switch to mobile data if Wi\u2011Fi loses Internet access.</string>
+ <string name="wifi_switch_away_when_unvalidated">Switch to mobile data if Wi\u2011Fi loses internet access.</string>
<!-- Preference title for option to automatically switch away from bad wifi networks [CHAR LIMIT=60]-->
<string name="wifi_cellular_data_fallback_title">Switch to mobile data automatically</string>
<!-- Preference summary to automatically switch away from bad wifi networks [CHAR LIMIT=None]-->
- <string name="wifi_cellular_data_fallback_summary">Use mobile data when Wi\u2011Fi has no Internet access. Data usage may apply.</string>
+ <string name="wifi_cellular_data_fallback_summary">Use mobile data when Wi\u2011Fi has no internet access. Data usage charges may apply.</string>
<!-- Action bar text message to manually add a wifi network [CHAR LIMIT=20]-->
<string name="wifi_add_network">Add network</string>
<!-- Action bar title to open additional Wi-Fi settings-->
@@ -1948,11 +1948,11 @@
<string name="wifi_hotspot_connect">CONNECT</string>
<!-- Dialog text to tell the user that the selected network does not have Internet access. -->
- <string name="no_internet_access_text">This network has no Internet access. Stay connected?</string>
+ <string name="no_internet_access_text">This network has no internet access. Stay connected?</string>
<string name="no_internet_access_remember">Don\u2019t ask again for this network</string>
<!-- Dialog text to tell the user that the selected network has lost Internet access, and asking the user whether they want to avoid this network. -->
- <string name="lost_internet_access_title">Wi\u2011Fi is not connected to the Internet</string>
+ <string name="lost_internet_access_title">Wi\u2011Fi is not connected to the internet</string>
<string name="lost_internet_access_text">You can switch to the mobile network whenever Wi\u2011Fi has a bad connection. Data usage charges may apply.</string>
<!-- Button text to let user switch to mobile data -->
<string name="lost_internet_access_switch">Switch to mobile</string>
@@ -1994,7 +1994,7 @@
<!-- Wifi Network Details -->
<!-- Wifi details title-->
- <string name="wifi_details_title">Network info</string>
+ <string name="wifi_details_title">Network details</string>
<!-- Wifi details preference title to display router IP subnet mask -->
<string name="wifi_details_subnet_mask">Subnet mask</string>
<!-- Wifi details preference title to display router DNS info -->
@@ -2065,13 +2065,13 @@
<!-- Label for Wifi tether checkbox. Toggles Access Point on/off [CHAR LIMIT=30] -->
<string name="wifi_hotspot_checkbox_text">Wi\u2011Fi hotspot</string>
<!-- Summary text when turning hotspot off -->
- <string name="wifi_hotspot_off_subtext">Not sharing Internet or content with other devices</string>
+ <string name="wifi_hotspot_off_subtext">Not sharing internet or content with other devices</string>
<!-- Summary text when tethering is on -->
- <string name="wifi_hotspot_tethering_on_subtext" product="tablet">Sharing this tablet\u2019s Internet connection via hotspot</string>
+ <string name="wifi_hotspot_tethering_on_subtext" product="tablet">Sharing this tablet\u2019s internet connection via hotspot</string>
<!-- Summary text when tethering is on -->
- <string name="wifi_hotspot_tethering_on_subtext" product="default">Sharing this phone\u2019s Internet connection via hotspot</string>
+ <string name="wifi_hotspot_tethering_on_subtext" product="default">Sharing this phone\u2019s internet connection via hotspot</string>
<!-- Summary text when hotspot is on for local-only -->
- <string name="wifi_hotspot_on_local_only_subtext">App is sharing content. To share Internet connection, turn hotspot off, then on</string>
+ <string name="wifi_hotspot_on_local_only_subtext">App is sharing content. To share internet connection, turn hotspot off, then on</string>
<!-- Wifi hotspot settings -->
<!-- Label for Wifi hotspot name. -->
@@ -2085,7 +2085,7 @@
<!-- Label for Wifi hotspot AP Band. -->
<string name="wifi_hotspot_ap_band_title">AP Band</string>
<!-- Wifi hotspot footer info for regular hotspot [CHAR LIMIT=NONE]-->
- <string name="wifi_hotspot_footer_info_regular">Use hotspot to create a Wi\u2011Fi network for your other devices. Hotspot provides Internet using your mobile data connection. Additional mobile data charges may apply.</string>
+ <string name="wifi_hotspot_footer_info_regular">Use hotspot to create a Wi\u2011Fi network for your other devices. Hotspot provides internet using your mobile data connection. Additional mobile data charges may apply.</string>
<!-- Wifi hotspot footer info [CHAR LIMIT=NONE]-->
<string name="wifi_hotspot_footer_info_local_only">Apps can create a hotspot to share content with nearby devices.</string>
@@ -2949,7 +2949,7 @@
<string name="storage_detail_explore">Explore <xliff:g id="name" example="SD card">^1</xliff:g></string>
<!-- Body of dialog informing user about other files on a storage device [CHAR LIMIT=NONE]-->
- <string name="storage_detail_dialog_other">Other includes shared files saved by apps, files downloaded from the Internet or Bluetooth, Android files, and so on.
+ <string name="storage_detail_dialog_other">Other includes shared files saved by apps, files downloaded from the internet or Bluetooth, Android files, and so on.
\n\nTo see the visible contents of this <xliff:g id="name" example="SD card">^1</xliff:g>, tap Explore.</string>
<!-- Body of dialog informing user about the storage used by the Android System [CHAR LIMIT=NONE]-->
@@ -3252,25 +3252,25 @@
<!-- USB Tethering options -->
<string name="usb_title">USB</string>
<string name="usb_tethering_button_text">USB tethering</string>
- <string name="usb_tethering_subtext" product="default">Share phone\u2019s Internet connection via USB</string>
- <string name="usb_tethering_subtext" product="tablet">Share tablet\u2019s Internet connection via USB</string>
+ <string name="usb_tethering_subtext" product="default">Share phone\u2019s internet connection via USB</string>
+ <string name="usb_tethering_subtext" product="tablet">Share tablet\u2019s internet connection via USB</string>
<!-- Bluetooth Tethering settings-->
<!-- Label for bluetooth tether checkbox [CHAR LIMIT=25]-->
<string name="bluetooth_tether_checkbox_text">Bluetooth tethering</string>
<!-- Bluetooth Tethering subtext [CHAR LIMIT=70]-->
- <string name="bluetooth_tethering_subtext" product="tablet">Share tablet\u2019s Internet connection via Bluetooth</string>
+ <string name="bluetooth_tethering_subtext" product="tablet">Share tablet\u2019s internet connection via Bluetooth</string>
<!-- Bluetooth Tethering subtext [CHAR LIMIT=70]-->
- <string name="bluetooth_tethering_subtext" product="default">Share phone\u2019s Internet connection via Bluetooth</string>
+ <string name="bluetooth_tethering_subtext" product="default">Share phone\u2019s internet connection via Bluetooth</string>
<!-- Bluetooth tethering off subtext - shown when Bluetooth Tethering is turned off [CHAR LIMIT=80]-->
- <string name="bluetooth_tethering_off_subtext_config">Sharing this <xliff:g id="device_name">%1$d</xliff:g>\u2019s Internet connection via Bluetooth</string>
+ <string name="bluetooth_tethering_off_subtext_config">Sharing this <xliff:g id="device_name">%1$d</xliff:g>\u2019s internet connection via Bluetooth</string>
<!-- Bluetooth Tethering settings. Error message shown when trying to connect an 8th device [CHAR LIMIT=50]-->
<string name="bluetooth_tethering_overflow_error">Can\u2019t tether to more than <xliff:g id="maxConnection">%1$d</xliff:g> devices.</string>
<!-- Bluetooth Tethering settings. Message for untethering from a bluetooth device [CHAR LIMIT=50]-->
<string name="bluetooth_untether_blank"><xliff:g id="device_name">%1$s</xliff:g> will be untethered.</string>
<!-- Tethering footer info [CHAR LIMIT=NONE]-->
- <string name="tethering_footer_info">Use hotspot and tethering to provide Internet to other devices through your mobile data connection. Apps can also create a hotspot to share content with nearby devices.</string>
+ <string name="tethering_footer_info">Use hotspot and tethering to provide internet to other devices through your mobile data connection. Apps can also create a hotspot to share content with nearby devices.</string>
<!-- Tethering help button - calls up a web view with general tethering info -->
<string name="tethering_help_button_text">Help</string>
@@ -3442,7 +3442,7 @@
<!-- About phone settings, Safety Legal information setting option name and title of dialog box holding safety legal info -->
<string name="settings_safetylegal_activity_title">Safety information</string>
<!-- About phone settings screen, Safety legal dialog message when data network is not connected -->
- <string name="settings_safetylegal_activity_unreachable">You don\u2019t have a data connection. To view this information now, go to %s from any computer connected to the Internet.</string>
+ <string name="settings_safetylegal_activity_unreachable">You don\u2019t have a data connection. To view this information now, go to %s from any computer connected to the internet.</string>
<!-- About phone settings screen, Safety Legal dialog title until the link is fully loaded -->
<string name="settings_safetylegal_activity_loading">Loading\u2026</string>
@@ -4057,6 +4057,8 @@
<!-- Title of setting on main settings screen. This item will take the user to the screen to tweak settings realted to locale and text -->
<string name="language_settings">Languages & input</string>
+ <!-- Text displayed when user has restriction DISALLOW_CONFIG_LOCALE [CHAR LIMIT=NONE]-->
+ <string name="language_empty_list_user_restricted">You don\u2019t have permission to change the device language.</string>
<!-- Title of Languages & input settings screen -->
<string name="language_keyboard_settings_title">Languages & input</string>
<!-- Title of preference category that lists all settings about helping user text input such as spell checker [CHAR LIMIT=60]-->
@@ -5861,9 +5863,9 @@
<!-- Dialog message title to set always-on VPN when another app was not already set. -->
<string name="vpn_set_vpn_title">Set always-on VPN?</string>
<!-- Dialog message body to explain that always-on VPN will disable network traffic while the VPN is connecting. -->
- <string name="vpn_first_always_on_vpn_message">By turning on this setting, you won\'t have an Internet connection until the VPN successfully connects</string>
+ <string name="vpn_first_always_on_vpn_message">When this setting is on, you won\'t have an internet connection until the VPN successfully connects</string>
<!-- Dialog message body to explain that always-on VPN will disable network traffic while the VPN is connecting, and that this will replace the current VPN. -->
- <string name="vpn_replace_always_on_vpn_enable_message">Your existing VPN will be replaced, and you won\'t have an Internet connection until the VPN successfully connects</string>
+ <string name="vpn_replace_always_on_vpn_enable_message">Your existing VPN will be replaced, and you won\'t have an internet connection until the VPN successfully connects</string>
<!-- Dialog message body to connect a VPN app, replacing another VPN app that is already always-on [CHAR LIMIT=NONE] -->
<string name="vpn_replace_always_on_vpn_disable_message">You\'re already connected to an always-on VPN. If you connect to a different one, your existing VPN will be replaced, and always-on mode will turn off.</string>
<!-- Dialog message body to set another VPN app to be always-on [CHAR LIMIT=NONE] -->
@@ -8187,7 +8189,7 @@
<string name="condition_airplane_title">Airplane mode is on</string>
<!-- Summary of condition that airplane mode is on [CHAR LIMIT=NONE] -->
- <string name="condition_airplane_summary">Wi-Fi, Bluetooth, and mobile network are turned off. You can\'t make phone calls or connect to the Internet.</string>
+ <string name="condition_airplane_summary">Wi-Fi, Bluetooth, and mobile network are turned off. You can\'t make phone calls or connect to the internet.</string>
<!-- Title of condition that do not disturb is on [CHAR LIMIT=30] -->
<string name="condition_zen_title">Do not disturb is on (<xliff:g name="zen_mode_type" example="Alarms only">%1$s</xliff:g>)</string>
@@ -8273,12 +8275,6 @@
<!-- Toast message letting the user know the how to apply connectivity monitor change -->
<string name="connectivity_monitor_toast">To apply connectivity monitor change, reboot device</string>
- <!-- Title for Camera HAL HDR+ switch [CHAR LIMIT=50] -->
- <string name="camera_hal_hdrplus_switch">Camera HAL HDR+</string>
-
- <!-- Toast message letting the user know how to enable Camera HAL HDR+ -->
- <string name="camera_hal_hdrplus_toast">To apply Camera HAL HDR+ change, reboot device</string>
-
<!-- Title for Camera laser sensor switch [CHAR LIMIT=NONE] -->
<string name="camera_laser_sensor_switch">Camera Laser Sensor</string>
@@ -8792,9 +8788,9 @@
<!-- setting enable OEM unlock Checkbox's summary to explain this Checkbox is disabled because the bootloader has been unlocked [CHAR_LIMIT=60] -->
<string name="oem_unlock_enable_disabled_summary_bootloader_unlocked">Bootloader is already unlocked</string>
<!-- setting enable OEM unlock Checkbox's summary to explain this Checkbox is disabled because there is no connectivity. [CHAR_LIMIT=60] -->
- <string name="oem_unlock_enable_disabled_summary_connectivity">Connect to the Internet first</string>
+ <string name="oem_unlock_enable_disabled_summary_connectivity">Connect to the internet first</string>
<!-- setting enable OEM unlock Checkbox's summary to explain this Checkbox is disabled because there is no connectivity or the device is locked by the carrier [CHAR_LIMIT=60] -->
- <string name="oem_unlock_enable_disabled_summary_connectivity_or_locked">Connect to the Internet or contact your carrier</string>
+ <string name="oem_unlock_enable_disabled_summary_connectivity_or_locked">Connect to the internet or contact your carrier</string>
<!-- setting enable OEM unlock Checkbox's summary to explain this Checkbox is disabled because this setting is unavailable on sim-locked devices. [CHAR_LIMIT=60] -->
<string name="oem_unlock_enable_disabled_summary_sim_locked_device">Unavailable on carrier-locked devices</string>
<!-- Information displayed after user locks OEM lock [Char Limit=None]-->
diff --git a/res/xml/app_default_settings.xml b/res/xml/app_default_settings.xml
index 0204c64..4d5c9d7 100644
--- a/res/xml/app_default_settings.xml
+++ b/res/xml/app_default_settings.xml
@@ -33,7 +33,7 @@
<extra android:name="for_work" android:value="false" />
</com.android.settings.widget.AppPreference>
- <com.android.settings.widget.AppPreference
+ <com.android.settings.widget.GearPreference
android:key="default_home"
android:title="@string/home_app"
android:fragment="com.android.settings.applications.defaultapps.DefaultHomePicker"
diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml
new file mode 100644
index 0000000..00a9142
--- /dev/null
+++ b/res/xml/app_notification_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="pref_app_header"
+ android:layout="@layout/settings_entity_header" />
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="block"
+ android:layout="@layout/styled_switch_bar" />
+
+ <!-- Show badge -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="badge"
+ android:title="@string/notification_badge_title"
+ settings:useAdditionalSummary="true"
+ settings:restrictedSwitchSummary="@string/enabled_by_admin" />
+
+ <!-- Channels/Channel groups added here -->
+
+ <Preference
+ android:key="app_link"
+ android:title="@string/app_settings_link"
+ android:order="500"
+ settings:allowDividerAbove="true"/>
+
+ <com.android.settings.notification.NotificationFooterPreference
+ android:key="block_desc"
+ android:order="1000" />
+
+ <com.android.settings.notification.NotificationFooterPreference
+ android:key="desc"
+ android:order="5000" />
+
+ <com.android.settings.notification.NotificationFooterPreference
+ android:key="deleted"
+ android:order="8000" />
+
+</PreferenceScreen>
diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml
new file mode 100644
index 0000000..aaadce4
--- /dev/null
+++ b/res/xml/channel_notification_settings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res/com.android.settings" >
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="pref_app_header"
+ android:layout="@layout/settings_entity_header" />
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="block"
+ android:layout="@layout/styled_switch_bar" />
+
+ <!-- Importance -->
+ <Preference
+ android:key="importance"
+ android:title="@string/notification_importance_title" />
+
+ <!-- Importance toggle -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="allow_sound"
+ android:title="@string/allow_interruption"
+ android:summary="@string/allow_interruption_summary" />
+
+ <!-- Default ringtone -->
+ <com.android.settings.notification.NotificationSoundPreference
+ android:key="ringtone"
+ android:title="@string/notification_channel_sound_title"
+ android:dialogTitle="@string/notification_channel_sound_title"
+ android:showSilent="true"
+ android:showDefault="true"
+ android:ringtoneType="notification" />
+
+ <!-- Vibration -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="vibrate"
+ android:title="@string/notification_vibrate_title"
+ settings:useAdditionalSummary="true" />
+
+ <!-- Visibility Override -->
+ <com.android.settings.notification.RestrictedDropDownPreference
+ android:key="visibility_override"
+ android:title="@string/app_notification_visibility_override_title"/>
+
+ <!-- Lights -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="lights"
+ android:title="@string/notification_show_lights_title"
+ settings:useAdditionalSummary="true"/>
+
+ <!-- Show badge -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="badge"
+ android:title="@string/notification_channel_badge_title"
+ settings:useAdditionalSummary="true"
+ settings:restrictedSwitchSummary="@string/enabled_by_admin"/>
+
+ <!-- Bypass DND -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="bypass_dnd"
+ android:title="@string/app_notification_override_dnd_title"
+ android:summary="@string/app_notification_override_dnd_summary"
+ settings:useAdditionalSummary="true"/>
+
+ <Preference
+ android:key="app_link"
+ android:title="@string/app_settings_link"
+ settings:allowDividerAbove="true"/>
+
+ <com.android.settings.notification.NotificationFooterPreference
+ android:key="desc" />
+
+ <com.android.settings.notification.NotificationFooterPreference
+ android:key="block_desc" />
+
+</PreferenceScreen>
diff --git a/res/xml/development_prefs.xml b/res/xml/development_settings.xml
similarity index 98%
rename from res/xml/development_prefs.xml
rename to res/xml/development_settings.xml
index c8c57a5..669f4fb 100644
--- a/res/xml/development_prefs.xml
+++ b/res/xml/development_settings.xml
@@ -172,10 +172,6 @@
android:key="camera_laser_sensor_switch"
android:title="@string/camera_laser_sensor_switch" />
- <SwitchPreference
- android:key="camera_hal_hdrplus_switch"
- android:title="@string/camera_hal_hdrplus_switch" />
-
<Preference
android:key="feature_flags_dashboard"
android:title="@string/feature_flags_dashboard_title"
diff --git a/res/xml/legacy_channel_notification_settings.xml b/res/xml/legacy_channel_notification_settings.xml
deleted file mode 100644
index 519bf5d..0000000
--- a/res/xml/legacy_channel_notification_settings.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:settings="http://schemas.android.com/apk/res/com.android.settings" >
-
- <!-- Show badge -->
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="badge"
- android:title="@string/notification_badge_title"
- settings:useAdditionalSummary="true"
- settings:restrictedSwitchSummary="@string/enabled_by_admin" />
-
- <!-- Importance toggle -->
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="allow_sound"
- android:title="@string/allow_interruption"
- android:summary="@string/allow_interruption_summary"/>
-
- <!-- Visibility Override -->
- <com.android.settings.notification.RestrictedDropDownPreference
- android:key="visibility_override"
- android:title="@string/app_notification_visibility_override_title" />
-
- <!-- Bypass DND -->
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="bypass_dnd"
- android:title="@string/app_notification_override_dnd_title"
- android:summary="@string/app_notification_override_dnd_summary"
- settings:useAdditionalSummary="true" />
-
-</PreferenceScreen>
diff --git a/res/xml/notification_group_settings.xml b/res/xml/notification_group_settings.xml
new file mode 100644
index 0000000..c138197
--- /dev/null
+++ b/res/xml/notification_group_settings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="pref_app_header"
+ android:layout="@layout/settings_entity_header" />
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="block"
+ android:layout="@layout/styled_switch_bar" />
+
+ <!-- Channels added here -->
+
+ <Preference
+ android:key="app_link"
+ android:title="@string/app_settings_link"
+ settings:allowDividerAbove="true"/>
+
+ <com.android.settings.notification.NotificationFooterPreference
+ android:key="desc" />
+
+ <com.android.settings.notification.NotificationFooterPreference
+ android:key="block_desc" />
+</PreferenceScreen>
diff --git a/res/xml/upgraded_app_notification_settings.xml b/res/xml/upgraded_app_notification_settings.xml
deleted file mode 100644
index f9a3304..0000000
--- a/res/xml/upgraded_app_notification_settings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
-
- <!-- Show badge -->
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="badge"
- android:title="@string/notification_badge_title"
- settings:useAdditionalSummary="true"
- settings:restrictedSwitchSummary="@string/enabled_by_admin" />
-
-</PreferenceScreen>
diff --git a/res/xml/upgraded_channel_notification_settings.xml b/res/xml/upgraded_channel_notification_settings.xml
deleted file mode 100644
index ee23435..0000000
--- a/res/xml/upgraded_channel_notification_settings.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:settings="http://schemas.android.com/apk/res/com.android.settings" >
-
- <!-- Importance -->
- <Preference
- android:key="importance"
- android:title="@string/notification_importance_title" />
-
- <!-- Default ringtone -->
- <com.android.settings.notification.NotificationSoundPreference
- android:key="ringtone"
- android:title="@string/notification_channel_sound_title"
- android:dialogTitle="@string/notification_channel_sound_title"
- android:showSilent="true"
- android:showDefault="true"
- android:ringtoneType="notification" />
-
- <!-- Vibration -->
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="vibrate"
- android:title="@string/notification_vibrate_title"
- settings:useAdditionalSummary="true" />
-
- <PreferenceCategory
- android:key="advanced"
- android:title="@string/advanced_apps">
-
- <!-- Visibility Override -->
- <com.android.settings.notification.RestrictedDropDownPreference
- android:key="visibility_override"
- android:title="@string/app_notification_visibility_override_title" />
-
- <!-- Lights -->
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="lights"
- android:title="@string/notification_show_lights_title"
- settings:useAdditionalSummary="true" />
-
- <!-- Show badge -->
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="badge"
- android:title="@string/notification_channel_badge_title"
- settings:useAdditionalSummary="true"
- settings:restrictedSwitchSummary="@string/enabled_by_admin" />
-
- <!-- Bypass DND -->
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="bypass_dnd"
- android:title="@string/app_notification_override_dnd_title"
- android:summary="@string/app_notification_override_dnd_summary"
- settings:useAdditionalSummary="true" />
-
- </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/src/com/android/settings/DeviceAdminSettings.java b/src/com/android/settings/DeviceAdminSettings.java
index 350d731..9391439 100644
--- a/src/com/android/settings/DeviceAdminSettings.java
+++ b/src/com/android/settings/DeviceAdminSettings.java
@@ -49,7 +49,6 @@
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.instrumentation.Instrumentable;
import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
@@ -137,9 +136,7 @@
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
Utils.forceCustomPadding(getListView(), true /* additive padding */);
- if (InstrumentedPreferenceFragment.usePreferenceScreenTitle()) {
- getActivity().setTitle(R.string.manage_device_admin);
- }
+ getActivity().setTitle(R.string.manage_device_admin);
}
@Override
diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java
index 42cac98..6c6c9e9 100644
--- a/src/com/android/settings/DeviceInfoSettings.java
+++ b/src/com/android/settings/DeviceInfoSettings.java
@@ -16,6 +16,8 @@
package com.android.settings;
+import static com.android.settings.core.FeatureFlags.DEVICE_INFO_V2;
+
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
@@ -55,8 +57,6 @@
public class DeviceInfoSettings extends DashboardFragment implements Indexable {
- public static final String DEVICE_INFO_V2_FEATURE_FLAG = "device_info_v2";
-
private static final String LOG_TAG = "DeviceInfoSettings";
private static final String KEY_LEGAL_CONTAINER = "legal_container";
@@ -88,7 +88,7 @@
@Override
protected int getPreferenceScreenResId() {
- return FeatureFlagUtils.isEnabled(DEVICE_INFO_V2_FEATURE_FLAG)
+ return FeatureFlagUtils.isEnabled(getContext(), DEVICE_INFO_V2)
? R.xml.device_info_settings_v2 : R.xml.device_info_settings;
}
@@ -125,7 +125,7 @@
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Activity activity, Fragment fragment, Lifecycle lifecycle) {
- if (FeatureFlagUtils.isEnabled(DEVICE_INFO_V2_FEATURE_FLAG)) {
+ if (FeatureFlagUtils.isEnabled(context, DEVICE_INFO_V2)) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
// Device name
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 96cc390..7a6f966 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -95,9 +95,7 @@
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (usePreferenceScreenTitle()) {
- getActivity().setTitle(R.string.master_clear_title);
- }
+ getActivity().setTitle(R.string.master_clear_title);
}
/**
diff --git a/src/com/android/settings/PrivacySettings.java b/src/com/android/settings/PrivacySettings.java
index a44e182..e547570 100644
--- a/src/com/android/settings/PrivacySettings.java
+++ b/src/com/android/settings/PrivacySettings.java
@@ -63,7 +63,6 @@
@VisibleForTesting
static final String DATA_MANAGEMENT = "data_management";
private static final String BACKUP_INACTIVE = "backup_inactive";
- private static final String FACTORY_RESET = "factory_reset";
private static final String TAG = "PrivacySettings";
private IBackupManager mBackupManager;
private Preference mBackup;
@@ -245,9 +244,5 @@
nonVisibleKeys.add(AUTO_RESTORE);
nonVisibleKeys.add(CONFIGURE_ACCOUNT);
}
- if (RestrictedLockUtils.hasBaseUserRestriction(context,
- UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) {
- nonVisibleKeys.add(FACTORY_RESET);
- }
}
}
diff --git a/src/com/android/settings/ResetNetwork.java b/src/com/android/settings/ResetNetwork.java
index dc89d05..0f08c26 100644
--- a/src/com/android/settings/ResetNetwork.java
+++ b/src/com/android/settings/ResetNetwork.java
@@ -68,9 +68,7 @@
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (usePreferenceScreenTitle()) {
- getActivity().setTitle(R.string.reset_network_title);
- }
+ getActivity().setTitle(R.string.reset_network_title);
}
/**
diff --git a/src/com/android/settings/ScreenPinningSettings.java b/src/com/android/settings/ScreenPinningSettings.java
index 68050b1..b3b6868 100644
--- a/src/com/android/settings/ScreenPinningSettings.java
+++ b/src/com/android/settings/ScreenPinningSettings.java
@@ -65,9 +65,7 @@
super.onActivityCreated(savedInstanceState);
final SettingsActivity activity = (SettingsActivity) getActivity();
- if (usePreferenceScreenTitle()) {
- activity.setTitle(R.string.screen_pinning_title);
- }
+ activity.setTitle(R.string.screen_pinning_title);
mLockPatternUtils = new LockPatternUtils(activity);
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index cbae80c..53cc046 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -16,6 +16,8 @@
package com.android.settings;
+import static com.android.settings.core.FeatureFlags.DEV_OPTION_V1;
+
import android.os.Bundle;
import android.util.FeatureFlagUtils;
@@ -65,7 +67,7 @@
@Deprecated
public static class DevelopmentSettingsActivity extends SettingsActivity {
public static final boolean isEnabled() {
- return FeatureFlagUtils.isEnabled("dev_option_v1");
+ return FeatureFlagUtils.isEnabled(null /* context */, DEV_OPTION_V1);
}
}
public static class DevelopmentSettingsDashboardActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 7203e24..f1c2a0a 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -62,7 +62,6 @@
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.DashboardSummary;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.search.SearchActivity;
import com.android.settings.wfd.WifiDisplaySettings;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
@@ -76,7 +75,7 @@
public class SettingsActivity extends SettingsDrawerActivity
implements PreferenceManager.OnPreferenceTreeClickListener,
PreferenceFragment.OnPreferenceStartFragmentCallback,
- ButtonBarHandler, FragmentManager.OnBackStackChangedListener, OnClickListener {
+ ButtonBarHandler, FragmentManager.OnBackStackChangedListener {
private static final String LOG_TAG = "Settings";
@@ -210,12 +209,7 @@
@Override
public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
- if (InstrumentedPreferenceFragment.usePreferenceScreenTitle()) {
- startPreferencePanel(caller, pref.getFragment(), pref.getExtras(), -1, null, null, 0);
- } else {
- startPreferencePanel(caller, pref.getFragment(), pref.getExtras(), -1, pref.getTitle(),
- null, 0);
- }
+ startPreferencePanel(caller, pref.getFragment(), pref.getExtras(), -1, null, null, 0);
return true;
}
@@ -329,8 +323,9 @@
if (mIsShowingDashboard) {
findViewById(R.id.search_bar).setVisibility(View.VISIBLE);
findViewById(R.id.action_bar).setVisibility(View.GONE);
- Toolbar toolbar = findViewById(R.id.search_action_bar);
- toolbar.setOnClickListener(this);
+ final Toolbar toolbar = findViewById(R.id.search_action_bar);
+ FeatureFactory.getFactory(this).getSearchFeatureProvider()
+ .initSearchToolbar(this, toolbar);
setActionBar(toolbar);
// Please forgive me for what I am about to do.
@@ -631,13 +626,8 @@
public void startPreferencePanel(Fragment caller, String fragmentClass, Bundle args,
int titleRes, CharSequence titleText, Fragment resultTo, int resultRequestCode) {
String title = null;
- if (titleRes < 0) {
- if (titleText != null) {
- title = titleText.toString();
- } else if (!InstrumentedPreferenceFragment.usePreferenceScreenTitle()) {
- // There not much we can do in that case
- title = "";
- }
+ if (titleRes < 0 && titleText != null) {
+ title = titleText.toString();
}
Utils.startWithFragment(this, fragmentClass, args, resultTo, resultRequestCode,
titleRes, title, mIsShortcut, mMetricsFeatureProvider.getMetricsCategory(caller));
@@ -959,10 +949,4 @@
return bitmap;
}
-
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(this, SearchActivity.class);
- startActivity(intent);
- }
}
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index a3d26af..5d3bf00 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -150,8 +150,8 @@
}
// Prepare help url and enable menu if necessary
- Bundle arguments = getArguments();
- int helpResource;
+ final Bundle arguments = getArguments();
+ final int helpResource;
if (arguments != null && arguments.containsKey(HELP_URI_RESOURCE_KEY)) {
helpResource = arguments.getInt(HELP_URI_RESOURCE_KEY);
} else {
@@ -160,6 +160,17 @@
if (helpResource != 0) {
mHelpUri = getResources().getString(helpResource);
}
+
+ // Check if we should keep the preferences expanded.
+ if (arguments != null) {
+ mPreferenceKey = arguments.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
+ if (!TextUtils.isEmpty(mPreferenceKey)) {
+ final PreferenceScreen screen = getPreferenceScreen();
+ if (screen != null) {
+ screen.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
+ }
+ }
+ }
}
@Override
@@ -224,9 +235,7 @@
public void onResume() {
super.onResume();
- final Bundle args = getArguments();
- if (args != null) {
- mPreferenceKey = args.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
+ if (mPreferenceKey != null) {
highlightPreferenceIfNeeded();
}
}
diff --git a/src/com/android/settings/TrustedCredentialsSettings.java b/src/com/android/settings/TrustedCredentialsSettings.java
index 479a914..491419a 100644
--- a/src/com/android/settings/TrustedCredentialsSettings.java
+++ b/src/com/android/settings/TrustedCredentialsSettings.java
@@ -203,9 +203,7 @@
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
activity.registerReceiver(mWorkProfileChangedReceiver, filter);
- if (usePreferenceScreenTitle()) {
- activity.setTitle(R.string.trusted_credentials);
- }
+ activity.setTitle(R.string.trusted_credentials);
}
@Override
diff --git a/src/com/android/settings/UserCredentialsSettings.java b/src/com/android/settings/UserCredentialsSettings.java
index f8966a5..54e12a8 100644
--- a/src/com/android/settings/UserCredentialsSettings.java
+++ b/src/com/android/settings/UserCredentialsSettings.java
@@ -87,9 +87,7 @@
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (usePreferenceScreenTitle()) {
- getActivity().setTitle(R.string.user_credentials);
- }
+ getActivity().setTitle(R.string.user_credentials);
}
protected void announceRemoval(String alias) {
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index b108c62..cab3139 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -48,7 +48,6 @@
import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -62,7 +61,6 @@
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
-import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Bundle;
@@ -97,7 +95,6 @@
import android.text.style.TtsSpan;
import android.util.ArraySet;
import android.util.Log;
-import android.util.SparseArray;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
@@ -108,13 +105,10 @@
import com.android.internal.app.UnlaunchableAppActivity;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.UserIcons;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
import com.android.settings.wrapper.FingerprintManagerWrapper;
-import java.io.IOException;
-import java.io.InputStream;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Iterator;
@@ -131,11 +125,6 @@
public static final int UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY = 1;
/**
- * The opacity level of a disabled icon.
- */
- public static final float DISABLED_ALPHA = 0.4f;
-
- /**
* Color spectrum to use to indicate badness. 0 is completely transparent (no data),
* 1 is most bad (red), the last value is least bad (green).
*/
@@ -152,8 +141,6 @@
public static final String OS_PKG = "os";
- private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<Bitmap>();
-
/**
* Finds a matching activity for a preference's intent. If a matching
* activity is not found, it will remove the preference.
@@ -344,46 +331,6 @@
view.setPaddingRelative(paddingStart, 0, paddingEnd, paddingBottom);
}
- /* Used by UserSettings as well. Call this on a non-ui thread. */
- public static void copyMeProfilePhoto(Context context, UserInfo user) {
- Uri contactUri = Profile.CONTENT_URI;
-
- int userId = user != null ? user.id : UserHandle.myUserId();
-
- InputStream avatarDataStream = Contacts.openContactPhotoInputStream(
- context.getContentResolver(),
- contactUri, true);
- // If there's no profile photo, assign a default avatar
- if (avatarDataStream == null) {
- assignDefaultPhoto(context, userId);
- return;
- }
-
- UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
- Bitmap icon = BitmapFactory.decodeStream(avatarDataStream);
- um.setUserIcon(userId, icon);
- try {
- avatarDataStream.close();
- } catch (IOException ioe) { }
- }
-
- /**
- * Assign the default photo to user with {@paramref userId}
- * @param context used to get the {@link UserManager}
- * @param userId used to get the icon bitmap
- * @return true if assign photo successfully, false if failed
- */
- public static boolean assignDefaultPhoto(Context context, int userId) {
- if (context == null) {
- return false;
- }
- UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
- Bitmap bitmap = getDefaultUserIconAsBitmap(userId);
- um.setUserIcon(userId, bitmap);
-
- return true;
- }
-
public static String getMeProfileName(Context context, boolean full) {
if (full) {
return getProfileDisplayName(context);
@@ -504,6 +451,26 @@
metricsCategory);
}
+
+ /**
+ * Start a new instance of the activity, showing only the given fragment.
+ * When launched in this mode, the given preference fragment will be instantiated and fill the
+ * entire activity.
+ *
+ * @param context The context.
+ * @param fragmentName The name of the fragment to display.
+ * @param titleResId resource id for the String to display for the title of this set
+ * of preferences.
+ * @param metricsCategory The current metricsCategory for logging source when fragment starts
+ * @param intentFlags flag that should be added to the intent.
+ */
+ public static void startWithFragment(Context context, String fragmentName, int titleResId,
+ int metricsCategory, int intentFlags) {
+ startWithFragment(context, fragmentName, null, null, 0,
+ null /* titleResPackageName */, titleResId, null, false /* not a shortcut */,
+ metricsCategory, intentFlags);
+ }
+
/**
* Start a new instance of the activity, showing only the given fragment.
* When launched in this mode, the given preference fragment will be instantiated and fill the
@@ -544,8 +511,17 @@
public static void startWithFragment(Context context, String fragmentName, Bundle args,
Fragment resultTo, int resultRequestCode, String titleResPackageName, int titleResId,
CharSequence title, boolean isShortcut, int metricsCategory) {
+ startWithFragment(context, fragmentName, args, resultTo, resultRequestCode,
+ titleResPackageName, titleResId, title, isShortcut, metricsCategory, 0);
+ }
+
+
+ public static void startWithFragment(Context context, String fragmentName, Bundle args,
+ Fragment resultTo, int resultRequestCode, String titleResPackageName, int titleResId,
+ CharSequence title, boolean isShortcut, int metricsCategory, int flags) {
Intent intent = onBuildStartFragmentIntent(context, fragmentName, args, titleResPackageName,
titleResId, title, isShortcut, metricsCategory);
+ intent.addFlags(flags);
if (resultTo == null) {
context.startActivity(intent);
} else {
@@ -936,23 +912,6 @@
return (sm.getStorageBytesUntilLow(context.getFilesDir()) < 0);
}
- /**
- * Returns a default user icon (as a {@link Bitmap}) for the given user.
- *
- * Note that for guest users, you should pass in {@code UserHandle.USER_NULL}.
- * @param userId the user id or {@code UserHandle.USER_NULL} for a non-user specific icon
- */
- public static Bitmap getDefaultUserIconAsBitmap(int userId) {
- Bitmap bitmap = null;
- // Try finding the corresponding bitmap in the dark bitmap cache
- bitmap = sDarkDefaultUserBitmapCache.get(userId);
- if (bitmap == null) {
- bitmap = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(userId, false));
- // Save it to cache
- sDarkDefaultUserBitmapCache.put(userId, bitmap);
- }
- return bitmap;
- }
public static boolean hasPreferredActivities(PackageManager pm, String packageName) {
// Get list of preferred activities
@@ -969,7 +928,7 @@
List<IntentFilter> filters = pm.getAllIntentFilters(packageName);
ArraySet<String> result = new ArraySet<>();
- if (iviList.size() > 0) {
+ if (iviList != null && iviList.size() > 0) {
for (IntentFilterVerificationInfo ivi : iviList) {
for (String host : ivi.getDomains()) {
result.add(host);
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 15e0095..877894b 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -521,9 +521,7 @@
extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
extras.putString(EXTRA_TITLE, title);
- if (usePreferenceScreenTitle()) {
- extras.putParcelable(EXTRA_RESOLVE_INFO, resolveInfo);
- }
+ extras.putParcelable(EXTRA_RESOLVE_INFO, resolveInfo);
String description = info.loadDescription(getPackageManager());
if (TextUtils.isEmpty(description)) {
diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
index 0f6bdd7..c437a16 100644
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
@@ -59,9 +59,6 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (!usePreferenceScreenTitle()) {
- addPreferencesFromResource(R.xml.accessibility_shortcut_settings);
- }
mServicePreference = findPreference(SHORTCUT_SERVICE_KEY);
mOnLockScreenSwitchPreference = (SwitchPreference) findPreference(ON_LOCK_SCREEN_KEY);
mOnLockScreenSwitchPreference.setOnPreferenceChangeListener((Preference p, Object o) -> {
diff --git a/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
index 7ad4d41..d0197cf 100644
--- a/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
@@ -141,10 +141,8 @@
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
extras.putString(AccessibilitySettings.EXTRA_TITLE, getString(
R.string.accessibility_screen_magnification_navbar_title));
- if (usePreferenceScreenTitle()) {
- extras.putInt(AccessibilitySettings.EXTRA_TITLE_RES,
- R.string.accessibility_screen_magnification_navbar_title);
- }
+ extras.putInt(AccessibilitySettings.EXTRA_TITLE_RES,
+ R.string.accessibility_screen_magnification_navbar_title);
extras.putCharSequence(AccessibilitySettings.EXTRA_SUMMARY,
getActivity().getResources().getText(
R.string.accessibility_screen_magnification_navbar_summary));
@@ -194,10 +192,8 @@
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
extras.putString(AccessibilitySettings.EXTRA_TITLE, context.getString(
R.string.accessibility_screen_magnification_gestures_title));
- if (usePreferenceScreenTitle()) {
- extras.putInt(AccessibilitySettings.EXTRA_TITLE_RES,
- R.string.accessibility_screen_magnification_gestures_title);
- }
+ extras.putInt(AccessibilitySettings.EXTRA_TITLE_RES,
+ R.string.accessibility_screen_magnification_gestures_title);
extras.putCharSequence(AccessibilitySettings.EXTRA_SUMMARY, context.getResources().getText(
R.string.accessibility_screen_magnification_summary));
extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED,
diff --git a/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java
index 5fa38e1..a94b72c 100644
--- a/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java
@@ -20,7 +20,6 @@
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.preference.Preference;
-import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.Switch;
@@ -29,7 +28,6 @@
import com.android.settings.widget.SeekBarPreference;
import com.android.settings.widget.SwitchBar;
-
/**
* Fragment for preference screen for settings related to Automatically click after mouse stops
* feature.
@@ -118,10 +116,6 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (!usePreferenceScreenTitle()) {
- addPreferencesFromResource(R.xml.accessibility_autoclick_settings);
- }
-
int delay = Settings.Secure.getInt(
getContentResolver(), Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
AccessibilityManager.AUTOCLICK_DELAY_DEFAULT);
@@ -157,15 +151,6 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- if (!usePreferenceScreenTitle()) {
- setTitle(getString(R.string.accessibility_autoclick_preference_title));
- }
- }
-
- @Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == mDelay && newValue instanceof Integer) {
Settings.Secure.putInt(getContentResolver(),
diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
index 6ee7217..8e76e48 100644
--- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
@@ -20,7 +20,6 @@
import android.provider.Settings;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
-import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.Switch;
@@ -50,10 +49,6 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (!usePreferenceScreenTitle()) {
- addPreferencesFromResource(R.xml.accessibility_daltonizer_settings);
- }
-
mType = (ListPreference) findPreference("type");
if (!AccessibilitySettings.isColorTransformAccelerated(getActivity())) {
@@ -84,15 +79,6 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- if (!usePreferenceScreenTitle()) {
- setTitle(getString(R.string.accessibility_display_daltonizer_preference_title));
- }
- }
-
- @Override
protected void onInstallSwitchBarToggleSwitch() {
super.onInstallSwitchBarToggleSwitch();
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index e647954..85d3a2f 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -42,7 +42,7 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final int resId = getPreferenceScreenResId();
- if (!usePreferenceScreenTitle() || resId <= 0) {
+ if (resId <= 0) {
PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
getActivity());
setPreferenceScreen(preferenceScreen);
@@ -119,8 +119,7 @@
}
// Title.
- if (usePreferenceScreenTitle()
- && arguments.containsKey(AccessibilitySettings.EXTRA_RESOLVE_INFO)) {
+ if (arguments.containsKey(AccessibilitySettings.EXTRA_RESOLVE_INFO)) {
ResolveInfo info = arguments.getParcelable(AccessibilitySettings.EXTRA_RESOLVE_INFO);
getActivity().setTitle(info.loadLabel(getPackageManager()).toString());
} else if (arguments.containsKey(AccessibilitySettings.EXTRA_TITLE)) {
diff --git a/src/com/android/settings/accessibility/ToggleFontSizePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFontSizePreferenceFragment.java
index 3e1e732..8c15e5b 100644
--- a/src/com/android/settings/accessibility/ToggleFontSizePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFontSizePreferenceFragment.java
@@ -52,9 +52,7 @@
for (int i = 0; i < strEntryValues.length; ++i) {
mValues[i] = Float.parseFloat(strEntryValues[i]);
}
- if (usePreferenceScreenTitle()) {
- getActivity().setTitle(R.string.title_font_size);
- }
+ getActivity().setTitle(R.string.title_font_size);
}
@Override
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index 35f7375..ecb4b9f 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -216,8 +216,7 @@
mInitialSetting = arguments.getBoolean(AccessibilitySettings.EXTRA_CHECKED);
}
- if (usePreferenceScreenTitle()
- && arguments.containsKey(AccessibilitySettings.EXTRA_TITLE_RES)) {
+ if (arguments.containsKey(AccessibilitySettings.EXTRA_TITLE_RES)) {
final int titleRes = arguments.getInt(AccessibilitySettings.EXTRA_TITLE_RES);
if (titleRes > 0) {
getActivity().setTitle(titleRes);
diff --git a/src/com/android/settings/applications/ConvertToFbe.java b/src/com/android/settings/applications/ConvertToFbe.java
index 192cd14..5f5ebd9 100644
--- a/src/com/android/settings/applications/ConvertToFbe.java
+++ b/src/com/android/settings/applications/ConvertToFbe.java
@@ -29,7 +29,6 @@
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.core.InstrumentedFragment;
-import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.password.ChooseLockSettingsHelper;
/* Class to prompt for conversion of userdata to file based encryption
@@ -49,9 +48,7 @@
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (InstrumentedPreferenceFragment.usePreferenceScreenTitle()) {
- getActivity().setTitle(R.string.convert_to_file_encryption);
- }
+ getActivity().setTitle(R.string.convert_to_file_encryption);
}
@Override
diff --git a/src/com/android/settings/applications/ManageDomainUrls.java b/src/com/android/settings/applications/ManageDomainUrls.java
index 53cad4a..adf406a 100644
--- a/src/com/android/settings/applications/ManageDomainUrls.java
+++ b/src/com/android/settings/applications/ManageDomainUrls.java
@@ -23,6 +23,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.Global;
+import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
@@ -37,6 +38,7 @@
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
+import com.android.settings.widget.AppPreference;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -63,9 +65,6 @@
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setAnimationAllowed(true);
- if (!usePreferenceScreenTitle()) {
- setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
- }
mApplicationsState = ApplicationsState.getInstance(
(Application) getContext().getApplicationContext());
mSession = mApplicationsState.newSession(this, getLifecycle());
@@ -175,7 +174,7 @@
String key = entry.info.packageName + "|" + entry.info.uid;
DomainAppPreference preference = (DomainAppPreference) getCachedPreference(key);
if (preference == null) {
- preference = new DomainAppPreference(getPrefContext(), entry);
+ preference = new DomainAppPreference(getPrefContext(), mApplicationsState, entry);
preference.setKey(key);
preference.setOnPreferenceClickListener(this);
group.addPreference(preference);
@@ -225,12 +224,16 @@
return false;
}
- private class DomainAppPreference extends Preference {
+ @VisibleForTesting
+ static class DomainAppPreference extends AppPreference {
private final AppEntry mEntry;
private final PackageManager mPm;
+ private final ApplicationsState mApplicationsState;
- public DomainAppPreference(final Context context, AppEntry entry) {
+ public DomainAppPreference(final Context context, ApplicationsState applicationsState,
+ AppEntry entry) {
super(context);
+ mApplicationsState = applicationsState;
mPm = context.getPackageManager();
mEntry = entry;
mEntry.ensureLabel(getContext());
diff --git a/src/com/android/settings/applications/PictureInPictureSettings.java b/src/com/android/settings/applications/PictureInPictureSettings.java
index 3dc8ab3..01d14f4 100644
--- a/src/com/android/settings/applications/PictureInPictureSettings.java
+++ b/src/com/android/settings/applications/PictureInPictureSettings.java
@@ -148,9 +148,6 @@
mPackageManager = new PackageManagerWrapper(mContext.getPackageManager());
mUserManager = new UserManagerWrapper(mContext.getSystemService(UserManager.class));
mIconDrawableFactory = IconDrawableFactory.newInstance(mContext);
- if (!usePreferenceScreenTitle()) {
- setPreferenceScreen(getPreferenceManager().createPreferenceScreen(mContext));
- }
}
@Override
diff --git a/src/com/android/settings/applications/PremiumSmsAccess.java b/src/com/android/settings/applications/PremiumSmsAccess.java
index b6613f2..ab6ea24 100644
--- a/src/com/android/settings/applications/PremiumSmsAccess.java
+++ b/src/com/android/settings/applications/PremiumSmsAccess.java
@@ -124,14 +124,8 @@
if (apps == null) return;
setEmptyText(R.string.premium_sms_none);
setLoading(false, true);
- final PreferenceScreen screen;
- if (usePreferenceScreenTitle()) {
- screen = getPreferenceScreen();
- screen.removeAll();
- } else {
- screen = getPreferenceManager().createPreferenceScreen(getPrefContext());
- }
-
+ final PreferenceScreen screen = getPreferenceScreen();
+ screen.removeAll();
screen.setOrderingAsAdded(true);
for (int i = 0; i < apps.size(); i++) {
@@ -145,10 +139,6 @@
footer.setTitle(R.string.premium_sms_warning);
screen.addPreference(footer);
}
-
- if (!usePreferenceScreenTitle()) {
- setPreferenceScreen(screen);
- }
}
private void update() {
diff --git a/src/com/android/settings/applications/RunningServices.java b/src/com/android/settings/applications/RunningServices.java
index dd8f278..4e3d629 100644
--- a/src/com/android/settings/applications/RunningServices.java
+++ b/src/com/android/settings/applications/RunningServices.java
@@ -44,9 +44,7 @@
setHasOptionsMenu(true);
- if (usePreferenceScreenTitle()) {
- getActivity().setTitle(R.string.runningservices_settings_title);
- }
+ getActivity().setTitle(R.string.runningservices_settings_title);
}
@Override
diff --git a/src/com/android/settings/applications/appops/BackgroundCheckSummary.java b/src/com/android/settings/applications/appops/BackgroundCheckSummary.java
index f46e6a4..d9db9aa 100644
--- a/src/com/android/settings/applications/appops/BackgroundCheckSummary.java
+++ b/src/com/android/settings/applications/appops/BackgroundCheckSummary.java
@@ -40,9 +40,7 @@
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (usePreferenceScreenTitle()) {
- getActivity().setTitle(R.string.background_check_pref);
- }
+ getActivity().setTitle(R.string.background_check_pref);
}
@Override
diff --git a/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java
index bd8b5d1..a7d65d3 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java
@@ -63,7 +63,7 @@
if (currentDefaultHome != null) {
return new DefaultAppInfo(mContext, mPackageManager, mUserId, currentDefaultHome);
}
- final ActivityInfo onlyAppInfo = getOnlyAppInfo();
+ final ActivityInfo onlyAppInfo = getOnlyAppInfo(homeActivities);
if (onlyAppInfo != null) {
return new DefaultAppInfo(mContext, mPackageManager, mUserId,
onlyAppInfo.getComponentName());
@@ -71,8 +71,7 @@
return null;
}
- private ActivityInfo getOnlyAppInfo() {
- final List<ResolveInfo> homeActivities = new ArrayList<>();
+ private ActivityInfo getOnlyAppInfo(List<ResolveInfo> homeActivities) {
final List<ActivityInfo> appLabels = new ArrayList<>();
mPackageManager.getHomeActivities(homeActivities);
@@ -88,6 +87,23 @@
: null;
}
+ @Override
+ protected Intent getSettingIntent(DefaultAppInfo info) {
+ final String packageName;
+ if (info.componentName != null) {
+ packageName = info.componentName.getPackageName();
+ } else if (info.packageItemInfo != null) {
+ packageName = info.packageItemInfo.packageName;
+ } else {
+ return null;
+ }
+
+ Intent intent = new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
+ .setPackage(packageName)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return mPackageManager.queryIntentActivities(intent, 0).size() == 1 ? intent : null;
+ }
+
public static boolean hasHomePreference(String pkg, Context context) {
ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
PackageManager pm = context.getPackageManager();
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index 7dc8951..d55c996 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -293,7 +293,7 @@
mResetAppsHelper = new ResetAppsHelper(activity);
- if (usePreferenceScreenTitle() && screenTitle > 0) {
+ if (screenTitle > 0) {
activity.setTitle(screenTitle);
}
}
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsController.java b/src/com/android/settings/bluetooth/BluetoothDetailsController.java
index 265690b..63d7b5c 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsController.java
@@ -72,8 +72,8 @@
@Override
public final void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
init(screen);
+ super.displayPreference(screen);
}
/**
diff --git a/src/com/android/settings/core/DynamicAvailabilityPreferenceController.java b/src/com/android/settings/core/DynamicAvailabilityPreferenceController.java
deleted file mode 100644
index 04a561c..0000000
--- a/src/com/android/settings/core/DynamicAvailabilityPreferenceController.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.core;
-
-import android.content.Context;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-
-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;
-
-public abstract class DynamicAvailabilityPreferenceController extends AbstractPreferenceController
- implements PreferenceControllerMixin, LifecycleObserver, OnResume {
-
- private Preference mPreference;
- private PreferenceScreen mScreen;
- private PreferenceAvailabilityObserver mAvailabilityObserver = null;
-
- public DynamicAvailabilityPreferenceController(Context context, Lifecycle lifecycle) {
- super(context);
- if (lifecycle != null) {
- lifecycle.addObserver(this);
- }
- }
-
- public void setAvailabilityObserver(PreferenceAvailabilityObserver observer) {
- mAvailabilityObserver = observer;
- }
-
- public PreferenceAvailabilityObserver getAvailabilityObserver() {
- return mAvailabilityObserver;
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- mScreen = screen;
- mPreference = screen.findPreference(getPreferenceKey());
- super.displayPreference(screen);
- }
-
- @Override
- public void onResume() {
- if (!isAvailable()) {
- removePreference(mScreen, getPreferenceKey());
- return;
- }
-
- updateState(mPreference);
- if (mScreen.findPreference(getPreferenceKey()) == null) {
- mScreen.addPreference(mPreference);
- }
- }
-
- protected void notifyOnAvailabilityUpdate(boolean available) {
- if (mAvailabilityObserver != null) {
- mAvailabilityObserver.onPreferenceAvailabilityUpdated(getPreferenceKey(), available);
- }
- }
-}
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
new file mode 100644
index 0000000..91699d4
--- /dev/null
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -0,0 +1,27 @@
+/*
+ * 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.core;
+
+/**
+ * This class keeps track of all feature flags in Settings.
+ */
+public class FeatureFlags {
+ public static final String DEVICE_INFO_V2 = "device_info_v2";
+ public static final String DEV_OPTION_V1 = "dev_option_v1";
+ public static final String SEARCH_V2 = "settings_search_v2";
+ public static final String SUGGESTIONS_V2 = "new_settings_suggestion";
+}
diff --git a/src/com/android/settings/core/InstrumentedPreferenceFragment.java b/src/com/android/settings/core/InstrumentedPreferenceFragment.java
index 5b95d66..7e37115 100644
--- a/src/com/android/settings/core/InstrumentedPreferenceFragment.java
+++ b/src/com/android/settings/core/InstrumentedPreferenceFragment.java
@@ -18,11 +18,9 @@
import android.content.Context;
import android.os.Bundle;
-import android.support.annotation.VisibleForTesting;
import android.support.annotation.XmlRes;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
-import android.util.FeatureFlagUtils;
import android.util.Log;
import com.android.settings.core.instrumentation.Instrumentable;
@@ -39,9 +37,8 @@
implements Instrumentable {
private static final String TAG = "InstrumentedPrefFrag";
- @VisibleForTesting
- static final String FEATURE_FLAG_USE_PREFERENCE_SCREEN_TITLE =
- "settings_use_preference_screen_title";
+
+
protected MetricsFeatureProvider mMetricsFeatureProvider;
// metrics placeholder value. Only use this for development.
@@ -70,11 +67,9 @@
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
- if (usePreferenceScreenTitle()) {
- final int resId = getPreferenceScreenResId();
- if (resId > 0) {
- addPreferencesFromResource(resId);
- }
+ final int resId = getPreferenceScreenResId();
+ if (resId > 0) {
+ addPreferencesFromResource(resId);
}
}
@@ -84,10 +79,6 @@
updateActivityTitleWithScreenTitle(getPreferenceScreen());
}
- public static boolean usePreferenceScreenTitle() {
- return FeatureFlagUtils.isEnabled(FEATURE_FLAG_USE_PREFERENCE_SCREEN_TITLE) || true;
- }
-
protected final Context getPrefContext() {
return getPreferenceManager().getContext();
}
@@ -104,7 +95,7 @@
}
private void updateActivityTitleWithScreenTitle(PreferenceScreen screen) {
- if (usePreferenceScreenTitle() && screen != null) {
+ if (screen != null) {
final CharSequence title = screen.getTitle();
if (!TextUtils.isEmpty(title)) {
getActivity().setTitle(title);
diff --git a/src/com/android/settings/core/PreferenceAvailabilityObserver.java b/src/com/android/settings/core/PreferenceAvailabilityObserver.java
deleted file mode 100644
index 46ff3ba..0000000
--- a/src/com/android/settings/core/PreferenceAvailabilityObserver.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.core;
-
-/**
- * @deprecated This interface allows a {@link android.support.v7.preference.PreferenceGroup}'s
- * controller to observe the availability of the {@link android.support.v7.preference.Preference}s
- * inside it, hiding the group when all preferences become unavailable. In the future,
- * {@link android.support.v7.preference.PreferenceGroup} will have native support for that
- * functionality, removing the need for this interface.
- */
-public interface PreferenceAvailabilityObserver {
-
- /**
- * Notifies the observer that the availability of the preference identified by {@code key} has
- * been updated.
- */
- void onPreferenceAvailabilityUpdated(String key, boolean available);
-}
diff --git a/src/com/android/settings/dashboard/conditional/NightDisplayCondition.java b/src/com/android/settings/dashboard/conditional/NightDisplayCondition.java
index bfcab7f..4d885ae 100644
--- a/src/com/android/settings/dashboard/conditional/NightDisplayCondition.java
+++ b/src/com/android/settings/dashboard/conditional/NightDisplayCondition.java
@@ -18,20 +18,20 @@
import android.graphics.drawable.Icon;
-import com.android.internal.app.NightDisplayController;
+import com.android.internal.app.ColorDisplayController;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.display.NightDisplaySettings;
public final class NightDisplayCondition extends Condition
- implements NightDisplayController.Callback {
+ implements ColorDisplayController.Callback {
- private NightDisplayController mController;
+ private ColorDisplayController mController;
NightDisplayCondition(ConditionManager manager) {
super(manager);
- mController = new NightDisplayController(manager.getContext());
+ mController = new ColorDisplayController(manager.getContext());
mController.setListener(this);
}
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
index 1be31b4..4f4753a 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
@@ -16,6 +16,8 @@
package com.android.settings.dashboard.suggestions;
+import static com.android.settings.core.FeatureFlags.SUGGESTIONS_V2;
+
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -62,8 +64,6 @@
private static final int EXCLUSIVE_SUGGESTION_MAX_COUNT = 3;
private static final String SHARED_PREF_FILENAME = "suggestions";
- @VisibleForTesting
- static final String FEATURE_FLAG_SUGGESTIONS_V2 = "new_settings_suggestion";
private final SuggestionRanker mSuggestionRanker;
private final MetricsFeatureProvider mMetricsFeatureProvider;
@@ -73,7 +73,7 @@
final ActivityManager am =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
boolean isLowRamDevice = am.isLowRamDevice();
- return !isLowRamDevice && !isV2Enabled();
+ return !isLowRamDevice && !isV2Enabled(context);
}
@Override
@@ -81,7 +81,7 @@
final ActivityManager am =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
boolean isLowRamDevice = am.isLowRamDevice();
- return !isLowRamDevice && isV2Enabled();
+ return !isLowRamDevice && isV2Enabled(context);
}
@Override
@@ -91,8 +91,8 @@
"com.android.settings.intelligence.suggestions.SuggestionService");
}
- private static boolean isV2Enabled() {
- return FeatureFlagUtils.isEnabled(FEATURE_FLAG_SUGGESTIONS_V2) || true;
+ private static boolean isV2Enabled(Context context) {
+ return FeatureFlagUtils.isEnabled(context, SUGGESTIONS_V2) || true;
}
@Override
diff --git a/src/com/android/settings/datausage/DataUsagePreference.java b/src/com/android/settings/datausage/DataUsagePreference.java
index 35cfbbc..32c7011 100644
--- a/src/com/android/settings/datausage/DataUsagePreference.java
+++ b/src/com/android/settings/datausage/DataUsagePreference.java
@@ -37,15 +37,13 @@
public DataUsagePreference(Context context, AttributeSet attrs) {
super(context, attrs);
- if (InstrumentedPreferenceFragment.usePreferenceScreenTitle()) {
- final TypedArray a = context.obtainStyledAttributes(
- attrs, new int[] { com.android.internal.R.attr.title },
- TypedArrayUtils.getAttr(
- context, android.support.v7.preference.R.attr.preferenceStyle,
- android.R.attr.preferenceStyle), 0);
- mTitleRes = a.getResourceId(0, 0);
- a.recycle();
- }
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, new int[] { com.android.internal.R.attr.title },
+ TypedArrayUtils.getAttr(
+ context, android.support.v7.preference.R.attr.preferenceStyle,
+ android.R.attr.preferenceStyle), 0);
+ mTitleRes = a.getResourceId(0, 0);
+ a.recycle();
}
@Override
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccess.java b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
index 2bf2e01..be289b2 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccess.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
@@ -59,9 +59,6 @@
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setAnimationAllowed(true);
- if (!usePreferenceScreenTitle()) {
- addPreferencesFromResource(R.xml.unrestricted_data_access_settings);
- }
mApplicationsState = ApplicationsState.getInstance(
(Application) getContext().getApplicationContext());
mDataSaverBackend = new DataSaverBackend(getContext());
diff --git a/src/com/android/settings/datetime/ZonePicker.java b/src/com/android/settings/datetime/ZonePicker.java
index 00a77df..57c340c 100644
--- a/src/com/android/settings/datetime/ZonePicker.java
+++ b/src/com/android/settings/datetime/ZonePicker.java
@@ -22,6 +22,7 @@
import android.app.ListFragment;
import android.content.Context;
import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -34,11 +35,11 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
-import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.instrumentation.Instrumentable;
import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
import com.android.settingslib.datetime.ZoneGetter;
+import java.text.Collator;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -165,9 +166,7 @@
// Sets the adapter
setSorting(true);
setHasOptionsMenu(true);
- if (InstrumentedPreferenceFragment.usePreferenceScreenTitle()) {
- activity.setTitle(R.string.date_time_set_timezone);
- }
+ activity.setTitle(R.string.date_time_set_timezone);
}
@Override
@@ -261,15 +260,21 @@
mVisibilityLoggerMixin.onPause();
}
- private static class MyComparator implements Comparator<Map<?, ?>> {
+ @VisibleForTesting
+ static class MyComparator implements Comparator<Map<?, ?>> {
+ private final Collator mCollator;
private String mSortingKey;
+ private boolean mSortedByName;
public MyComparator(String sortingKey) {
+ mCollator = Collator.getInstance();
mSortingKey = sortingKey;
+ mSortedByName = ZoneGetter.KEY_DISPLAY_LABEL.equals(sortingKey);
}
public void setSortingKey(String sortingKey) {
mSortingKey = sortingKey;
+ mSortedByName = ZoneGetter.KEY_DISPLAY_LABEL.equals(sortingKey);
}
public int compare(Map<?, ?> map1, Map<?, ?> map2) {
@@ -286,7 +291,11 @@
return -1;
}
- return ((Comparable) value1).compareTo(value2);
+ if (mSortedByName) {
+ return mCollator.compare(value1, value2);
+ } else {
+ return ((Comparable) value1).compareTo(value2);
+ }
}
private boolean isComparable(Object value) {
diff --git a/src/com/android/settings/development/CameraHalHdrplusPreferenceController.java b/src/com/android/settings/development/CameraHalHdrplusPreferenceController.java
deleted file mode 100644
index a5390cc..0000000
--- a/src/com/android/settings/development/CameraHalHdrplusPreferenceController.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.Context;
-import android.os.SystemProperties;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-import android.widget.Toast;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
-
-/**
- * deprecated in favor of {@link CameraHalHdrPlusPreferenceControllerV2}
- */
-@Deprecated
-public class CameraHalHdrplusPreferenceController extends AbstractPreferenceController
- implements PreferenceControllerMixin {
-
- private static final String KEY_CAMERA_HAL_HDRPLUS_SWITCH = "camera_hal_hdrplus_switch";
- @VisibleForTesting
- static final String BUILD_TYPE = "ro.build.type";
- @VisibleForTesting
- static final String PROPERTY_CAMERA_HAL_HDRPLUS = "persist.camera.hdrplus.enable";
- @VisibleForTesting
- static final String ENABLED = "1";
- @VisibleForTesting
- static final String DISABLED = "0";
-
- private SwitchPreference mPreference;
-
- public CameraHalHdrplusPreferenceController(Context context) {
- super(context);
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- if (isAvailable()) {
- mPreference = (SwitchPreference) screen.findPreference(KEY_CAMERA_HAL_HDRPLUS_SWITCH);
- mPreference.setChecked(isHalHdrplusEnabled());
- }
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_CAMERA_HAL_HDRPLUS_SWITCH;
- }
-
- @Override
- public boolean isAvailable() {
- return mContext.getResources().getBoolean(R.bool.config_show_camera_hal_hdrplus);
- }
-
- @Override
- public void updateState(Preference preference) {
- updatePreference();
- }
-
- @Override
- public boolean handlePreferenceTreeClick(Preference preference) {
- if (KEY_CAMERA_HAL_HDRPLUS_SWITCH.equals(preference.getKey())) {
- final SwitchPreference switchPreference = (SwitchPreference)preference;
- SystemProperties.set(PROPERTY_CAMERA_HAL_HDRPLUS,
- switchPreference.isChecked() ? ENABLED : DISABLED);
- Toast.makeText(mContext, R.string.camera_hal_hdrplus_toast,
- Toast.LENGTH_LONG).show();
- return true;
- }
- return false;
- }
-
- public void enablePreference(boolean enabled) {
- if (isAvailable()) {
- mPreference.setEnabled(enabled);
- }
- }
-
- public boolean updatePreference() {
- if (!isAvailable()) {
- return false;
- }
- final boolean enabled = isHalHdrplusEnabled();
- mPreference.setChecked(enabled);
- return enabled;
- }
-
- private boolean isHalHdrplusEnabled() {
- return SystemProperties.getBoolean(PROPERTY_CAMERA_HAL_HDRPLUS, true);
- }
-}
diff --git a/src/com/android/settings/development/CameraHalHdrplusPreferenceControllerV2.java b/src/com/android/settings/development/CameraHalHdrplusPreferenceControllerV2.java
deleted file mode 100644
index b8828fe..0000000
--- a/src/com/android/settings/development/CameraHalHdrplusPreferenceControllerV2.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.Context;
-import android.os.SystemProperties;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-import android.text.TextUtils;
-import android.widget.Toast;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.development.DeveloperOptionsPreferenceController;
-
-public class CameraHalHdrplusPreferenceControllerV2 extends
- DeveloperOptionsPreferenceController implements
- Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
-
- private static final String KEY_CAMERA_HAL_HDRPLUS_SWITCH = "camera_hal_hdrplus_switch";
- @VisibleForTesting
- static final String BUILD_TYPE = "ro.build.type";
- @VisibleForTesting
- static final String PROPERTY_CAMERA_HAL_HDRPLUS = "persist.camera.hdrplus.enable";
- @VisibleForTesting
- static final String ENABLED = "1";
- @VisibleForTesting
- static final String DISABLED = "0";
-
- private SwitchPreference mPreference;
-
- public CameraHalHdrplusPreferenceControllerV2(Context context) {
- super(context);
- }
-
- @Override
- public boolean isAvailable() {
- final String buildType = SystemProperties.get(BUILD_TYPE);
-
- return mContext.getResources().getBoolean(R.bool.config_show_camera_hal_hdrplus);
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_CAMERA_HAL_HDRPLUS_SWITCH;
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
-
- mPreference = (SwitchPreference) screen.findPreference(getPreferenceKey());
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final boolean isEnabled = (Boolean) newValue;
- SystemProperties.set(PROPERTY_CAMERA_HAL_HDRPLUS, isEnabled ? ENABLED : DISABLED);
- Toast.makeText(mContext, R.string.camera_hal_hdrplus_toast, Toast.LENGTH_LONG).show();
- return true;
- }
-
- @Override
- public void updateState(Preference preference) {
- final boolean enabled = isHalHdrplusEnabled();
- mPreference.setChecked(enabled);
- }
-
- @Override
- protected void onDeveloperOptionsSwitchEnabled() {
- mPreference.setEnabled(true);
- }
-
- @Override
- protected void onDeveloperOptionsSwitchDisabled() {
- SystemProperties.set(PROPERTY_CAMERA_HAL_HDRPLUS, DISABLED);
- mPreference.setChecked(false);
- mPreference.setEnabled(false);
- }
-
- private boolean isHalHdrplusEnabled() {
- return SystemProperties.getBoolean(PROPERTY_CAMERA_HAL_HDRPLUS, true /* default */);
- }
-}
diff --git a/src/com/android/settings/development/DevelopmentSettings.java b/src/com/android/settings/development/DevelopmentSettings.java
index 558ebcf..4745023 100644
--- a/src/com/android/settings/development/DevelopmentSettings.java
+++ b/src/com/android/settings/development/DevelopmentSettings.java
@@ -336,7 +336,6 @@
private BugReportPreferenceController mBugReportController;
private BugReportInPowerPreferenceController mBugReportInPowerController;
private ConnectivityMonitorPreferenceController mConnectivityMonitorController;
- private CameraHalHdrplusPreferenceController mCameraHalHdrplusController;
private CameraLaserSensorPreferenceController mCameraLaserSensorController;
private BroadcastReceiver mEnableAdbReceiver;
@@ -384,7 +383,6 @@
mLogpersistController = new LogpersistPreferenceController(getActivity(), getLifecycle());
mWebViewAppPrefController = new WebViewAppPreferenceController(getActivity());
mVerifyAppsOverUsbController = new VerifyAppsOverUsbPreferenceController(getActivity());
- mCameraHalHdrplusController = new CameraHalHdrplusPreferenceController(getActivity());
mCameraLaserSensorController = new CameraLaserSensorPreferenceController(getActivity());
setIfOnlyAvailableForAdmins(true);
@@ -396,7 +394,7 @@
return;
}
- addPreferencesFromResource(R.xml.development_prefs);
+ addPreferencesFromResource(R.xml.development_settings);
final PreferenceScreen preferenceScreen = getPreferenceScreen();
final PreferenceGroup debugDebuggingCategory = (PreferenceGroup)
@@ -421,7 +419,6 @@
mLogdSizeController.displayPreference(preferenceScreen);
mLogpersistController.displayPreference(preferenceScreen);
mWebViewAppPrefController.displayPreference(preferenceScreen);
- mCameraHalHdrplusController.displayPreference(preferenceScreen);
mEnableAdbController.displayPreference(preferenceScreen);
mCameraLaserSensorController.displayPreference(getPreferenceScreen());
@@ -646,7 +643,6 @@
mLogdSizeController.enablePreference(enabled);
mLogpersistController.enablePreference(enabled);
mWebViewAppPrefController.enablePreference(enabled);
- mCameraHalHdrplusController.enablePreference(enabled);
mCameraLaserSensorController.enablePreference(enabled);
updateAllOptions();
}
@@ -793,7 +789,6 @@
}
mHaveDebugSettings |= mBugReportInPowerController.updatePreference();
mHaveDebugSettings |= mConnectivityMonitorController.updatePreference();
- mHaveDebugSettings |= mCameraHalHdrplusController.updatePreference();
mHaveDebugSettings |= mCameraLaserSensorController.updatePreference();
updateSwitchPreference(mKeepScreenOn, Settings.Global.getInt(cr,
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
@@ -2260,10 +2255,6 @@
return true;
}
- if (mCameraHalHdrplusController.handlePreferenceTreeClick(preference)) {
- return true;
- }
-
if (mEnableAdbController.handlePreferenceTreeClick(preference)) {
return true;
}
@@ -2596,7 +2587,7 @@
Context context, boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.development_prefs;
+ sir.xmlResId = R.xml.development_settings;
return Arrays.asList(sir);
}
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 83f395f..025e35e 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -135,6 +135,15 @@
}
@Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ if (Utils.isMonkeyRunning()) {
+ getActivity().finish();
+ return;
+ }
+ }
+
+ @Override
public void onActivityCreated(Bundle icicle) {
super.onActivityCreated(icicle);
// Apply page-level restrictions
@@ -290,7 +299,7 @@
@Override
protected int getPreferenceScreenResId() {
Log.d(TAG, "Creating pref screen");
- return R.xml.development_prefs;
+ return R.xml.development_settings;
}
@Override
@@ -377,7 +386,6 @@
controllers.add(new LogPersistPreferenceControllerV2(context, fragment, lifecycle));
controllers.add(new ConnectivityMonitorPreferenceControllerV2(context));
controllers.add(new CameraLaserSensorPreferenceControllerV2(context));
- controllers.add(new CameraHalHdrplusPreferenceControllerV2(context));
controllers.add(new WifiDisplayCertificationPreferenceController(context));
controllers.add(new WifiVerboseLoggingPreferenceController(context));
controllers.add(new WifiAggressiveHandoverPreferenceController(context));
@@ -452,7 +460,7 @@
Context context, boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.development_prefs;
+ sir.xmlResId = R.xml.development_settings;
return Arrays.asList(sir);
}
diff --git a/src/com/android/settings/development/featureflags/FeatureFlagPreference.java b/src/com/android/settings/development/featureflags/FeatureFlagPreference.java
index 80851d3..7da1826 100644
--- a/src/com/android/settings/development/featureflags/FeatureFlagPreference.java
+++ b/src/com/android/settings/development/featureflags/FeatureFlagPreference.java
@@ -29,7 +29,7 @@
mKey = key;
setKey(key);
setTitle(key);
- setCheckedInternal(FeatureFlagUtils.isEnabled(mKey));
+ setCheckedInternal(FeatureFlagUtils.isEnabled(context, mKey));
}
@Override
diff --git a/src/com/android/settings/deviceinfo/BasebandVersionPreferenceController.java b/src/com/android/settings/deviceinfo/BasebandVersionPreferenceController.java
index 90d4c11..06ed872 100644
--- a/src/com/android/settings/deviceinfo/BasebandVersionPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/BasebandVersionPreferenceController.java
@@ -21,9 +21,14 @@
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.deviceinfo.firmwareversion.BasebandVersionDialogController;
import com.android.settingslib.Utils;
import com.android.settingslib.core.AbstractPreferenceController;
+/**
+ * deprecated in favor of {@link BasebandVersionDialogController}
+ */
+@Deprecated
public class BasebandVersionPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin {
diff --git a/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java b/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
index e7fab5a..7934ad7 100644
--- a/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
@@ -23,8 +23,8 @@
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
-import com.android.settings.DeviceInfoSettings;
import com.android.settings.R;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.DeviceInfoUtils;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -51,7 +51,7 @@
super.displayPreference(screen);
final Preference pref = screen.findPreference(KEY_DEVICE_MODEL);
if (pref != null) {
- if (FeatureFlagUtils.isEnabled(DeviceInfoSettings.DEVICE_INFO_V2_FEATURE_FLAG)) {
+ if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.DEVICE_INFO_V2)) {
pref.setSummary(mContext.getResources().getString(R.string.model_summary,
getDeviceModel()));
} else {
diff --git a/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java b/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java
index 3d825b9..26f1ac2 100644
--- a/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java
+++ b/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java
@@ -29,8 +29,8 @@
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.DeviceInfoSettings;
import com.android.settings.R;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
public class HardwareInfoDialogFragment extends InstrumentedDialogFragment {
@@ -59,7 +59,7 @@
DeviceModelPreferenceController.getDeviceModel());
// Serial number
- if (FeatureFlagUtils.isEnabled(DeviceInfoSettings.DEVICE_INFO_V2_FEATURE_FLAG)) {
+ if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DEVICE_INFO_V2)) {
setText(content, R.id.serial_number_label, R.id.serial_number_value, getSerialNumber());
} else {
content.findViewById(R.id.serial_number_label).setVisibility(View.GONE);
@@ -73,7 +73,7 @@
return builder.setView(content).create();
}
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ @VisibleForTesting
void setText(View content, int labelViewId, int valueViewId, String value) {
if (content == null) {
return;
diff --git a/src/com/android/settings/deviceinfo/KernelVersionPreferenceController.java b/src/com/android/settings/deviceinfo/KernelVersionPreferenceController.java
index 5afed9c..f3b98ed 100644
--- a/src/com/android/settings/deviceinfo/KernelVersionPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/KernelVersionPreferenceController.java
@@ -39,7 +39,7 @@
@Override
public void updateState(Preference preference) {
super.updateState(preference);
- preference.setSummary(DeviceInfoUtils.getFormattedKernelVersion());
+ preference.setSummary(DeviceInfoUtils.getFormattedKernelVersion(mContext));
}
@Override
diff --git a/src/com/android/settings/deviceinfo/SecurityPatchPreferenceController.java b/src/com/android/settings/deviceinfo/SecurityPatchPreferenceController.java
index f38602a..9b0120e 100644
--- a/src/com/android/settings/deviceinfo/SecurityPatchPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/SecurityPatchPreferenceController.java
@@ -23,9 +23,14 @@
import android.util.Log;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.deviceinfo.firmwareversion.SecurityPatchLevelDialogController;
import com.android.settingslib.DeviceInfoUtils;
import com.android.settingslib.core.AbstractPreferenceController;
+/**
+ * deprecated in favor of {@link SecurityPatchLevelDialogController}
+ */
+@Deprecated
public class SecurityPatchPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin {
diff --git a/src/com/android/settings/deviceinfo/StorageWizardBase.java b/src/com/android/settings/deviceinfo/StorageWizardBase.java
index c7bea30..c2ea2d2 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardBase.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardBase.java
@@ -16,15 +16,19 @@
package com.android.settings.deviceinfo;
+import static com.android.settings.deviceinfo.StorageSettings.TAG;
+
import android.annotation.LayoutRes;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
+import android.os.SystemClock;
import android.os.storage.DiskInfo;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.text.TextUtils;
+import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
@@ -202,13 +206,27 @@
}
protected VolumeInfo findFirstVolume(int type) {
- final List<VolumeInfo> vols = mStorage.getVolumes();
- for (VolumeInfo vol : vols) {
- if (Objects.equals(mDisk.getId(), vol.getDiskId()) && (vol.getType() == type)) {
- return vol;
+ return findFirstVolume(type, 1);
+ }
+
+ protected VolumeInfo findFirstVolume(int type, int attempts) {
+ while (true) {
+ final List<VolumeInfo> vols = mStorage.getVolumes();
+ for (VolumeInfo vol : vols) {
+ if (Objects.equals(mDisk.getId(), vol.getDiskId()) && (vol.getType() == type)
+ && (vol.getState() == VolumeInfo.STATE_MOUNTED)) {
+ return vol;
+ }
+ }
+
+ if (--attempts > 0) {
+ Log.w(TAG, "Missing mounted volume of type " + type + " hosted by disk "
+ + mDisk.getId() + "; trying again");
+ SystemClock.sleep(250);
+ } else {
+ return null;
}
}
- return null;
}
private final StorageEventListener mStorageListener = new StorageEventListener() {
diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
index 59a1866..3dfc74b 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
@@ -16,15 +16,20 @@
package com.android.settings.deviceinfo;
+import static android.os.storage.VolumeInfo.TYPE_PRIVATE;
+
+import static com.android.settings.deviceinfo.StorageSettings.TAG;
+
import android.app.AlertDialog;
import android.app.Dialog;
-import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.IPackageMoveObserver;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.IVoldTaskListener;
+import android.os.PersistableBundle;
import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
@@ -38,8 +43,8 @@
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import java.util.Objects;
-
-import static com.android.settings.deviceinfo.StorageSettings.TAG;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
public class StorageWizardFormatProgress extends StorageWizardBase {
private static final String TAG_SLOW_WARNING = "slow_warning";
@@ -99,9 +104,21 @@
storage.partitionPrivate(activity.mDisk.getId());
publishProgress(40);
- final VolumeInfo privateVol = activity.findFirstVolume(VolumeInfo.TYPE_PRIVATE);
- mPrivateBench = storage.benchmark(privateVol.getId());
- mPrivateBench /= 1000000;
+ final VolumeInfo privateVol = activity.findFirstVolume(TYPE_PRIVATE, 5);
+ final CompletableFuture<PersistableBundle> result = new CompletableFuture<>();
+ storage.benchmark(privateVol.getId(), new IVoldTaskListener.Stub() {
+ @Override
+ public void onStatus(int status, PersistableBundle extras) {
+ // Map benchmark 0-100% progress onto 40-80%
+ publishProgress(40 + ((status * 40) / 100));
+ }
+
+ @Override
+ public void onFinished(int status, PersistableBundle extras) {
+ result.complete(extras);
+ }
+ });
+ mPrivateBench = result.get(60, TimeUnit.SECONDS).getLong("run", Long.MAX_VALUE);
// If we just adopted the device that had been providing
// physical storage, then automatically move storage to the
diff --git a/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java b/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java
index d2ad6d8..d8a64a8 100644
--- a/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java
@@ -15,6 +15,8 @@
*/
package com.android.settings.deviceinfo;
+import static android.content.Context.CARRIER_CONFIG_SERVICE;
+
import android.content.Context;
import android.content.Intent;
import android.os.Build;
@@ -31,8 +33,6 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
-import static android.content.Context.CARRIER_CONFIG_SERVICE;
-
public class SystemUpdatePreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin {
@@ -59,12 +59,11 @@
@Override
public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
if (isAvailable()) {
Utils.updatePreferenceToSpecificActivityOrRemove(mContext, screen,
KEY_SYSTEM_UPDATE_SETTINGS,
Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
- } else {
- removePreference(screen, KEY_SYSTEM_UPDATE_SETTINGS);
}
}
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionDialogController.java b/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionDialogController.java
new file mode 100644
index 0000000..c857f19
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionDialogController.java
@@ -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.firmwareversion;
+
+import android.content.Context;
+import android.os.SystemProperties;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+
+public class BasebandVersionDialogController {
+
+ @VisibleForTesting
+ static final int BASEBAND_VERSION_LABEL_ID = R.id.baseband_version_label;
+ @VisibleForTesting
+ static final int BASEBAND_VERSION_VALUE_ID = R.id.baseband_version_value;
+ @VisibleForTesting
+ static final String BASEBAND_PROPERTY = "gsm.version.baseband";
+
+ private final FirmwareVersionDialogFragment mDialog;
+
+ public BasebandVersionDialogController(FirmwareVersionDialogFragment dialog) {
+ mDialog = dialog;
+ }
+
+ /**
+ * Updates the baseband version field of the dialog.
+ */
+ public void initialize() {
+ final Context context = mDialog.getContext();
+ if (Utils.isWifiOnly(context)) {
+ mDialog.removeSettingFromScreen(BASEBAND_VERSION_LABEL_ID);
+ mDialog.removeSettingFromScreen(BASEBAND_VERSION_VALUE_ID);
+ return;
+ }
+
+ mDialog.setText(BASEBAND_VERSION_VALUE_ID, SystemProperties.get(BASEBAND_PROPERTY,
+ context.getString(R.string.device_info_default)));
+ }
+}
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/BuildNumberDialogController.java b/src/com/android/settings/deviceinfo/firmwareversion/BuildNumberDialogController.java
new file mode 100644
index 0000000..d995867
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/BuildNumberDialogController.java
@@ -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.deviceinfo.firmwareversion;
+
+import android.os.Build;
+import android.support.annotation.VisibleForTesting;
+import android.text.BidiFormatter;
+
+import com.android.settings.R;
+
+public class BuildNumberDialogController {
+
+ @VisibleForTesting
+ static final int BUILD_NUMBER_VALUE_ID = R.id.build_number_value;
+
+ private final FirmwareVersionDialogFragment mDialog;
+
+ public BuildNumberDialogController(FirmwareVersionDialogFragment dialog) {
+ mDialog = dialog;
+ }
+
+ /**
+ * Updates the build number to the dialog.
+ */
+ public void initialize() {
+ mDialog.setText(BUILD_NUMBER_VALUE_ID,
+ BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY));
+ }
+}
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogController.java b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogController.java
new file mode 100644
index 0000000..5794e12
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogController.java
@@ -0,0 +1,112 @@
+/*
+ * 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.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settingslib.RestrictedLockUtils;
+
+public class FirmwareVersionDialogController implements View.OnClickListener {
+
+ private static final String TAG = "firmwareDialogCtrl";
+ private static final int DELAY_TIMER_MILLIS = 500;
+ private static final int ACTIVITY_TRIGGER_COUNT = 3;
+
+ @VisibleForTesting
+ static final int FIRMWARE_VERSION_VALUE_ID = R.id.firmware_version_value;
+ @VisibleForTesting
+ static final int FIRMWARE_VERSION_LABEL_ID = R.id.firmware_version_label;
+
+ private final FirmwareVersionDialogFragment mDialog;
+ private final Context mContext;
+ private final UserManager mUserManager;
+ private final long[] mHits = new long[ACTIVITY_TRIGGER_COUNT];
+
+ private RestrictedLockUtils.EnforcedAdmin mFunDisallowedAdmin;
+ private boolean mFunDisallowedBySystem;
+
+ public FirmwareVersionDialogController(FirmwareVersionDialogFragment dialog) {
+ mDialog = dialog;
+ mContext = dialog.getContext();
+ mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ }
+
+ @Override
+ public void onClick(View v) {
+ arrayCopy();
+ mHits[mHits.length - 1] = SystemClock.uptimeMillis();
+ if (mHits[0] >= (SystemClock.uptimeMillis() - DELAY_TIMER_MILLIS)) {
+ if (mUserManager.hasUserRestriction(UserManager.DISALLOW_FUN)) {
+ if (mFunDisallowedAdmin != null && !mFunDisallowedBySystem) {
+ RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext,
+ mFunDisallowedAdmin);
+ }
+ Log.d(TAG, "Sorry, no fun for you!");
+ return;
+ }
+
+ final Intent intent = new Intent(Intent.ACTION_MAIN)
+ .setClassName(
+ "android", com.android.internal.app.PlatLogoActivity.class.getName());
+ try {
+ mContext.startActivity(intent);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to start activity " + intent.toString());
+ }
+ }
+ }
+
+ /**
+ * Populates the Android version field in the dialog and registers click listeners.
+ */
+ public void initialize() {
+ initializeAdminPermissions();
+ registerClickListeners();
+
+ mDialog.setText(FIRMWARE_VERSION_VALUE_ID, Build.VERSION.RELEASE);
+ }
+
+ private void registerClickListeners() {
+ mDialog.registerClickListener(FIRMWARE_VERSION_LABEL_ID, this /* listener */);
+ mDialog.registerClickListener(FIRMWARE_VERSION_VALUE_ID, this /* listener */);
+ }
+
+ /**
+ * Copies the array onto itself to remove the oldest hit.
+ */
+ @VisibleForTesting
+ void arrayCopy() {
+ System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
+ }
+
+ @VisibleForTesting
+ void initializeAdminPermissions() {
+ mFunDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_FUN, UserHandle.myUserId());
+ mFunDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(
+ mContext, UserManager.DISALLOW_FUN, UserHandle.myUserId());
+ }
+}
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogFragment.java b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogFragment.java
index 3af21a9..0087444 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogFragment.java
+++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogFragment.java
@@ -23,6 +23,7 @@
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@@ -32,6 +33,8 @@
private static final String TAG = "firmwareVersionDialog";
+ private View mRootView;
+
public static void show(Fragment host) {
final FragmentManager manager = host.getChildFragmentManager();
if (manager.findFragmentByTag(TAG) == null) {
@@ -51,9 +54,40 @@
.setTitle(R.string.firmware_title)
.setPositiveButton(android.R.string.ok, null /* listener */);
- final View view = LayoutInflater.from(getActivity()).inflate(
+ mRootView = LayoutInflater.from(getActivity()).inflate(
R.layout.dialog_firmware_version, null /* parent */);
- return builder.setView(view).create();
+ initializeControllers();
+
+ return builder.setView(mRootView).create();
+ }
+
+ public void setText(int viewId, CharSequence text) {
+ final TextView view = mRootView.findViewById(viewId);
+ if (view != null) {
+ view.setText(text);
+ }
+ }
+
+ public void removeSettingFromScreen(int viewId) {
+ final View view = mRootView.findViewById(viewId);
+ if (view != null) {
+ view.setVisibility(View.GONE);
+ }
+ }
+
+ public void registerClickListener(int viewId, View.OnClickListener listener) {
+ final View view = mRootView.findViewById(viewId);
+ if (view != null) {
+ view.setOnClickListener(listener);
+ }
+ }
+
+ private void initializeControllers() {
+ new FirmwareVersionDialogController(this).initialize();
+ new SecurityPatchLevelDialogController(this).initialize();
+ new BasebandVersionDialogController(this).initialize();
+ new KernelVersionDialogController(this).initialize();
+ new BuildNumberDialogController(this).initialize();
}
}
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionDialogController.java b/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionDialogController.java
new file mode 100644
index 0000000..d583e04
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionDialogController.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.firmwareversion;
+
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.R;
+import com.android.settingslib.DeviceInfoUtils;
+
+public class KernelVersionDialogController {
+
+ @VisibleForTesting
+ static int KERNEL_VERSION_VALUE_ID = R.id.kernel_version_value;
+
+ private final FirmwareVersionDialogFragment mDialog;
+
+ public KernelVersionDialogController(FirmwareVersionDialogFragment dialog) {
+ mDialog = dialog;
+ }
+
+ /**
+ * Updates kernel version to the dialog.
+ */
+ public void initialize() {
+ mDialog.setText(KERNEL_VERSION_VALUE_ID,
+ DeviceInfoUtils.getFormattedKernelVersion(mDialog.getContext()));
+ }
+}
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelDialogController.java b/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelDialogController.java
new file mode 100644
index 0000000..01f440d
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelDialogController.java
@@ -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.deviceinfo.firmwareversion;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settingslib.DeviceInfoUtils;
+import com.android.settingslib.wrapper.PackageManagerWrapper;
+
+public class SecurityPatchLevelDialogController implements View.OnClickListener {
+
+ private static final String TAG = "SecurityPatchCtrl";
+ private static final Uri INTENT_URI_DATA = Uri.parse(
+ "https://source.android.com/security/bulletin/");
+
+ @VisibleForTesting
+ static final int SECURITY_PATCH_VALUE_ID = R.id.security_patch_level_value;
+ @VisibleForTesting
+ static final int SECURITY_PATCH_LABEL_ID = R.id.security_patch_level_label;
+
+ private final FirmwareVersionDialogFragment mDialog;
+ private final Context mContext;
+ private final PackageManagerWrapper mPackageManager;
+ private final String mCurrentPatch;
+
+ public SecurityPatchLevelDialogController(FirmwareVersionDialogFragment dialog) {
+ mDialog = dialog;
+ mContext = dialog.getContext();
+ mPackageManager = new PackageManagerWrapper(mContext.getPackageManager());
+ mCurrentPatch = DeviceInfoUtils.getSecurityPatch();
+ }
+
+ @Override
+ public void onClick(View v) {
+ final Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.setData(INTENT_URI_DATA);
+ if (mPackageManager.queryIntentActivities(intent, 0).isEmpty()) {
+ // Don't send out the intent to stop crash
+ Log.w(TAG, "Stop click action on " + SECURITY_PATCH_VALUE_ID + ": "
+ + "queryIntentActivities() returns empty");
+ return;
+ }
+
+ mContext.startActivity(intent);
+ }
+
+ /**
+ * Populates the security patch level field in the dialog and registers click listeners.
+ */
+ public void initialize() {
+ if (TextUtils.isEmpty(mCurrentPatch)) {
+ mDialog.removeSettingFromScreen(SECURITY_PATCH_LABEL_ID);
+ mDialog.removeSettingFromScreen(SECURITY_PATCH_VALUE_ID);
+ return;
+ }
+ registerListeners();
+ mDialog.setText(SECURITY_PATCH_VALUE_ID, mCurrentPatch);
+ }
+
+ private void registerListeners() {
+ mDialog.registerClickListener(SECURITY_PATCH_LABEL_ID, this /* listener */);
+ mDialog.registerClickListener(SECURITY_PATCH_VALUE_ID, this /* listener */);
+ }
+}
diff --git a/src/com/android/settings/display/ColorModePreferenceFragment.java b/src/com/android/settings/display/ColorModePreferenceFragment.java
index 9f18fd8..e3fb65d 100644
--- a/src/com/android/settings/display/ColorModePreferenceFragment.java
+++ b/src/com/android/settings/display/ColorModePreferenceFragment.java
@@ -17,7 +17,7 @@
import android.graphics.drawable.Drawable;
import android.support.annotation.VisibleForTesting;
-import com.android.internal.app.NightDisplayController;
+import com.android.internal.app.ColorDisplayController;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@@ -36,12 +36,12 @@
@VisibleForTesting
static final String KEY_COLOR_MODE_SATURATED = "color_mode_saturated";
- private NightDisplayController mController;
+ private ColorDisplayController mController;
@Override
public void onAttach(Context context) {
super.onAttach(context);
- mController = new NightDisplayController(context);
+ mController = new ColorDisplayController(context);
}
@Override
@@ -64,10 +64,10 @@
@Override
protected String getDefaultKey() {
- if (mController.getColorMode() == NightDisplayController.COLOR_MODE_SATURATED) {
+ if (mController.getColorMode() == ColorDisplayController.COLOR_MODE_SATURATED) {
return KEY_COLOR_MODE_SATURATED;
}
- if (mController.getColorMode() == NightDisplayController.COLOR_MODE_BOOSTED) {
+ if (mController.getColorMode() == ColorDisplayController.COLOR_MODE_BOOSTED) {
return KEY_COLOR_MODE_BOOSTED;
}
return KEY_COLOR_MODE_NATURAL;
@@ -77,13 +77,13 @@
protected boolean setDefaultKey(String key) {
switch (key) {
case KEY_COLOR_MODE_NATURAL:
- mController.setColorMode(NightDisplayController.COLOR_MODE_NATURAL);
+ mController.setColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
break;
case KEY_COLOR_MODE_BOOSTED:
- mController.setColorMode(NightDisplayController.COLOR_MODE_BOOSTED);
+ mController.setColorMode(ColorDisplayController.COLOR_MODE_BOOSTED);
break;
case KEY_COLOR_MODE_SATURATED:
- mController.setColorMode(NightDisplayController.COLOR_MODE_SATURATED);
+ mController.setColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
break;
}
return true;
diff --git a/src/com/android/settings/display/NightDisplayPreference.java b/src/com/android/settings/display/NightDisplayPreference.java
index b966530..ea39f75 100644
--- a/src/com/android/settings/display/NightDisplayPreference.java
+++ b/src/com/android/settings/display/NightDisplayPreference.java
@@ -18,7 +18,7 @@
import android.support.v14.preference.SwitchPreference;
import android.util.AttributeSet;
-import com.android.internal.app.NightDisplayController;
+import com.android.internal.app.ColorDisplayController;
import com.android.settings.R;
import java.text.DateFormat;
@@ -27,15 +27,15 @@
import java.util.TimeZone;
public class NightDisplayPreference extends SwitchPreference
- implements NightDisplayController.Callback {
+ implements ColorDisplayController.Callback {
- private NightDisplayController mController;
+ private ColorDisplayController mController;
private DateFormat mTimeFormatter;
public NightDisplayPreference(Context context, AttributeSet attrs) {
super(context, attrs);
- mController = new NightDisplayController(context);
+ mController = new ColorDisplayController(context);
mTimeFormatter = android.text.format.DateFormat.getTimeFormat(context);
mTimeFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
}
@@ -78,12 +78,12 @@
final String autoModeSummary;
switch (autoMode) {
default:
- case NightDisplayController.AUTO_MODE_DISABLED:
+ case ColorDisplayController.AUTO_MODE_DISABLED:
autoModeSummary = context.getString(isActivated
? R.string.night_display_summary_on_auto_mode_never
: R.string.night_display_summary_off_auto_mode_never);
break;
- case NightDisplayController.AUTO_MODE_CUSTOM:
+ case ColorDisplayController.AUTO_MODE_CUSTOM:
if (isActivated) {
autoModeSummary = context.getString(
R.string.night_display_summary_on_auto_mode_custom,
@@ -94,7 +94,7 @@
getFormattedTimeString(mController.getCustomStartTime()));
}
break;
- case NightDisplayController.AUTO_MODE_TWILIGHT:
+ case ColorDisplayController.AUTO_MODE_TWILIGHT:
autoModeSummary = context.getString(isActivated
? R.string.night_display_summary_on_auto_mode_twilight
: R.string.night_display_summary_off_auto_mode_twilight);
diff --git a/src/com/android/settings/display/NightDisplayPreferenceController.java b/src/com/android/settings/display/NightDisplayPreferenceController.java
index f42e324..643f1d4 100644
--- a/src/com/android/settings/display/NightDisplayPreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayPreferenceController.java
@@ -15,7 +15,7 @@
import android.content.Context;
-import com.android.internal.app.NightDisplayController;
+import com.android.internal.app.ColorDisplayController;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -30,7 +30,7 @@
@Override
public boolean isAvailable() {
- return NightDisplayController.isAvailable(mContext);
+ return ColorDisplayController.isAvailable(mContext);
}
@Override
diff --git a/src/com/android/settings/display/NightDisplaySettings.java b/src/com/android/settings/display/NightDisplaySettings.java
index 5879297..ab94720 100644
--- a/src/com/android/settings/display/NightDisplaySettings.java
+++ b/src/com/android/settings/display/NightDisplaySettings.java
@@ -25,7 +25,7 @@
import android.support.v7.preference.TwoStatePreference;
import android.widget.TimePicker;
-import com.android.internal.app.NightDisplayController;
+import com.android.internal.app.ColorDisplayController;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.widget.SeekBarPreference;
@@ -40,7 +40,7 @@
* Settings screen for Night display.
*/
public class NightDisplaySettings extends SettingsPreferenceFragment
- implements NightDisplayController.Callback, Preference.OnPreferenceChangeListener {
+ implements ColorDisplayController.Callback, Preference.OnPreferenceChangeListener {
private static final String KEY_NIGHT_DISPLAY_AUTO_MODE = "night_display_auto_mode";
private static final String KEY_NIGHT_DISPLAY_START_TIME = "night_display_start_time";
@@ -51,7 +51,7 @@
private static final int DIALOG_START_TIME = 0;
private static final int DIALOG_END_TIME = 1;
- private NightDisplayController mController;
+ private ColorDisplayController mController;
private DateFormat mTimeFormatter;
private DropDownPreference mAutoModePreference;
@@ -65,7 +65,7 @@
super.onCreate(savedInstanceState);
final Context context = getContext();
- mController = new NightDisplayController(context);
+ mController = new ColorDisplayController(context);
mTimeFormatter = android.text.format.DateFormat.getTimeFormat(context);
mTimeFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
@@ -98,9 +98,9 @@
getString(R.string.night_display_auto_mode_twilight)
});
mAutoModePreference.setEntryValues(new CharSequence[] {
- String.valueOf(NightDisplayController.AUTO_MODE_DISABLED),
- String.valueOf(NightDisplayController.AUTO_MODE_CUSTOM),
- String.valueOf(NightDisplayController.AUTO_MODE_TWILIGHT)
+ String.valueOf(ColorDisplayController.AUTO_MODE_DISABLED),
+ String.valueOf(ColorDisplayController.AUTO_MODE_CUSTOM),
+ String.valueOf(ColorDisplayController.AUTO_MODE_TWILIGHT)
});
mAutoModePreference.setOnPreferenceChangeListener(this);
mActivatedPreference.setOnPreferenceChangeListener(this);
@@ -192,7 +192,7 @@
public void onAutoModeChanged(int autoMode) {
mAutoModePreference.setValue(String.valueOf(autoMode));
- final boolean showCustomSchedule = autoMode == NightDisplayController.AUTO_MODE_CUSTOM;
+ final boolean showCustomSchedule = autoMode == ColorDisplayController.AUTO_MODE_CUSTOM;
mStartTimePreference.setVisible(showCustomSchedule);
mEndTimePreference.setVisible(showCustomSchedule);
}
diff --git a/src/com/android/settings/display/NightModePreferenceController.java b/src/com/android/settings/display/NightModePreferenceController.java
index 7e9701b..96ef938 100644
--- a/src/com/android/settings/display/NightModePreferenceController.java
+++ b/src/com/android/settings/display/NightModePreferenceController.java
@@ -13,6 +13,8 @@
*/
package com.android.settings.display;
+import static android.content.Context.UI_MODE_SERVICE;
+
import android.app.UiModeManager;
import android.content.Context;
import android.support.v7.preference.ListPreference;
@@ -23,8 +25,6 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
-import static android.content.Context.UI_MODE_SERVICE;
-
public class NightModePreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
@@ -48,7 +48,7 @@
@Override
public void displayPreference(PreferenceScreen screen) {
if (!isAvailable()) {
- removePreference(screen, KEY_NIGHT_MODE);
+ setVisible(screen, KEY_NIGHT_MODE, false /* visible */);
return;
}
ListPreference mNightModePreference = (ListPreference) screen.findPreference(
diff --git a/src/com/android/settings/display/ScreenZoomSettings.java b/src/com/android/settings/display/ScreenZoomSettings.java
index f9a23c7..a77782f 100644
--- a/src/com/android/settings/display/ScreenZoomSettings.java
+++ b/src/com/android/settings/display/ScreenZoomSettings.java
@@ -71,9 +71,7 @@
mDefaultDensity = density.getDefaultDensity();
}
- if (usePreferenceScreenTitle()) {
- getActivity().setTitle(R.string.screen_zoom_title);
- }
+ getActivity().setTitle(R.string.screen_zoom_title);
}
@Override
diff --git a/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceController.java b/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceController.java
index be41e4d..6b4e70d 100644
--- a/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceController.java
+++ b/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceController.java
@@ -17,18 +17,14 @@
import android.Manifest;
import android.content.Context;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
public class AdminGrantedCameraPermissionPreferenceController extends
AdminGrantedPermissionsPreferenceControllerBase {
private static final String KEY_ENTERPRISE_PRIVACY_NUMBER_CAMERA_ACCESS_PACKAGES
= "enterprise_privacy_number_camera_access_packages";
- public AdminGrantedCameraPermissionPreferenceController(Context context, Lifecycle lifecycle,
- boolean async) {
- super(context, lifecycle, async, new String[] {Manifest.permission.CAMERA},
- Manifest.permission_group.CAMERA);
+ public AdminGrantedCameraPermissionPreferenceController(Context context, boolean async) {
+ super(context, async, new String[] {Manifest.permission.CAMERA});
}
@Override
diff --git a/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceController.java b/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceController.java
index 77c6040..5c6dfc2 100644
--- a/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceController.java
+++ b/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceController.java
@@ -17,18 +17,15 @@
import android.Manifest;
import android.content.Context;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
public class AdminGrantedLocationPermissionsPreferenceController extends
AdminGrantedPermissionsPreferenceControllerBase {
private static final String KEY_ENTERPRISE_PRIVACY_NUMBER_LOCATION_ACCESS_PACKAGES
= "enterprise_privacy_number_location_access_packages";
- public AdminGrantedLocationPermissionsPreferenceController(Context context, Lifecycle lifecycle,
- boolean async) {
- super(context, lifecycle, async, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION}, Manifest.permission_group.LOCATION);
+ public AdminGrantedLocationPermissionsPreferenceController(Context context, boolean async) {
+ super(context, async, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION});
}
@Override
diff --git a/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceController.java b/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceController.java
index 9896420..74e260a 100644
--- a/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceController.java
+++ b/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceController.java
@@ -17,18 +17,14 @@
import android.Manifest;
import android.content.Context;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
public class AdminGrantedMicrophonePermissionPreferenceController extends
AdminGrantedPermissionsPreferenceControllerBase {
private static final String KEY_ENTERPRISE_PRIVACY_NUMBER_MICROPHONE_ACCESS_PACKAGES
= "enterprise_privacy_number_microphone_access_packages";
- public AdminGrantedMicrophonePermissionPreferenceController(Context context,
- Lifecycle lifecycle, boolean async) {
- super(context, lifecycle, async, new String[] {Manifest.permission.RECORD_AUDIO},
- Manifest.permission_group.MICROPHONE);
+ public AdminGrantedMicrophonePermissionPreferenceController(Context context, boolean async) {
+ super(context, async, new String[] {Manifest.permission.RECORD_AUDIO});
}
@Override
diff --git a/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBase.java b/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBase.java
index 9187cec..dd5ab34 100644
--- a/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBase.java
+++ b/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBase.java
@@ -20,24 +20,22 @@
import com.android.settings.R;
import com.android.settings.applications.ApplicationFeatureProvider;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.AbstractPreferenceController;
public abstract class AdminGrantedPermissionsPreferenceControllerBase
- extends DynamicAvailabilityPreferenceController {
+ extends AbstractPreferenceController implements PreferenceControllerMixin {
private final String[] mPermissions;
- private final String mPermissionGroup;
private final ApplicationFeatureProvider mFeatureProvider;
private final boolean mAsync;
private boolean mHasApps;
- public AdminGrantedPermissionsPreferenceControllerBase(Context context, Lifecycle lifecycle,
- boolean async, String[] permissions, String permissionGroup) {
- super(context, lifecycle);
+ public AdminGrantedPermissionsPreferenceControllerBase(Context context, boolean async,
+ String[] permissions) {
+ super(context);
mPermissions = permissions;
- mPermissionGroup = permissionGroup;
mFeatureProvider = FeatureFactory.getFactory(context)
.getApplicationFeatureProvider(context);
mAsync = async;
@@ -58,7 +56,6 @@
mHasApps = true;
}
preference.setVisible(mHasApps);
- notifyOnAvailabilityUpdate(mHasApps);
});
}
@@ -80,7 +77,6 @@
mFeatureProvider.calculateNumberOfAppsWithAdminGrantedPermissions(mPermissions,
false /* async */, (num) -> haveAppsWithAdminGrantedPermissions[0] = num > 0);
mHasApps = haveAppsWithAdminGrantedPermissions[0];
- notifyOnAvailabilityUpdate(mHasApps);
return mHasApps;
}
diff --git a/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceController.java b/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceController.java
index ed91fef..883fd36 100644
--- a/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceController.java
+++ b/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceController.java
@@ -17,18 +17,18 @@
import android.support.v7.preference.Preference;
import com.android.settings.R;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.AbstractPreferenceController;
public class AlwaysOnVpnCurrentUserPreferenceController
- extends DynamicAvailabilityPreferenceController {
+ extends AbstractPreferenceController implements PreferenceControllerMixin {
private static final String KEY_ALWAYS_ON_VPN_PRIMARY_USER = "always_on_vpn_primary_user";
private final EnterprisePrivacyFeatureProvider mFeatureProvider;
- public AlwaysOnVpnCurrentUserPreferenceController(Context context, Lifecycle lifecycle) {
- super(context, lifecycle);
+ public AlwaysOnVpnCurrentUserPreferenceController(Context context) {
+ super(context);
mFeatureProvider = FeatureFactory.getFactory(context)
.getEnterprisePrivacyFeatureProvider(context);
}
@@ -42,9 +42,7 @@
@Override
public boolean isAvailable() {
- final boolean available = mFeatureProvider.isAlwaysOnVpnSetInCurrentUser();
- notifyOnAvailabilityUpdate(available);
- return available;
+ return mFeatureProvider.isAlwaysOnVpnSetInCurrentUser();
}
@Override
diff --git a/src/com/android/settings/enterprise/AlwaysOnVpnManagedProfilePreferenceController.java b/src/com/android/settings/enterprise/AlwaysOnVpnManagedProfilePreferenceController.java
index db6fc1d..a23af0c 100644
--- a/src/com/android/settings/enterprise/AlwaysOnVpnManagedProfilePreferenceController.java
+++ b/src/com/android/settings/enterprise/AlwaysOnVpnManagedProfilePreferenceController.java
@@ -15,27 +15,25 @@
import android.content.Context;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.AbstractPreferenceController;
public class AlwaysOnVpnManagedProfilePreferenceController
- extends DynamicAvailabilityPreferenceController {
+ extends AbstractPreferenceController implements PreferenceControllerMixin {
private static final String KEY_ALWAYS_ON_VPN_MANAGED_PROFILE = "always_on_vpn_managed_profile";
private final EnterprisePrivacyFeatureProvider mFeatureProvider;
- public AlwaysOnVpnManagedProfilePreferenceController(Context context, Lifecycle lifecycle) {
- super(context, lifecycle);
+ public AlwaysOnVpnManagedProfilePreferenceController(Context context) {
+ super(context);
mFeatureProvider = FeatureFactory.getFactory(context)
.getEnterprisePrivacyFeatureProvider(context);
}
@Override
public boolean isAvailable() {
- final boolean available = mFeatureProvider.isAlwaysOnVpnSetInManagedProfile();
- notifyOnAvailabilityUpdate(available);
- return available;
+ return mFeatureProvider.isAlwaysOnVpnSetInManagedProfile();
}
@Override
diff --git a/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceController.java b/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceController.java
index 30da907..e328fc5 100644
--- a/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceController.java
+++ b/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceController.java
@@ -20,16 +20,13 @@
import com.android.settings.R;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
public class CaCertsCurrentUserPreferenceController extends CaCertsPreferenceControllerBase {
@VisibleForTesting
static final String CA_CERTS_CURRENT_USER = "ca_certs_current_user";
- public CaCertsCurrentUserPreferenceController(Context context,
- Lifecycle lifecycle) {
- super(context, lifecycle);
+ public CaCertsCurrentUserPreferenceController(Context context) {
+ super(context);
}
@Override
diff --git a/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceController.java b/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceController.java
index 2b4e72d..94b923f 100644
--- a/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceController.java
+++ b/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceController.java
@@ -17,16 +17,13 @@
import android.content.Context;
import android.support.annotation.VisibleForTesting;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
public class CaCertsManagedProfilePreferenceController extends CaCertsPreferenceControllerBase {
@VisibleForTesting
static final String CA_CERTS_MANAGED_PROFILE = "ca_certs_managed_profile";
- public CaCertsManagedProfilePreferenceController(Context context,
- Lifecycle lifecycle) {
- super(context, lifecycle);
+ public CaCertsManagedProfilePreferenceController(Context context) {
+ super(context);
}
@Override
diff --git a/src/com/android/settings/enterprise/CaCertsPreferenceControllerBase.java b/src/com/android/settings/enterprise/CaCertsPreferenceControllerBase.java
index 8009caf..b9df20a 100644
--- a/src/com/android/settings/enterprise/CaCertsPreferenceControllerBase.java
+++ b/src/com/android/settings/enterprise/CaCertsPreferenceControllerBase.java
@@ -18,17 +18,17 @@
import android.support.v7.preference.Preference;
import com.android.settings.R;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.AbstractPreferenceController;
public abstract class CaCertsPreferenceControllerBase
- extends DynamicAvailabilityPreferenceController {
+ extends AbstractPreferenceController implements PreferenceControllerMixin {
protected final EnterprisePrivacyFeatureProvider mFeatureProvider;
- public CaCertsPreferenceControllerBase(Context context, Lifecycle lifecycle) {
- super(context, lifecycle);
+ public CaCertsPreferenceControllerBase(Context context) {
+ super(context);
mFeatureProvider = FeatureFactory.getFactory(context)
.getEnterprisePrivacyFeatureProvider(context);
}
@@ -42,9 +42,7 @@
@Override
public boolean isAvailable() {
- final boolean available = getNumberOfCaCerts() > 0;
- notifyOnAvailabilityUpdate(available);
- return available;
+ return getNumberOfCaCerts() > 0;
}
protected abstract int getNumberOfCaCerts();
diff --git a/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java b/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java
index cced8e8..1086c0e 100644
--- a/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java
+++ b/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java
@@ -18,21 +18,20 @@
import com.android.settings.R;
import com.android.settings.applications.ApplicationFeatureProvider;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.AbstractPreferenceController;
public class EnterpriseInstalledPackagesPreferenceController
- extends DynamicAvailabilityPreferenceController {
+ extends AbstractPreferenceController implements PreferenceControllerMixin {
private static final String KEY_NUMBER_ENTERPRISE_INSTALLED_PACKAGES
= "number_enterprise_installed_packages";
private final ApplicationFeatureProvider mFeatureProvider;
private final boolean mAsync;
- public EnterpriseInstalledPackagesPreferenceController(Context context, Lifecycle lifecycle,
- boolean async) {
- super(context, lifecycle);
+ public EnterpriseInstalledPackagesPreferenceController(Context context, boolean async) {
+ super(context);
mFeatureProvider = FeatureFactory.getFactory(context)
.getApplicationFeatureProvider(context);
mAsync = async;
@@ -53,7 +52,6 @@
}
preference.setVisible(available);
- notifyOnAvailabilityUpdate(available);
});
}
@@ -72,9 +70,8 @@
final Boolean[] haveEnterpriseInstalledPackages = { null };
mFeatureProvider.calculateNumberOfPolicyInstalledApps(false /* async */,
(num) -> haveEnterpriseInstalledPackages[0] = num > 0);
- final boolean available = haveEnterpriseInstalledPackages[0];
- notifyOnAvailabilityUpdate(available);
- return available;
+ return haveEnterpriseInstalledPackages[0];
+
}
@Override
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyPreferenceController.java b/src/com/android/settings/enterprise/EnterprisePrivacyPreferenceController.java
index 6ec091b..11fc29e 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyPreferenceController.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyPreferenceController.java
@@ -17,23 +17,27 @@
import android.support.v7.preference.Preference;
import com.android.settings.R;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.AbstractPreferenceController;
-public class EnterprisePrivacyPreferenceController extends DynamicAvailabilityPreferenceController {
+public class EnterprisePrivacyPreferenceController extends AbstractPreferenceController implements
+ PreferenceControllerMixin {
private static final String KEY_ENTERPRISE_PRIVACY = "enterprise_privacy";
private final EnterprisePrivacyFeatureProvider mFeatureProvider;
- public EnterprisePrivacyPreferenceController(Context context, Lifecycle lifecycle) {
- super(context, lifecycle);
+ public EnterprisePrivacyPreferenceController(Context context) {
+ super(context);
mFeatureProvider = FeatureFactory.getFactory(context)
.getEnterprisePrivacyFeatureProvider(context);
}
@Override
public void updateState(Preference preference) {
+ if (preference == null) {
+ return;
+ }
final String organizationName = mFeatureProvider.getDeviceOwnerOrganizationName();
if (organizationName == null) {
preference.setSummary(R.string.enterprise_privacy_settings_summary_generic);
@@ -45,9 +49,7 @@
@Override
public boolean isAvailable() {
- final boolean available = mFeatureProvider.hasDeviceOwner();
- notifyOnAvailabilityUpdate(available);
- return available;
+ return mFeatureProvider.hasDeviceOwner();
}
@Override
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
index 4caec30..0628dbb 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
@@ -21,12 +21,11 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
+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;
@@ -53,45 +52,41 @@
@Override
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
- return buildPreferenceControllers(context, getLifecycle(), true /* async */);
+ return buildPreferenceControllers(context, true /* async */);
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
- Lifecycle lifecycle, boolean async) {
+ boolean async) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new NetworkLogsPreferenceController(context));
controllers.add(new BugReportsPreferenceController(context));
controllers.add(new SecurityLogsPreferenceController(context));
- final List<DynamicAvailabilityPreferenceController> exposureChangesCategoryControllers =
+ final List<AbstractPreferenceController> exposureChangesCategoryControllers =
new ArrayList<>();
exposureChangesCategoryControllers.add(new EnterpriseInstalledPackagesPreferenceController(
- context, lifecycle, async));
+ context, async));
exposureChangesCategoryControllers.add(
- new AdminGrantedLocationPermissionsPreferenceController(context, lifecycle, async));
+ new AdminGrantedLocationPermissionsPreferenceController(context, async));
exposureChangesCategoryControllers.add(
- new AdminGrantedMicrophonePermissionPreferenceController(context, lifecycle,
- async));
+ new AdminGrantedMicrophonePermissionPreferenceController(context, async));
exposureChangesCategoryControllers.add(new AdminGrantedCameraPermissionPreferenceController(
- context, lifecycle, async));
+ context, async));
exposureChangesCategoryControllers.add(new EnterpriseSetDefaultAppsPreferenceController(
- context, lifecycle));
+ context));
exposureChangesCategoryControllers.add(new AlwaysOnVpnCurrentUserPreferenceController(
- context, lifecycle));
+ context));
exposureChangesCategoryControllers.add(new AlwaysOnVpnManagedProfilePreferenceController(
- context, lifecycle));
- exposureChangesCategoryControllers.add(new ImePreferenceController(context, lifecycle));
- exposureChangesCategoryControllers.add(new GlobalHttpProxyPreferenceController(context,
- lifecycle));
- exposureChangesCategoryControllers.add(new CaCertsCurrentUserPreferenceController(
- context, lifecycle));
+ context));
+ exposureChangesCategoryControllers.add(new ImePreferenceController(context));
+ exposureChangesCategoryControllers.add(new GlobalHttpProxyPreferenceController(context));
+ exposureChangesCategoryControllers.add(new CaCertsCurrentUserPreferenceController(context));
exposureChangesCategoryControllers.add(new CaCertsManagedProfilePreferenceController(
- context, lifecycle));
+ context));
controllers.addAll(exposureChangesCategoryControllers);
- controllers.add(new ExposureChangesCategoryPreferenceController(context, lifecycle,
- exposureChangesCategoryControllers, async));
- controllers.add(new FailedPasswordWipeCurrentUserPreferenceController(context, lifecycle));
- controllers.add(new FailedPasswordWipeManagedProfilePreferenceController(context,
- lifecycle));
+ controllers.add(new PreferenceCategoryController(context, "exposure_changes_category",
+ exposureChangesCategoryControllers));
+ controllers.add(new FailedPasswordWipeCurrentUserPreferenceController(context));
+ controllers.add(new FailedPasswordWipeManagedProfilePreferenceController(context));
return controllers;
}
@@ -114,11 +109,12 @@
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.enterprise_privacy_settings;
return Arrays.asList(sir);
- }
+ }
- @Override
- public List<AbstractPreferenceController> getPreferenceControllers(Context context) {
- return buildPreferenceControllers(context, null /* lifecycle */, false /* async */);
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(
+ Context context) {
+ return buildPreferenceControllers(context, false /* async */);
}
};
}
diff --git a/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceController.java b/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceController.java
index 537ef78..0f9584b 100644
--- a/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceController.java
+++ b/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceController.java
@@ -21,20 +21,20 @@
import com.android.settings.R;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.applications.EnterpriseDefaultApps;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.users.UserFeatureProvider;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.AbstractPreferenceController;
public class EnterpriseSetDefaultAppsPreferenceController
- extends DynamicAvailabilityPreferenceController {
+ extends AbstractPreferenceController implements PreferenceControllerMixin {
private static final String KEY_DEFAULT_APPS = "number_enterprise_set_default_apps";
private final ApplicationFeatureProvider mApplicationFeatureProvider;
private final UserFeatureProvider mUserFeatureProvider;
- public EnterpriseSetDefaultAppsPreferenceController(Context context, Lifecycle lifecycle) {
- super(context, lifecycle);
+ public EnterpriseSetDefaultAppsPreferenceController(Context context) {
+ super(context);
final FeatureFactory factory = FeatureFactory.getFactory(context);
mApplicationFeatureProvider = factory.getApplicationFeatureProvider(context);
mUserFeatureProvider = factory.getUserFeatureProvider(context);
@@ -49,9 +49,7 @@
@Override
public boolean isAvailable() {
- final boolean available = getNumberOfEnterpriseSetDefaultApps() > 0;
- notifyOnAvailabilityUpdate(available);
- return available;
+ return getNumberOfEnterpriseSetDefaultApps() > 0;
}
@Override
diff --git a/src/com/android/settings/enterprise/ExposureChangesCategoryPreferenceController.java b/src/com/android/settings/enterprise/ExposureChangesCategoryPreferenceController.java
deleted file mode 100644
index 7833325..0000000
--- a/src/com/android/settings/enterprise/ExposureChangesCategoryPreferenceController.java
+++ /dev/null
@@ -1,111 +0,0 @@
-
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.settings.enterprise;
-
-import android.content.Context;
-import android.support.v7.preference.Preference;
-
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
-import com.android.settings.core.PreferenceAvailabilityObserver;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A controller that hides a {@link android.support.v7.preference.PreferenceGroup} when none of the
- * {@link Preference}s inside it are visible.
- *
- * TODO(b/62051162): Use {@link android.support.v7.preference.PreferenceGroup}'s native ability to
- * hide itself when all {@link Preference}s inside it are invisible when that functionality becomes
- * available. This custom controller will still be needed to remove the
- * {@link android.support.v7.preference.PreferenceGroup} from the search index as required (by
- * having {@link #isAvailable()} return {@code false} if the method returns {@code false} for all
- * {@link Preference}s in the {@link android.support.v7.preference.PreferenceGroup}).
- */
-public class ExposureChangesCategoryPreferenceController
- extends DynamicAvailabilityPreferenceController implements PreferenceAvailabilityObserver {
-
- private static final String KEY_EXPOSURE_CHANGES_CATEGORY = "exposure_changes_category";
- private final Set<String> mAvailablePrefs = new HashSet<String>();
- private Preference mPreference = null;
- private boolean mControllingUi;
-
- /**
- * When {@code controllingUi} is {@code true}, some of the preferences may have their visibility
- * determined asynchronously. In this case, {@link #isAvailable()} must always return {@code
- * true} and the group should be hidden using {@link Preference#setVisible()} if all preferences
- * report that they are invisible.
- * When {@code controllingUi} is {@code false}, we are running on the search indexer thread and
- * visibility must be determined synchronously. {@link #isAvailable()} can rely on all
- * preferences having their visibility determined already and should return whether the group is
- * visible or not.
- */
- public ExposureChangesCategoryPreferenceController(Context context, Lifecycle lifecycle,
- List<DynamicAvailabilityPreferenceController> controllers, boolean controllingUi) {
- super(context, lifecycle);
- mControllingUi = controllingUi;
- for (final DynamicAvailabilityPreferenceController controller : controllers) {
- controller.setAvailabilityObserver(this);
- }
- }
-
- @Override
- public void onPreferenceAvailabilityUpdated(String key, boolean available) {
- if (available) {
- mAvailablePrefs.add(key);
- } else {
- mAvailablePrefs.remove(key);
- }
- available = haveAnyVisiblePreferences();
- if (mControllingUi) {
- notifyOnAvailabilityUpdate(available);
- }
- if (mPreference != null) {
- mPreference.setVisible(available);
- }
- }
-
- @Override
- public void updateState(Preference preference) {
- mPreference = preference;
- mPreference.setVisible(haveAnyVisiblePreferences());
- }
-
- @Override
- public boolean isAvailable() {
- if (mControllingUi) {
- // When running on the main UI thread, some preferences determine their visibility
- // asynchronously. Always return true here and determine the pref group's actual
- // visibility as the other preferences report their visibility asynchronously via
- // onPreferenceAvailabilityUpdated().
- return true;
- }
- final boolean available = haveAnyVisiblePreferences();
- notifyOnAvailabilityUpdate(available);
- return available;
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_EXPOSURE_CHANGES_CATEGORY;
- }
-
- private boolean haveAnyVisiblePreferences() {
- return mAvailablePrefs.size() > 0;
- }
-}
diff --git a/src/com/android/settings/enterprise/FailedPasswordWipeCurrentUserPreferenceController.java b/src/com/android/settings/enterprise/FailedPasswordWipeCurrentUserPreferenceController.java
index d7f8dc0..f93025c 100644
--- a/src/com/android/settings/enterprise/FailedPasswordWipeCurrentUserPreferenceController.java
+++ b/src/com/android/settings/enterprise/FailedPasswordWipeCurrentUserPreferenceController.java
@@ -15,16 +15,14 @@
import android.content.Context;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
public class FailedPasswordWipeCurrentUserPreferenceController
extends FailedPasswordWipePreferenceControllerBase {
private static final String KEY_FAILED_PASSWORD_WIPE_CURRENT_USER
= "failed_password_wipe_current_user";
- public FailedPasswordWipeCurrentUserPreferenceController(Context context, Lifecycle lifecycle) {
- super(context, lifecycle);
+ public FailedPasswordWipeCurrentUserPreferenceController(Context context) {
+ super(context);
}
@Override
diff --git a/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceController.java b/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceController.java
index 739003a..5a0e7c8 100644
--- a/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceController.java
+++ b/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceController.java
@@ -14,7 +14,6 @@
package com.android.settings.enterprise;
import android.content.Context;
-import com.android.settingslib.core.lifecycle.Lifecycle;
public class FailedPasswordWipeManagedProfilePreferenceController
extends FailedPasswordWipePreferenceControllerBase {
@@ -22,9 +21,8 @@
private static final String KEY_FAILED_PASSWORD_WIPE_MANAGED_PROFILE
= "failed_password_wipe_managed_profile";
- public FailedPasswordWipeManagedProfilePreferenceController(Context context,
- Lifecycle lifecycle) {
- super(context, lifecycle);
+ public FailedPasswordWipeManagedProfilePreferenceController(Context context) {
+ super(context);
}
@Override
diff --git a/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBase.java b/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBase.java
index 298f911..3c78c21 100644
--- a/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBase.java
+++ b/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBase.java
@@ -15,21 +15,20 @@
package com.android.settings.enterprise;
import android.content.Context;
-import android.content.res.Resources;
import android.support.v7.preference.Preference;
import com.android.settings.R;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.AbstractPreferenceController;
public abstract class FailedPasswordWipePreferenceControllerBase
- extends DynamicAvailabilityPreferenceController {
+ extends AbstractPreferenceController implements PreferenceControllerMixin {
protected final EnterprisePrivacyFeatureProvider mFeatureProvider;
- public FailedPasswordWipePreferenceControllerBase(Context context, Lifecycle lifecycle) {
- super(context, lifecycle);
+ public FailedPasswordWipePreferenceControllerBase(Context context) {
+ super(context);
mFeatureProvider = FeatureFactory.getFactory(context)
.getEnterprisePrivacyFeatureProvider(context);
}
@@ -46,8 +45,6 @@
@Override
public boolean isAvailable() {
- final boolean available = getMaximumFailedPasswordsBeforeWipe() > 0;
- notifyOnAvailabilityUpdate(available);
- return available;
+ return getMaximumFailedPasswordsBeforeWipe() > 0;
}
}
diff --git a/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceController.java b/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceController.java
index 55552b6..04e63aa 100644
--- a/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceController.java
+++ b/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceController.java
@@ -15,26 +15,25 @@
import android.content.Context;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.AbstractPreferenceController;
-public class GlobalHttpProxyPreferenceController extends DynamicAvailabilityPreferenceController {
+public class GlobalHttpProxyPreferenceController extends AbstractPreferenceController implements
+ PreferenceControllerMixin {
private static final String KEY_GLOBAL_HTTP_PROXY = "global_http_proxy";
private final EnterprisePrivacyFeatureProvider mFeatureProvider;
- public GlobalHttpProxyPreferenceController(Context context, Lifecycle lifecycle) {
- super(context, lifecycle);
+ public GlobalHttpProxyPreferenceController(Context context) {
+ super(context);
mFeatureProvider = FeatureFactory.getFactory(context)
.getEnterprisePrivacyFeatureProvider(context);
}
@Override
public boolean isAvailable() {
- final boolean available = mFeatureProvider.isGlobalHttpProxySet();
- notifyOnAvailabilityUpdate(available);
- return available;
+ return mFeatureProvider.isGlobalHttpProxySet();
}
@Override
diff --git a/src/com/android/settings/enterprise/ImePreferenceController.java b/src/com/android/settings/enterprise/ImePreferenceController.java
index ca52fc0..7a4ea2c 100644
--- a/src/com/android/settings/enterprise/ImePreferenceController.java
+++ b/src/com/android/settings/enterprise/ImePreferenceController.java
@@ -15,21 +15,21 @@
package com.android.settings.enterprise;
import android.content.Context;
-import android.content.res.Resources;
import android.support.v7.preference.Preference;
import com.android.settings.R;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.AbstractPreferenceController;
-public class ImePreferenceController extends DynamicAvailabilityPreferenceController {
+public class ImePreferenceController extends AbstractPreferenceController implements
+ PreferenceControllerMixin {
private static final String KEY_INPUT_METHOD = "input_method";
private final EnterprisePrivacyFeatureProvider mFeatureProvider;
- public ImePreferenceController(Context context, Lifecycle lifecycle) {
- super(context, lifecycle);
+ public ImePreferenceController(Context context) {
+ super(context);
mFeatureProvider = FeatureFactory.getFactory(context)
.getEnterprisePrivacyFeatureProvider(context);
}
@@ -37,15 +37,13 @@
@Override
public void updateState(Preference preference) {
preference.setSummary(mContext.getResources().getString(
- R.string.enterprise_privacy_input_method_name,
- mFeatureProvider.getImeLabelIfOwnerSet()));
+ R.string.enterprise_privacy_input_method_name,
+ mFeatureProvider.getImeLabelIfOwnerSet()));
}
@Override
public boolean isAvailable() {
- final boolean available = mFeatureProvider.getImeLabelIfOwnerSet() != null;
- notifyOnAvailabilityUpdate(available);
- return available;
+ return mFeatureProvider.getImeLabelIfOwnerSet() != null;
}
@Override
diff --git a/src/com/android/settings/language/PhoneLanguagePreferenceController.java b/src/com/android/settings/language/PhoneLanguagePreferenceController.java
index e32adec..49f7f21 100644
--- a/src/com/android/settings/language/PhoneLanguagePreferenceController.java
+++ b/src/com/android/settings/language/PhoneLanguagePreferenceController.java
@@ -68,8 +68,7 @@
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
- if (!InstrumentedPreferenceFragment.usePreferenceScreenTitle()
- || !KEY_PHONE_LANGUAGE.equals(preference.getKey())) {
+ if (!KEY_PHONE_LANGUAGE.equals(preference.getKey())) {
return false;
}
Utils.startWithFragment(mContext, LocaleListEditor.class.getName(), null, null, 0,
diff --git a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
index 0b40bbd..1d21c12 100644
--- a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
+++ b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
@@ -82,14 +82,13 @@
}
public LocaleDragAndDropAdapter(Context context, List<LocaleStore.LocaleInfo> feedItemList) {
- this.mFeedItemList = feedItemList;
-
- this.mContext = context;
+ mFeedItemList = feedItemList;
+ mContext = context;
final float dragElevation = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
context.getResources().getDisplayMetrics());
- this.mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
+ mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0 /* no swipe */) {
@Override
@@ -248,15 +247,6 @@
return result;
}
- LocaleStore.LocaleInfo getFirstChecked() {
- for (LocaleStore.LocaleInfo li : mFeedItemList) {
- if (li.getChecked()) {
- return li;
- }
- }
- return null;
- }
-
void addLocale(LocaleStore.LocaleInfo li) {
mFeedItemList.add(li);
notifyItemInserted(mFeedItemList.size() - 1);
diff --git a/src/com/android/settings/localepicker/LocaleListEditor.java b/src/com/android/settings/localepicker/LocaleListEditor.java
index 165be90..79d538f 100644
--- a/src/com/android/settings/localepicker/LocaleListEditor.java
+++ b/src/com/android/settings/localepicker/LocaleListEditor.java
@@ -18,7 +18,6 @@
import android.app.AlertDialog;
import android.app.FragmentTransaction;
-import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.LocaleList;
@@ -30,21 +29,24 @@
import android.view.View;
import android.view.ViewGroup;
+import android.widget.TextView;
import com.android.internal.app.LocalePicker;
import com.android.internal.app.LocalePickerWithRegion;
import com.android.internal.app.LocaleStore;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.RestrictedSettingsFragment;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import static android.os.UserManager.DISALLOW_CONFIG_LOCALE;
+
/**
* Drag-and-drop editor for the user-ordered locale lists.
*/
-public class LocaleListEditor extends SettingsPreferenceFragment
+public class LocaleListEditor extends RestrictedSettingsFragment
implements LocalePickerWithRegion.LocaleSelectedListener {
private static final String CFGKEY_REMOVE_MODE = "localeRemoveMode";
@@ -56,6 +58,11 @@
private View mAddLanguage;
private boolean mRemoveMode;
private boolean mShowingRemoveDialog;
+ private boolean mIsUiRestricted;
+
+ public LocaleListEditor() {
+ super(DISALLOW_CONFIG_LOCALE);
+ }
@Override
public int getMetricsCategory() {
@@ -68,7 +75,7 @@
setHasOptionsMenu(true);
LocaleStore.fillCache(this.getContext());
- final List<LocaleStore.LocaleInfo> feedsList = getUserLocaleList(this.getContext());
+ final List<LocaleStore.LocaleInfo> feedsList = getUserLocaleList();
mAdapter = new LocaleDragAndDropAdapter(this.getContext(), feedsList);
}
@@ -82,6 +89,25 @@
}
@Override
+ public void onResume() {
+ super.onResume();
+
+ final boolean previouslyRestricted = mIsUiRestricted;
+ mIsUiRestricted = isUiRestricted();
+ final TextView emptyView = getEmptyTextView();
+ if (mIsUiRestricted && !previouslyRestricted) {
+ // Lock it down.
+ emptyView.setText(R.string.language_empty_list_user_restricted);
+ emptyView.setVisibility(View.VISIBLE);
+ updateVisibilityOfRemoveMenu();
+ } else if (!mIsUiRestricted && previouslyRestricted) {
+ // Unlock it.
+ emptyView.setVisibility(View.GONE);
+ updateVisibilityOfRemoveMenu();
+ }
+ }
+
+ @Override
public void onViewStateRestored(Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if (savedInstanceState != null) {
@@ -217,20 +243,18 @@
updateVisibilityOfRemoveMenu();
}
- private static List<LocaleStore.LocaleInfo> getUserLocaleList(Context context) {
+ private List<LocaleStore.LocaleInfo> getUserLocaleList() {
final List<LocaleStore.LocaleInfo> result = new ArrayList<>();
-
final LocaleList localeList = LocalePicker.getLocales();
for (int i = 0; i < localeList.size(); i++) {
Locale locale = localeList.get(i);
result.add(LocaleStore.getLocaleInfo(locale));
}
-
return result;
}
private void configureDragAndDrop(View view) {
- final RecyclerView list = (RecyclerView) view.findViewById(R.id.dragList);
+ final RecyclerView list = view.findViewById(R.id.dragList);
final LocaleLinearLayoutManager llm = new LocaleLinearLayoutManager(getContext(), mAdapter);
llm.setAutoMeasureEnabled(true);
list.setLayoutManager(llm);
@@ -272,7 +296,8 @@
if (menuItemRemove != null) {
menuItemRemove.setShowAsAction(
mRemoveMode ? MenuItem.SHOW_AS_ACTION_ALWAYS : MenuItem.SHOW_AS_ACTION_NEVER);
- menuItemRemove.setVisible(mAdapter.getItemCount() > 1);
+ final boolean hasMultipleLanguages = mAdapter.getItemCount() > 1;
+ menuItemRemove.setVisible(hasMultipleLanguages && !mIsUiRestricted);
}
}
}
diff --git a/src/com/android/settings/location/AppLocationPermissionPreferenceController.java b/src/com/android/settings/location/AppLocationPermissionPreferenceController.java
index 75c9e2f..fabe295 100644
--- a/src/com/android/settings/location/AppLocationPermissionPreferenceController.java
+++ b/src/com/android/settings/location/AppLocationPermissionPreferenceController.java
@@ -2,8 +2,6 @@
import android.content.Context;
import android.provider.Settings;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -12,21 +10,12 @@
AbstractPreferenceController implements PreferenceControllerMixin {
private static final String KEY_APP_LEVEL_PERMISSIONS = "app_level_permissions";
- private Preference mPreference;
public AppLocationPermissionPreferenceController(Context context) {
super(context);
}
@Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- if (isAvailable()) {
- mPreference = screen.findPreference(KEY_APP_LEVEL_PERMISSIONS);
- }
- }
-
- @Override
public String getPreferenceKey() {
return KEY_APP_LEVEL_PERMISSIONS;
}
diff --git a/src/com/android/settings/location/BluetoothScanningPreferenceController.java b/src/com/android/settings/location/BluetoothScanningPreferenceController.java
new file mode 100644
index 0000000..c97bc7d
--- /dev/null
+++ b/src/com/android/settings/location/BluetoothScanningPreferenceController.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.settings.location;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class BluetoothScanningPreferenceController extends AbstractPreferenceController
+ implements PreferenceControllerMixin {
+
+ private static final String KEY_BLUETOOTH_SCAN_ALWAYS_AVAILABLE = "bluetooth_always_scanning";
+
+ public BluetoothScanningPreferenceController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BLUETOOTH_SCAN_ALWAYS_AVAILABLE;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ ((SwitchPreference) preference).setChecked(
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0) == 1);
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (KEY_BLUETOOTH_SCAN_ALWAYS_AVAILABLE.equals(preference.getKey())) {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE,
+ ((SwitchPreference) preference).isChecked() ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/settings/location/LocationBasePreferenceController.java b/src/com/android/settings/location/LocationBasePreferenceController.java
new file mode 100644
index 0000000..6cf8626
--- /dev/null
+++ b/src/com/android/settings/location/LocationBasePreferenceController.java
@@ -0,0 +1,44 @@
+/*
+ * 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.location;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+/**
+ * A base controller for preferences that listens to location settings change and modifies location
+ * settings.
+ */
+public abstract class LocationBasePreferenceController extends AbstractPreferenceController
+ implements PreferenceControllerMixin, LocationEnabler.LocationModeChangeListener {
+
+ protected final UserManager mUserManager;
+ protected final LocationEnabler mLocationEnabler;
+
+ public LocationBasePreferenceController(Context context, Lifecycle lifecycle) {
+ super(context);
+ mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ mLocationEnabler = new LocationEnabler(context, this /* listener */, lifecycle);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+}
diff --git a/src/com/android/settings/location/LocationEnabler.java b/src/com/android/settings/location/LocationEnabler.java
new file mode 100644
index 0000000..0bec6ba
--- /dev/null
+++ b/src/com/android/settings/location/LocationEnabler.java
@@ -0,0 +1,166 @@
+/*
+ * 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.location;
+
+import android.Manifest.permission;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.location.LocationManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import com.android.settings.Utils;
+import com.android.settingslib.RestrictedLockUtils;
+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;
+
+/**
+ * A class that listens to location settings change and modifies location settings
+ * settings.
+ */
+public class LocationEnabler implements LifecycleObserver, OnResume, OnPause {
+
+ private static final String TAG = "LocationEnabler";
+ @VisibleForTesting
+ static final String MODE_CHANGING_ACTION =
+ "com.android.settings.location.MODE_CHANGING";
+ private static final String CURRENT_MODE_KEY = "CURRENT_MODE";
+ private static final String NEW_MODE_KEY = "NEW_MODE";
+ @VisibleForTesting
+ static final IntentFilter INTENT_FILTER_LOCATION_MODE_CHANGED =
+ new IntentFilter(LocationManager.MODE_CHANGED_ACTION);
+
+ private final Context mContext;
+ private final UserManager mUserManager;
+ private final LocationModeChangeListener mListener;
+
+ @VisibleForTesting
+ BroadcastReceiver mReceiver;
+
+ public interface LocationModeChangeListener {
+ /** Called when location mode has changed. */
+ void onLocationModeChanged(int mode, boolean restricted);
+ }
+
+ public LocationEnabler(Context context, LocationModeChangeListener listener,
+ Lifecycle lifecycle) {
+ mContext = context;
+ mListener = listener;
+ mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public void onResume() {
+ if (mReceiver == null) {
+ mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Received location mode change intent: " + intent);
+ }
+ refreshLocationMode();
+ }
+ };
+ }
+ mContext.registerReceiver(mReceiver, INTENT_FILTER_LOCATION_MODE_CHANGED);
+ refreshLocationMode();
+ }
+
+ @Override
+ public void onPause() {
+ try {
+ mContext.unregisterReceiver(mReceiver);
+ } catch (RuntimeException e) {
+ // Ignore exceptions caused by race condition
+ }
+ }
+
+ void refreshLocationMode() {
+ final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
+ if (Log.isLoggable(TAG, Log.INFO)) {
+ Log.i(TAG, "Location mode has been changed");
+ }
+ if (mListener != null) {
+ mListener.onLocationModeChanged(mode, isRestricted());
+ }
+ }
+
+ void setLocationMode(int mode) {
+ final int currentMode = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
+ if (isRestricted()) {
+ // Location toggling disabled by user restriction. Read the current location mode to
+ // update the location master switch.
+ if (Log.isLoggable(TAG, Log.INFO)) {
+ Log.i(TAG, "Restricted user, not setting location mode");
+ }
+ if (mListener != null) {
+ mListener.onLocationModeChanged(currentMode, true);
+ }
+ return;
+ }
+
+ updateLocationMode(currentMode, mode);
+ refreshLocationMode();
+ }
+
+ boolean isEnabled(int mode) {
+ return mode != Settings.Secure.LOCATION_MODE_OFF && !isRestricted();
+ }
+
+ /**
+ * Checking if device policy has put a location access lock-down on the managed profile.
+ *
+ * @return true if device policy has put a location access lock-down on the managed profile
+ */
+ boolean isManagedProfileRestrictedByBase() {
+ final UserHandle managedProfile = Utils.getManagedProfile(mUserManager);
+ return managedProfile != null
+ && hasShareLocationRestriction(managedProfile.getIdentifier());
+ }
+
+ RestrictedLockUtils.EnforcedAdmin getShareLocationEnforcedAdmin(int userId) {
+ return RestrictedLockUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_SHARE_LOCATION, userId);
+ }
+
+ boolean hasShareLocationRestriction(int userId) {
+ return RestrictedLockUtils.hasBaseUserRestriction(
+ mContext, UserManager.DISALLOW_SHARE_LOCATION, userId);
+ }
+
+ private boolean isRestricted() {
+ return mUserManager.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION);
+ }
+
+ private boolean updateLocationMode(int oldMode, int newMode) {
+ final Intent intent = new Intent(MODE_CHANGING_ACTION);
+ intent.putExtra(CURRENT_MODE_KEY, oldMode);
+ intent.putExtra(NEW_MODE_KEY, newMode);
+ mContext.sendBroadcast(intent, permission.WRITE_SECURE_SETTINGS);
+ return Settings.Secure.putInt(
+ mContext.getContentResolver(), Settings.Secure.LOCATION_MODE, newMode);
+ }
+}
diff --git a/src/com/android/settings/location/LocationForWorkPreferenceController.java b/src/com/android/settings/location/LocationForWorkPreferenceController.java
new file mode 100644
index 0000000..a81c9d4
--- /dev/null
+++ b/src/com/android/settings/location/LocationForWorkPreferenceController.java
@@ -0,0 +1,103 @@
+/*
+ * 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.location;
+
+import android.content.Context;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class LocationForWorkPreferenceController extends LocationBasePreferenceController {
+
+ /**
+ * Key for managed profile location switch preference. Shown only
+ * if there is a managed profile.
+ */
+ private static final String KEY_MANAGED_PROFILE_SWITCH = "managed_profile_location_switch";
+
+ private RestrictedSwitchPreference mPreference;
+
+ public LocationForWorkPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, lifecycle);
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (KEY_MANAGED_PROFILE_SWITCH.equals(preference.getKey())) {
+ final boolean switchState = mPreference.isChecked();
+ mUserManager.setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, !switchState,
+ Utils.getManagedProfile(mUserManager));
+ mPreference.setSummary(switchState ?
+ R.string.switch_on_text : R.string.switch_off_text);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference =
+ (RestrictedSwitchPreference) screen.findPreference(KEY_MANAGED_PROFILE_SWITCH);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ // Looking for a managed profile. If there are no managed profiles then we are removing the
+ // managed profile category.
+ return Utils.getManagedProfile(mUserManager) != null;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_MANAGED_PROFILE_SWITCH;
+ }
+
+ @Override
+ public void onLocationModeChanged(int mode, boolean restricted) {
+ if (!mPreference.isVisible() || !isAvailable()) {
+ return;
+ }
+ final RestrictedLockUtils.EnforcedAdmin admin =
+ mLocationEnabler.getShareLocationEnforcedAdmin(
+ Utils.getManagedProfile(mUserManager).getIdentifier());
+ final boolean isRestrictedByBase = mLocationEnabler.isManagedProfileRestrictedByBase();
+ if (!isRestrictedByBase && admin != null) {
+ mPreference.setDisabledByAdmin(admin);
+ mPreference.setChecked(false);
+ } else {
+ final boolean enabled = mLocationEnabler.isEnabled(mode);
+ mPreference.setEnabled(enabled);
+
+ int summaryResId = R.string.switch_off_text;
+ if (!enabled) {
+ mPreference.setChecked(false);
+ } else {
+ mPreference.setChecked(!isRestrictedByBase);
+ summaryResId = (isRestrictedByBase ?
+ R.string.switch_off_text : R.string.switch_on_text);
+ }
+ mPreference.setSummary(summaryResId);
+ }
+ }
+}
+
diff --git a/src/com/android/settings/location/LocationMode.java b/src/com/android/settings/location/LocationMode.java
index 4ca098d..34f082b 100644
--- a/src/com/android/settings/location/LocationMode.java
+++ b/src/com/android/settings/location/LocationMode.java
@@ -16,12 +16,20 @@
package com.android.settings.location;
-import android.provider.Settings;
-import android.support.v7.preference.PreferenceScreen;
+import android.content.Context;
+import android.provider.SearchIndexableResource;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
-import com.android.settings.widget.RadioButtonPreference;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+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;
/**
* A page with 3 radio buttons to choose the location mode.
@@ -34,14 +42,9 @@
*
* Sensors only: use GPS location only.
*/
-public class LocationMode extends LocationSettingsBase
- implements RadioButtonPreference.OnClickListener {
- private static final String KEY_HIGH_ACCURACY = "high_accuracy";
- private RadioButtonPreference mHighAccuracy;
- private static final String KEY_BATTERY_SAVING = "battery_saving";
- private RadioButtonPreference mBatterySaving;
- private static final String KEY_SENSORS_ONLY = "sensors_only";
- private RadioButtonPreference mSensorsOnly;
+public class LocationMode extends DashboardFragment {
+
+ private static final String TAG = "LocationMode";
@Override
public int getMetricsCategory() {
@@ -49,95 +52,52 @@
}
@Override
- public void onResume() {
- super.onResume();
- createPreferenceHierarchy();
+ protected int getPreferenceScreenResId() {
+ return R.xml.location_mode;
}
@Override
- public void onPause() {
- super.onPause();
- }
-
- private PreferenceScreen createPreferenceHierarchy() {
- PreferenceScreen root = getPreferenceScreen();
- if (root != null) {
- root.removeAll();
- }
- addPreferencesFromResource(R.xml.location_mode);
- root = getPreferenceScreen();
-
- mHighAccuracy = (RadioButtonPreference) root.findPreference(KEY_HIGH_ACCURACY);
- mBatterySaving = (RadioButtonPreference) root.findPreference(KEY_BATTERY_SAVING);
- mSensorsOnly = (RadioButtonPreference) root.findPreference(KEY_SENSORS_ONLY);
- mHighAccuracy.setOnClickListener(this);
- mBatterySaving.setOnClickListener(this);
- mSensorsOnly.setOnClickListener(this);
-
- refreshLocationMode();
- return root;
- }
-
- private void updateRadioButtons(RadioButtonPreference activated) {
- if (activated == null) {
- mHighAccuracy.setChecked(false);
- mBatterySaving.setChecked(false);
- mSensorsOnly.setChecked(false);
- } else if (activated == mHighAccuracy) {
- mHighAccuracy.setChecked(true);
- mBatterySaving.setChecked(false);
- mSensorsOnly.setChecked(false);
- } else if (activated == mBatterySaving) {
- mHighAccuracy.setChecked(false);
- mBatterySaving.setChecked(true);
- mSensorsOnly.setChecked(false);
- } else if (activated == mSensorsOnly) {
- mHighAccuracy.setChecked(false);
- mBatterySaving.setChecked(false);
- mSensorsOnly.setChecked(true);
- }
+ protected String getLogTag() {
+ return TAG;
}
@Override
- public void onRadioButtonClicked(RadioButtonPreference emiter) {
- int mode = Settings.Secure.LOCATION_MODE_OFF;
- if (emiter == mHighAccuracy) {
- mode = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
- } else if (emiter == mBatterySaving) {
- mode = Settings.Secure.LOCATION_MODE_BATTERY_SAVING;
- } else if (emiter == mSensorsOnly) {
- mode = Settings.Secure.LOCATION_MODE_SENSORS_ONLY;
- }
- setLocationMode(mode);
- }
-
- @Override
- public void onModeChanged(int mode, boolean restricted) {
- switch (mode) {
- case Settings.Secure.LOCATION_MODE_OFF:
- updateRadioButtons(null);
- break;
- case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
- updateRadioButtons(mSensorsOnly);
- break;
- case Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
- updateRadioButtons(mBatterySaving);
- break;
- case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
- updateRadioButtons(mHighAccuracy);
- break;
- default:
- break;
- }
-
- boolean enabled = (mode != Settings.Secure.LOCATION_MODE_OFF) && !restricted;
- mHighAccuracy.setEnabled(enabled);
- mBatterySaving.setEnabled(enabled);
- mSensorsOnly.setEnabled(enabled);
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getLifecycle());
}
@Override
public int getHelpResource() {
return R.string.help_url_location_access;
}
+
+ private static List<AbstractPreferenceController> buildPreferenceControllers(
+ Context context, Lifecycle lifecycle) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new LocationModeHighAccuracyPreferenceController(context, lifecycle));
+ controllers.add(
+ new LocationModeBatterySavingPreferenceController(context, lifecycle));
+ controllers.add(new LocationModeSensorsOnlyPreferenceController(context, lifecycle));
+ return controllers;
+ }
+
+ /**
+ * For Search.
+ */
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.location_mode;
+ return Arrays.asList(sir);
+ }
+
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context
+ context) {
+ return buildPreferenceControllers(context, null /* lifecycle */);
+ }
+ };
}
diff --git a/src/com/android/settings/location/LocationModeBatterySavingPreferenceController.java b/src/com/android/settings/location/LocationModeBatterySavingPreferenceController.java
new file mode 100644
index 0000000..70c7013
--- /dev/null
+++ b/src/com/android/settings/location/LocationModeBatterySavingPreferenceController.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.settings.location;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class LocationModeBatterySavingPreferenceController
+ extends LocationModeRadioButtonPreferenceController {
+
+ private static final String KEY_BATTERY_SAVING = "battery_saving";
+
+ public LocationModeBatterySavingPreferenceController(Context context,
+ Lifecycle lifecycle) {
+ super(context, lifecycle);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BATTERY_SAVING;
+ }
+
+ @Override
+ protected int getLocationMode() {
+ return Settings.Secure.LOCATION_MODE_BATTERY_SAVING;
+ }
+}
diff --git a/src/com/android/settings/location/LocationModeHighAccuracyPreferenceController.java b/src/com/android/settings/location/LocationModeHighAccuracyPreferenceController.java
new file mode 100644
index 0000000..bd2d07e
--- /dev/null
+++ b/src/com/android/settings/location/LocationModeHighAccuracyPreferenceController.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.settings.location;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class LocationModeHighAccuracyPreferenceController
+ extends LocationModeRadioButtonPreferenceController {
+
+ private static final String KEY_HIGH_ACCURACY = "high_accuracy";
+
+ public LocationModeHighAccuracyPreferenceController(Context context,
+ Lifecycle lifecycle) {
+ super(context, lifecycle);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_HIGH_ACCURACY;
+ }
+
+ @Override
+ protected int getLocationMode() {
+ return Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
+ }
+}
diff --git a/src/com/android/settings/location/LocationModePreferenceController.java b/src/com/android/settings/location/LocationModePreferenceController.java
new file mode 100644
index 0000000..a9ed6ad
--- /dev/null
+++ b/src/com/android/settings/location/LocationModePreferenceController.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.settings.location;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class LocationModePreferenceController extends LocationBasePreferenceController {
+
+ /** Key for preference screen "Mode" */
+ private static final String KEY_LOCATION_MODE = "location_mode";
+
+ private final LocationSettings mParentFragment;
+ private Preference mPreference;
+
+ public LocationModePreferenceController(Context context, LocationSettings parent,
+ Lifecycle lifecycle) {
+ super(context, lifecycle);
+ mParentFragment = parent;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_LOCATION_MODE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(KEY_LOCATION_MODE);
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (KEY_LOCATION_MODE.equals(preference.getKey())) {
+ final SettingsActivity activity = (SettingsActivity) mParentFragment.getActivity();
+ activity.startPreferencePanel(mParentFragment, LocationMode.class.getName(), null,
+ R.string.location_mode_screen_title, null, mParentFragment, 0);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onLocationModeChanged(int mode, boolean restricted) {
+ final int modeDescription = LocationPreferenceController.getLocationString(mode);
+ if (modeDescription != 0) {
+ mPreference.setSummary(modeDescription);
+ }
+ // Restricted user can't change the location mode, so disable the master switch. But in some
+ // corner cases, the location might still be enabled. In such case the master switch should
+ // be disabled but checked.
+ mPreference.setEnabled(mLocationEnabler.isEnabled(mode));
+ }
+}
diff --git a/src/com/android/settings/location/LocationModeRadioButtonPreferenceController.java b/src/com/android/settings/location/LocationModeRadioButtonPreferenceController.java
new file mode 100644
index 0000000..bdf7c8f
--- /dev/null
+++ b/src/com/android/settings/location/LocationModeRadioButtonPreferenceController.java
@@ -0,0 +1,53 @@
+/*
+ * 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.location;
+
+import android.content.Context;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.widget.RadioButtonPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public abstract class LocationModeRadioButtonPreferenceController
+ extends LocationBasePreferenceController
+ implements RadioButtonPreference.OnClickListener {
+
+ protected RadioButtonPreference mPreference;
+
+ public LocationModeRadioButtonPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, lifecycle);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = (RadioButtonPreference) screen.findPreference(getPreferenceKey());
+ mPreference.setOnClickListener(this);
+ }
+
+ @Override
+ public void onRadioButtonClicked(RadioButtonPreference emiter) {
+ mLocationEnabler.setLocationMode(getLocationMode());
+ }
+
+ @Override
+ public void onLocationModeChanged(int mode, boolean restricted) {
+ mPreference.setChecked(mode == getLocationMode());
+ mPreference.setEnabled(mLocationEnabler.isEnabled(mode));
+ }
+
+ /** Gets the location mode that this controller monitors. */
+ protected abstract int getLocationMode();
+
+}
diff --git a/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceController.java b/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceController.java
new file mode 100644
index 0000000..b79dbf2
--- /dev/null
+++ b/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceController.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.settings.location;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class LocationModeSensorsOnlyPreferenceController
+ extends LocationModeRadioButtonPreferenceController {
+
+ private static final String KEY_SENSORS_ONLY = "sensors_only";
+
+ public LocationModeSensorsOnlyPreferenceController(Context context,
+ Lifecycle lifecycle) {
+ super(context, lifecycle);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_SENSORS_ONLY;
+ }
+
+ @Override
+ protected int getLocationMode() {
+ return Settings.Secure.LOCATION_MODE_SENSORS_ONLY;
+ }
+}
diff --git a/src/com/android/settings/location/LocationServicePreferenceController.java b/src/com/android/settings/location/LocationServicePreferenceController.java
new file mode 100644
index 0000000..0a6a5c1
--- /dev/null
+++ b/src/com/android/settings/location/LocationServicePreferenceController.java
@@ -0,0 +1,130 @@
+/*
+ * 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.location;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.location.SettingInjectorService;
+import android.os.UserHandle;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceScreen;
+import android.util.Log;
+
+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 LocationServicePreferenceController extends LocationBasePreferenceController
+ implements LifecycleObserver, OnResume, OnPause {
+
+ private static final String TAG = "LocationServicePrefCtrl";
+ /** Key for preference category "Location services" */
+ private static final String KEY_LOCATION_SERVICES = "location_services";
+ @VisibleForTesting
+ static final IntentFilter INTENT_FILTER_INJECTED_SETTING_CHANGED =
+ new IntentFilter(SettingInjectorService.ACTION_INJECTED_SETTING_CHANGED);
+
+ private PreferenceCategory mCategoryLocationServices;
+ private final LocationSettings mFragment;
+ private final SettingsInjector mInjector;
+ /** Receives UPDATE_INTENT */
+ @VisibleForTesting
+ BroadcastReceiver mInjectedSettingsReceiver;
+
+ public LocationServicePreferenceController(Context context, LocationSettings fragment,
+ Lifecycle lifecycle) {
+ this(context, fragment, lifecycle, new SettingsInjector(context));
+ }
+
+ @VisibleForTesting
+ LocationServicePreferenceController(Context context, LocationSettings fragment,
+ Lifecycle lifecycle, SettingsInjector injector) {
+ super(context, lifecycle);
+ mFragment = fragment;
+ mInjector = injector;
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_LOCATION_SERVICES;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ // If managed profile has lock-down on location access then its injected location services
+ // must not be shown.
+ return mInjector.hasInjectedSettings(mLocationEnabler.isManagedProfileRestrictedByBase()
+ ? UserHandle.myUserId() : UserHandle.USER_CURRENT);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mCategoryLocationServices =
+ (PreferenceCategory) screen.findPreference(KEY_LOCATION_SERVICES);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ mCategoryLocationServices.removeAll();
+ LocationSettings.addPreferencesSorted(getLocationServices(), mCategoryLocationServices);
+ }
+
+ @Override
+ public void onLocationModeChanged(int mode, boolean restricted) {
+ // As a safety measure, also reloads on location mode change to ensure the settings are
+ // up-to-date even if an affected app doesn't send the setting changed broadcast.
+ mInjector.reloadStatusMessages();
+ }
+
+ @Override
+ public void onResume() {
+ if (mInjectedSettingsReceiver == null) {
+ mInjectedSettingsReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Received settings change intent: " + intent);
+ }
+ mInjector.reloadStatusMessages();
+ }
+ };
+ }
+ mContext.registerReceiver(
+ mInjectedSettingsReceiver, INTENT_FILTER_INJECTED_SETTING_CHANGED);
+ }
+
+ @Override
+ public void onPause() {
+ mContext.unregisterReceiver(mInjectedSettingsReceiver);
+ }
+
+ private List<Preference> getLocationServices() {
+ // If location access is locked down by device policy then we only show injected settings
+ // for the primary profile.
+ return mInjector.getInjectedSettings(mFragment.getPreferenceManager().getContext(),
+ mLocationEnabler.isManagedProfileRestrictedByBase()
+ ? UserHandle.myUserId() : UserHandle.USER_CURRENT);
+ }
+}
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index 7d61f7f..3330421 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -16,37 +16,23 @@
package com.android.settings.location;
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
import android.app.Activity;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.location.SettingInjectorService;
import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.UserManager;
import android.provider.SearchIndexableResource;
import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceGroup;
-import android.support.v7.preference.PreferenceScreen;
-import android.util.Log;
-import android.widget.Switch;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
-import com.android.settings.Utils;
-import com.android.settings.applications.InstalledAppDetails;
+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.AppPreference;
-import com.android.settings.widget.SwitchBar;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.location.RecentLocationApps;
import java.util.ArrayList;
@@ -80,34 +66,11 @@
* other things, this simplifies integration with future changes to the default (AOSP)
* implementation.
*/
-public class LocationSettings extends LocationSettingsBase
- implements SwitchBar.OnSwitchChangeListener, Indexable {
+public class LocationSettings extends DashboardFragment {
private static final String TAG = "LocationSettings";
- /**
- * Key for managed profile location switch preference. Shown only
- * if there is a managed profile.
- */
- private static final String KEY_MANAGED_PROFILE_SWITCH = "managed_profile_location_switch";
- /** Key for preference screen "Mode" */
- private static final String KEY_LOCATION_MODE = "location_mode";
- /** Key for preference category "Recent location requests" */
- private static final String KEY_RECENT_LOCATION_REQUESTS = "recent_location_requests";
- /** Key for preference category "Location services" */
- private static final String KEY_LOCATION_SERVICES = "location_services";
-
- private SwitchBar mSwitchBar;
- private Switch mSwitch;
- private boolean mValidListener = false;
- private UserHandle mManagedProfile;
- private RestrictedSwitchPreference mManagedProfileSwitch;
- private Preference mLocationMode;
- private PreferenceCategory mCategoryRecentLocationRequests;
- /** Receives UPDATE_INTENT */
- private BroadcastReceiver mReceiver;
- private SettingsInjector injector;
- private UserManager mUm;
+ private LocationSwitchBarController mSwitchBarController;
@Override
public int getMetricsCategory() {
@@ -117,52 +80,27 @@
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
-
final SettingsActivity activity = (SettingsActivity) getActivity();
- mUm = (UserManager) activity.getSystemService(Context.USER_SERVICE);
-
- setHasOptionsMenu(true);
- mSwitchBar = activity.getSwitchBar();
- mSwitch = mSwitchBar.getSwitch();
- mSwitchBar.show();
-
- setHasOptionsMenu(true);
+ mSwitchBarController = new LocationSwitchBarController(
+ activity, activity.getSwitchBar(), getLifecycle());
}
@Override
- public void onDestroyView() {
- super.onDestroyView();
- mSwitchBar.hide();
+ protected int getPreferenceScreenResId() {
+ return R.xml.location_settings;
}
@Override
- public void onResume() {
- super.onResume();
- createPreferenceHierarchy();
- if (!mValidListener) {
- mSwitchBar.addOnSwitchChangeListener(this);
- mValidListener = true;
- }
+ protected String getLogTag() {
+ return TAG;
}
@Override
- public void onPause() {
- try {
- getActivity().unregisterReceiver(mReceiver);
- } catch (RuntimeException e) {
- // Ignore exceptions caused by race condition
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Swallowing " + e);
- }
- }
- if (mValidListener) {
- mSwitchBar.removeOnSwitchChangeListener(this);
- mValidListener = false;
- }
- super.onPause();
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, this, getLifecycle());
}
- private void addPreferencesSorted(List<Preference> prefs, PreferenceGroup container) {
+ static void addPreferencesSorted(List<Preference> prefs, PreferenceGroup container) {
// If there's some items to display, sort the items and add them to the container.
Collections.sort(prefs, new Comparator<Preference>() {
@Override
@@ -175,259 +113,22 @@
}
}
- private PreferenceScreen createPreferenceHierarchy() {
- final SettingsActivity activity = (SettingsActivity) getActivity();
- PreferenceScreen root = getPreferenceScreen();
- if (root != null) {
- root.removeAll();
- }
- addPreferencesFromResource(R.xml.location_settings);
- root = getPreferenceScreen();
-
- setupManagedProfileCategory(root);
- mLocationMode = root.findPreference(KEY_LOCATION_MODE);
- mLocationMode.setOnPreferenceClickListener(
- new Preference.OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- activity.startPreferencePanel(
- LocationSettings.this,
- LocationMode.class.getName(), null,
- R.string.location_mode_screen_title, null, LocationSettings.this,
- 0);
- return true;
- }
- });
-
- RecentLocationApps recentApps = new RecentLocationApps(activity);
- List<RecentLocationApps.Request> recentLocationRequests = recentApps.getAppList();
-
- final AppLocationPermissionPreferenceController preferenceController =
- new AppLocationPermissionPreferenceController(activity);
- preferenceController.displayPreference(root);
-
- mCategoryRecentLocationRequests =
- (PreferenceCategory) root.findPreference(KEY_RECENT_LOCATION_REQUESTS);
-
- List<Preference> recentLocationPrefs = new ArrayList<>(recentLocationRequests.size());
- for (final RecentLocationApps.Request request : recentLocationRequests) {
- final AppPreference pref = new AppPreference(getPrefContext());
- pref.setSummary(request.contentDescription);
- pref.setIcon(request.icon);
- pref.setTitle(request.label);
- pref.setOnPreferenceClickListener(
- new PackageEntryClickedListener(request.packageName, request.userHandle));
- recentLocationPrefs.add(pref);
- }
- if (recentLocationRequests.size() > 0) {
- addPreferencesSorted(recentLocationPrefs, mCategoryRecentLocationRequests);
- } else {
- // If there's no item to display, add a "No recent apps" item.
- Preference banner = new AppPreference(getPrefContext());
- banner.setTitle(R.string.location_no_recent_apps);
- banner.setSelectable(false);
- mCategoryRecentLocationRequests.addPreference(banner);
- }
-
- boolean lockdownOnLocationAccess = false;
- // Checking if device policy has put a location access lock-down on the managed
- // profile. If managed profile has lock-down on location access then its
- // injected location services must not be shown.
- if (mManagedProfile != null
- && mUm.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, mManagedProfile)) {
- lockdownOnLocationAccess = true;
- }
- addLocationServices(activity, root, lockdownOnLocationAccess);
-
- refreshLocationMode();
- return root;
- }
-
- private void setupManagedProfileCategory(PreferenceScreen root) {
- // Looking for a managed profile. If there are no managed profiles then we are removing the
- // managed profile category.
- mManagedProfile = Utils.getManagedProfile(mUm);
- if (mManagedProfile == null) {
- // There is no managed profile
- root.removePreference(root.findPreference(KEY_MANAGED_PROFILE_SWITCH));
- mManagedProfileSwitch = null;
- } else {
- mManagedProfileSwitch = (RestrictedSwitchPreference)root
- .findPreference(KEY_MANAGED_PROFILE_SWITCH);
- mManagedProfileSwitch.setOnPreferenceClickListener(null);
- }
- }
-
- private void changeManagedProfileLocationAccessStatus(boolean mainSwitchOn) {
- if (mManagedProfileSwitch == null) {
- return;
- }
- mManagedProfileSwitch.setOnPreferenceClickListener(null);
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
- UserManager.DISALLOW_SHARE_LOCATION, mManagedProfile.getIdentifier());
- final boolean isRestrictedByBase = isManagedProfileRestrictedByBase();
- if (!isRestrictedByBase && admin != null) {
- mManagedProfileSwitch.setDisabledByAdmin(admin);
- mManagedProfileSwitch.setChecked(false);
- } else {
- boolean enabled = mainSwitchOn;
- mManagedProfileSwitch.setEnabled(enabled);
-
- int summaryResId = R.string.switch_off_text;
- if (!enabled) {
- mManagedProfileSwitch.setChecked(false);
- } else {
- mManagedProfileSwitch.setChecked(!isRestrictedByBase);
- summaryResId = (isRestrictedByBase ?
- R.string.switch_off_text : R.string.switch_on_text);
- mManagedProfileSwitch.setOnPreferenceClickListener(
- mManagedProfileSwitchClickListener);
- }
- mManagedProfileSwitch.setSummary(summaryResId);
- }
- }
-
- /**
- * Add the settings injected by external apps into the "App Settings" category. Hides the
- * category if there are no injected settings.
- *
- * Reloads the settings whenever receives
- * {@link SettingInjectorService#ACTION_INJECTED_SETTING_CHANGED}.
- */
- private void addLocationServices(Context context, PreferenceScreen root,
- boolean lockdownOnLocationAccess) {
- PreferenceCategory categoryLocationServices =
- (PreferenceCategory) root.findPreference(KEY_LOCATION_SERVICES);
- injector = new SettingsInjector(context);
- // If location access is locked down by device policy then we only show injected settings
- // for the primary profile.
- final Context prefContext = categoryLocationServices.getContext();
- final List<Preference> locationServices = injector.getInjectedSettings(prefContext,
- lockdownOnLocationAccess ? UserHandle.myUserId() : UserHandle.USER_CURRENT);
-
- mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Received settings change intent: " + intent);
- }
- injector.reloadStatusMessages();
- }
- };
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(SettingInjectorService.ACTION_INJECTED_SETTING_CHANGED);
- context.registerReceiver(mReceiver, filter);
-
- if (locationServices.size() > 0) {
- addPreferencesSorted(locationServices, categoryLocationServices);
- } else {
- // If there's no item to display, remove the whole category.
- root.removePreference(categoryLocationServices);
- }
- }
-
@Override
public int getHelpResource() {
return R.string.help_url_location_access;
}
- @Override
- public void onModeChanged(int mode, boolean restricted) {
- int modeDescription = LocationPreferenceController.getLocationString(mode);
- if (modeDescription != 0) {
- mLocationMode.setSummary(modeDescription);
- }
-
- // Restricted user can't change the location mode, so disable the master switch. But in some
- // corner cases, the location might still be enabled. In such case the master switch should
- // be disabled but checked.
- final boolean enabled = (mode != android.provider.Settings.Secure.LOCATION_MODE_OFF);
- EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
- UserManager.DISALLOW_SHARE_LOCATION, UserHandle.myUserId());
- boolean hasBaseUserRestriction = RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
- UserManager.DISALLOW_SHARE_LOCATION, UserHandle.myUserId());
- // Disable the whole switch bar instead of the switch itself. If we disabled the switch
- // only, it would be re-enabled again if the switch bar is not disabled.
- if (!hasBaseUserRestriction && admin != null) {
- mSwitchBar.setDisabledByAdmin(admin);
- } else {
- mSwitchBar.setEnabled(!restricted);
- }
- mLocationMode.setEnabled(enabled && !restricted);
- mCategoryRecentLocationRequests.setEnabled(enabled);
-
- if (enabled != mSwitch.isChecked()) {
- // set listener to null so that that code below doesn't trigger onCheckedChanged()
- if (mValidListener) {
- mSwitchBar.removeOnSwitchChangeListener(this);
- }
- mSwitch.setChecked(enabled);
- if (mValidListener) {
- mSwitchBar.addOnSwitchChangeListener(this);
- }
- }
-
- changeManagedProfileLocationAccessStatus(enabled);
-
- // As a safety measure, also reloads on location mode change to ensure the settings are
- // up-to-date even if an affected app doesn't send the setting changed broadcast.
- injector.reloadStatusMessages();
- }
-
- /**
- * Listens to the state change of the location master switch.
- */
- @Override
- public void onSwitchChanged(Switch switchView, boolean isChecked) {
- if (isChecked) {
- setLocationMode(android.provider.Settings.Secure.LOCATION_MODE_PREVIOUS);
- } else {
- setLocationMode(android.provider.Settings.Secure.LOCATION_MODE_OFF);
- }
- }
-
- private boolean isManagedProfileRestrictedByBase() {
- if (mManagedProfile == null) {
- return false;
- }
- return mUm.hasBaseUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, mManagedProfile);
- }
-
- private Preference.OnPreferenceClickListener mManagedProfileSwitchClickListener =
- new Preference.OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- final boolean switchState = mManagedProfileSwitch.isChecked();
- mUm.setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION,
- !switchState, mManagedProfile);
- mManagedProfileSwitch.setSummary(switchState ?
- R.string.switch_on_text : R.string.switch_off_text);
- return true;
- }
- };
-
- private class PackageEntryClickedListener
- implements Preference.OnPreferenceClickListener {
- private String mPackage;
- private UserHandle mUserHandle;
-
- public PackageEntryClickedListener(String packageName, UserHandle userHandle) {
- mPackage = packageName;
- mUserHandle = userHandle;
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- // start new fragment to display extended information
- Bundle args = new Bundle();
- args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mPackage);
- ((SettingsActivity) getActivity()).startPreferencePanelAsUser(
- LocationSettings.this,
- InstalledAppDetails.class.getName(), args,
- R.string.application_info_label, null, mUserHandle);
- return true;
- }
+ private static List<AbstractPreferenceController> buildPreferenceControllers(
+ Context context, LocationSettings fragment, Lifecycle lifecycle) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new LocationModePreferenceController(context, fragment, lifecycle));
+ controllers.add(new AppLocationPermissionPreferenceController(context));
+ controllers.add(new LocationForWorkPreferenceController(context, lifecycle));
+ controllers.add(
+ new RecentLocationRequestPreferenceController(context, fragment, lifecycle));
+ controllers.add(
+ new LocationServicePreferenceController(context, fragment, lifecycle));
+ return controllers;
}
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
@@ -470,5 +171,12 @@
sir.xmlResId = R.xml.location_settings;
return Arrays.asList(sir);
}
+
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context
+ context) {
+ return buildPreferenceControllers(context, null /* fragment */,
+ null /* lifecycle */);
+ }
};
}
diff --git a/src/com/android/settings/location/LocationSettingsBase.java b/src/com/android/settings/location/LocationSettingsBase.java
deleted file mode 100644
index 741d607..0000000
--- a/src/com/android/settings/location/LocationSettingsBase.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.settings.location;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.location.LocationManager;
-import android.os.Bundle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.settings.SettingsPreferenceFragment;
-
-/**
- * A base class that listens to location settings change and modifies location
- * settings.
- */
-public abstract class LocationSettingsBase extends SettingsPreferenceFragment {
- private static final String TAG = "LocationSettingsBase";
- /** Broadcast intent action when the location mode is about to change. */
- private static final String MODE_CHANGING_ACTION =
- "com.android.settings.location.MODE_CHANGING";
- private static final String CURRENT_MODE_KEY = "CURRENT_MODE";
- private static final String NEW_MODE_KEY = "NEW_MODE";
-
- private int mCurrentMode;
- private BroadcastReceiver mReceiver;
-
- /**
- * Whether the fragment is actively running.
- */
- private boolean mActive = false;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Received location mode change intent: " + intent);
- }
- refreshLocationMode();
- }
- };
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mActive = true;
- IntentFilter filter = new IntentFilter();
- filter.addAction(LocationManager.MODE_CHANGED_ACTION);
- getActivity().registerReceiver(mReceiver, filter);
- }
-
- @Override
- public void onPause() {
- try {
- getActivity().unregisterReceiver(mReceiver);
- } catch (RuntimeException e) {
- // Ignore exceptions caused by race condition
- }
- super.onPause();
- mActive = false;
- }
-
- /** Called when location mode has changed. */
- public abstract void onModeChanged(int mode, boolean restricted);
-
- public static boolean isRestricted(Context context) {
- final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
- return um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION);
- }
-
- public static boolean updateLocationMode(Context context, int oldMode, int newMode) {
- Intent intent = new Intent(MODE_CHANGING_ACTION);
- intent.putExtra(CURRENT_MODE_KEY, oldMode);
- intent.putExtra(NEW_MODE_KEY, newMode);
- context.sendBroadcast(intent, android.Manifest.permission.WRITE_SECURE_SETTINGS);
- return Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE,
- newMode);
- }
-
- public void setLocationMode(int mode) {
- Context context = getActivity();
- if (isRestricted(context)) {
- // Location toggling disabled by user restriction. Read the current location mode to
- // update the location master switch.
- if (Log.isLoggable(TAG, Log.INFO)) {
- Log.i(TAG, "Restricted user, not setting location mode");
- }
- mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE,
- Settings.Secure.LOCATION_MODE_OFF);
- if (mActive) {
- onModeChanged(mode, true);
- }
- return;
- }
-
- updateLocationMode(context, mCurrentMode, mode);
- refreshLocationMode();
- }
-
- public void refreshLocationMode() {
- if (mActive) {
- int mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE,
- Settings.Secure.LOCATION_MODE_OFF);
- mCurrentMode = mode;
- if (Log.isLoggable(TAG, Log.INFO)) {
- Log.i(TAG, "Location mode has been changed");
- }
- onModeChanged(mode, isRestricted(getActivity()));
- }
- }
-}
diff --git a/src/com/android/settings/location/LocationSwitchBarController.java b/src/com/android/settings/location/LocationSwitchBarController.java
new file mode 100644
index 0000000..6522dc7
--- /dev/null
+++ b/src/com/android/settings/location/LocationSwitchBarController.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.settings.location;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.widget.Switch;
+
+import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+public class LocationSwitchBarController implements SwitchBar.OnSwitchChangeListener,
+ LocationEnabler.LocationModeChangeListener, LifecycleObserver, OnStart, OnStop {
+
+ private final SwitchBar mSwitchBar;
+ private final Switch mSwitch;
+ private final LocationEnabler mLocationEnabler;
+ private boolean mValidListener;
+
+ public LocationSwitchBarController(Context context, SwitchBar switchBar,
+ Lifecycle lifecycle) {
+ mSwitchBar = switchBar;
+ mSwitch = mSwitchBar.getSwitch();
+ mLocationEnabler = new LocationEnabler(context, this /* listener */, lifecycle);
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public void onStart() {
+ if (!mValidListener) {
+ mSwitchBar.addOnSwitchChangeListener(this);
+ mValidListener = true;
+ }
+ mSwitchBar.show();
+ }
+
+ @Override
+ public void onStop() {
+ mSwitchBar.hide();
+ if (mValidListener) {
+ mSwitchBar.removeOnSwitchChangeListener(this);
+ mValidListener = false;
+ }
+ }
+
+ @Override
+ public void onLocationModeChanged(int mode, boolean restricted) {
+ // Restricted user can't change the location mode, so disable the master switch. But in some
+ // corner cases, the location might still be enabled. In such case the master switch should
+ // be disabled but checked.
+ final boolean enabled = mLocationEnabler.isEnabled(mode);
+ final int userId = UserHandle.myUserId();
+ final RestrictedLockUtils.EnforcedAdmin admin =
+ mLocationEnabler.getShareLocationEnforcedAdmin(userId);
+ final boolean hasBaseUserRestriction =
+ mLocationEnabler.hasShareLocationRestriction(userId);
+ // Disable the whole switch bar instead of the switch itself. If we disabled the switch
+ // only, it would be re-enabled again if the switch bar is not disabled.
+ if (!hasBaseUserRestriction && admin != null) {
+ mSwitchBar.setDisabledByAdmin(admin);
+ } else {
+ mSwitchBar.setEnabled(!restricted);
+ }
+
+ if (enabled != mSwitch.isChecked()) {
+ // set listener to null so that that code below doesn't trigger onCheckedChanged()
+ if (mValidListener) {
+ mSwitchBar.removeOnSwitchChangeListener(this);
+ }
+ mSwitch.setChecked(enabled);
+ if (mValidListener) {
+ mSwitchBar.addOnSwitchChangeListener(this);
+ }
+ }
+ }
+
+ /**
+ * Listens to the state change of the location master switch.
+ */
+ @Override
+ public void onSwitchChanged(Switch switchView, boolean isChecked) {
+ mLocationEnabler.setLocationMode(isChecked
+ ? android.provider.Settings.Secure.LOCATION_MODE_PREVIOUS
+ : android.provider.Settings.Secure.LOCATION_MODE_OFF);
+ }
+
+}
diff --git a/src/com/android/settings/location/RecentLocationRequestPreferenceController.java b/src/com/android/settings/location/RecentLocationRequestPreferenceController.java
new file mode 100644
index 0000000..92e5169
--- /dev/null
+++ b/src/com/android/settings/location/RecentLocationRequestPreferenceController.java
@@ -0,0 +1,137 @@
+/*
+ * 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.location;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.applications.InstalledAppDetails;
+import com.android.settings.widget.AppPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.location.RecentLocationApps;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RecentLocationRequestPreferenceController extends LocationBasePreferenceController {
+
+ /** Key for preference category "Recent location requests" */
+ private static final String KEY_RECENT_LOCATION_REQUESTS = "recent_location_requests";
+ private final LocationSettings mFragment;
+ private final RecentLocationApps mRecentLocationApps;
+ private PreferenceCategory mCategoryRecentLocationRequests;
+
+ @VisibleForTesting
+ static class PackageEntryClickedListener implements Preference.OnPreferenceClickListener {
+ private final LocationSettings mFragment;
+ private final String mPackage;
+ private final UserHandle mUserHandle;
+
+ public PackageEntryClickedListener(LocationSettings fragment, String packageName,
+ UserHandle userHandle) {
+ mFragment = fragment;
+ mPackage = packageName;
+ mUserHandle = userHandle;
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ // start new fragment to display extended information
+ final Bundle args = new Bundle();
+ args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mPackage);
+ ((SettingsActivity) mFragment.getActivity()).startPreferencePanelAsUser(
+ mFragment,
+ InstalledAppDetails.class.getName(), args,
+ R.string.application_info_label, null, mUserHandle);
+ return true;
+ }
+ }
+
+ public RecentLocationRequestPreferenceController(Context context, LocationSettings fragment,
+ Lifecycle lifecycle) {
+ this(context, fragment, lifecycle, new RecentLocationApps(context));
+ }
+
+ @VisibleForTesting
+ RecentLocationRequestPreferenceController(Context context, LocationSettings fragment,
+ Lifecycle lifecycle, RecentLocationApps recentApps) {
+ super(context, lifecycle);
+ mFragment = fragment;
+ mRecentLocationApps = recentApps;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_RECENT_LOCATION_REQUESTS;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mCategoryRecentLocationRequests =
+ (PreferenceCategory) screen.findPreference(KEY_RECENT_LOCATION_REQUESTS);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ mCategoryRecentLocationRequests.removeAll();
+
+ final Context prefContext = preference.getContext();
+ final List<RecentLocationApps.Request> recentLocationRequests =
+ mRecentLocationApps.getAppList();
+
+ final List<Preference> recentLocationPrefs = new ArrayList<>(recentLocationRequests.size());
+ for (final RecentLocationApps.Request request : recentLocationRequests) {
+ recentLocationPrefs.add(createAppPreference(prefContext, request));
+ }
+ if (recentLocationRequests.size() > 0) {
+ LocationSettings.addPreferencesSorted(
+ recentLocationPrefs, mCategoryRecentLocationRequests);
+ } else {
+ // If there's no item to display, add a "No recent apps" item.
+ final Preference banner = createAppPreference(prefContext);
+ banner.setTitle(R.string.location_no_recent_apps);
+ banner.setSelectable(false);
+ mCategoryRecentLocationRequests.addPreference(banner);
+ }
+ }
+
+ @Override
+ public void onLocationModeChanged(int mode, boolean restricted) {
+ mCategoryRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode));
+ }
+
+ @VisibleForTesting
+ AppPreference createAppPreference(Context prefContext) {
+ return new AppPreference(prefContext);
+ }
+
+ @VisibleForTesting
+ AppPreference createAppPreference(Context prefContext, RecentLocationApps.Request request) {
+ final AppPreference pref = createAppPreference(prefContext);
+ pref.setSummary(request.contentDescription);
+ pref.setIcon(request.icon);
+ pref.setTitle(request.label);
+ pref.setOnPreferenceClickListener(new PackageEntryClickedListener(
+ mFragment, request.packageName, request.userHandle));
+ return pref;
+ }
+}
diff --git a/src/com/android/settings/location/ScanningSettings.java b/src/com/android/settings/location/ScanningSettings.java
index 5c34b62..4585870 100644
--- a/src/com/android/settings/location/ScanningSettings.java
+++ b/src/com/android/settings/location/ScanningSettings.java
@@ -18,26 +18,23 @@
import android.content.Context;
import android.provider.SearchIndexableResource;
-import android.provider.Settings.Global;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
+import com.android.settingslib.core.AbstractPreferenceController;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* A page that configures the background scanning settings for Wi-Fi and Bluetooth.
*/
-public class ScanningSettings extends SettingsPreferenceFragment implements Indexable {
- private static final String KEY_WIFI_SCAN_ALWAYS_AVAILABLE = "wifi_always_scanning";
- private static final String KEY_BLUETOOTH_SCAN_ALWAYS_AVAILABLE = "bluetooth_always_scanning";
+public class ScanningSettings extends DashboardFragment {
+ private static final String TAG = "ScanningSettings";
@Override
public int getMetricsCategory() {
@@ -45,48 +42,25 @@
}
@Override
- public void onResume() {
- super.onResume();
- createPreferenceHierarchy();
- }
-
- private PreferenceScreen createPreferenceHierarchy() {
- PreferenceScreen root = getPreferenceScreen();
- if (root != null) {
- root.removeAll();
- }
- addPreferencesFromResource(R.xml.location_scanning);
- root = getPreferenceScreen();
- initPreferences();
- return root;
- }
-
- private void initPreferences() {
- final SwitchPreference wifiScanAlwaysAvailable =
- (SwitchPreference) findPreference(KEY_WIFI_SCAN_ALWAYS_AVAILABLE);
- wifiScanAlwaysAvailable.setChecked(Global.getInt(getContentResolver(),
- Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1);
- final SwitchPreference bleScanAlwaysAvailable =
- (SwitchPreference) findPreference(KEY_BLUETOOTH_SCAN_ALWAYS_AVAILABLE);
- bleScanAlwaysAvailable.setChecked(Global.getInt(getContentResolver(),
- Global.BLE_SCAN_ALWAYS_AVAILABLE, 0) == 1);
+ protected int getPreferenceScreenResId() {
+ return R.xml.location_scanning;
}
@Override
- public boolean onPreferenceTreeClick(Preference preference) {
- String key = preference.getKey();
- if (KEY_WIFI_SCAN_ALWAYS_AVAILABLE.equals(key)) {
- Global.putInt(getContentResolver(),
- Global.WIFI_SCAN_ALWAYS_AVAILABLE,
- ((SwitchPreference) preference).isChecked() ? 1 : 0);
- } else if (KEY_BLUETOOTH_SCAN_ALWAYS_AVAILABLE.equals(key)) {
- Global.putInt(getContentResolver(),
- Global.BLE_SCAN_ALWAYS_AVAILABLE,
- ((SwitchPreference) preference).isChecked() ? 1 : 0);
- } else {
- return super.onPreferenceTreeClick(preference);
- }
- return true;
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context);
+ }
+
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new WifiScanningPreferenceController(context));
+ controllers.add(new BluetoothScanningPreferenceController(context));
+ return controllers;
}
/**
@@ -101,5 +75,11 @@
sir.xmlResId = R.xml.location_scanning;
return Arrays.asList(sir);
}
+
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context
+ context) {
+ return buildPreferenceControllers(context);
+ }
};
}
diff --git a/src/com/android/settings/location/SettingsInjector.java b/src/com/android/settings/location/SettingsInjector.java
index c6d1f37..dfa5143 100644
--- a/src/com/android/settings/location/SettingsInjector.java
+++ b/src/com/android/settings/location/SettingsInjector.java
@@ -30,6 +30,7 @@
import android.location.SettingInjectorService;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.SystemClock;
@@ -253,6 +254,28 @@
}
/**
+ * Checks wheteher there is any preference that other apps have injected.
+ *
+ * @param profileId Identifier of the user/profile to obtain the injected settings for or
+ * UserHandle.USER_CURRENT for all profiles associated with current user.
+ */
+ public boolean hasInjectedSettings(final int profileId) {
+ final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ final List<UserHandle> profiles = um.getUserProfiles();
+ final int profileCount = profiles.size();
+ for (int i = 0; i < profileCount; ++i) {
+ final UserHandle userHandle = profiles.get(i);
+ if (profileId == UserHandle.USER_CURRENT || profileId == userHandle.getIdentifier()) {
+ Iterable<InjectedSetting> settings = getSettings(userHandle);
+ for (InjectedSetting setting : settings) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* Reloads the status messages for all the preference items.
*/
public void reloadStatusMessages() {
@@ -338,6 +361,9 @@
private boolean mReloadRequested;
+ private StatusLoadingHandler() {
+ super(Looper.getMainLooper());
+ }
@Override
public void handleMessage(Message msg) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
diff --git a/src/com/android/settings/location/WifiScanningPreferenceController.java b/src/com/android/settings/location/WifiScanningPreferenceController.java
new file mode 100644
index 0000000..8d4cf98
--- /dev/null
+++ b/src/com/android/settings/location/WifiScanningPreferenceController.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.settings.location;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class WifiScanningPreferenceController extends AbstractPreferenceController
+ implements PreferenceControllerMixin {
+
+ private static final String KEY_WIFI_SCAN_ALWAYS_AVAILABLE = "wifi_always_scanning";
+
+ public WifiScanningPreferenceController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_WIFI_SCAN_ALWAYS_AVAILABLE;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ ((SwitchPreference) preference).setChecked(
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1);
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (KEY_WIFI_SCAN_ALWAYS_AVAILABLE.equals(preference.getKey())) {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
+ ((SwitchPreference) preference).isChecked() ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/settings/network/AirplaneModePreferenceController.java b/src/com/android/settings/network/AirplaneModePreferenceController.java
index d2015df..0620f14 100644
--- a/src/com/android/settings/network/AirplaneModePreferenceController.java
+++ b/src/com/android/settings/network/AirplaneModePreferenceController.java
@@ -81,7 +81,7 @@
mMetricsFeatureProvider);
}
} else {
- removePreference(screen, getPreferenceKey());
+ setVisible(screen, getPreferenceKey(), false /* visible */);
}
}
@@ -91,7 +91,7 @@
}
public static boolean isAvailable(Context context) {
- return !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION);
+ return !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
}
@Override
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index e982a28..2a04d27 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -48,8 +48,11 @@
MobilePlanPreferenceHost {
private static final String TAG = "NetworkDashboardFrag";
+ private static final int MENU_NETWORK_RESET = Menu.FIRST;
+ private static final int MENU_PRIVATE_DNS = Menu.FIRST + 1;
private NetworkResetActionMenuController mNetworkResetController;
+ private PrivateDnsMenuController mPrivateDnsMenuController;
@Override
public int getMetricsCategory() {
@@ -69,7 +72,9 @@
@Override
public void onAttach(Context context) {
super.onAttach(context);
- mNetworkResetController = new NetworkResetActionMenuController(context);
+ mNetworkResetController = new NetworkResetActionMenuController(context, MENU_NETWORK_RESET);
+ mPrivateDnsMenuController = new PrivateDnsMenuController(getFragmentManager(),
+ MENU_PRIVATE_DNS);
}
@Override
@@ -81,6 +86,7 @@
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
mNetworkResetController.buildMenuItem(menu);
+ mPrivateDnsMenuController.buildMenuItem(menu);
}
@Override
diff --git a/src/com/android/settings/network/NetworkResetActionMenuController.java b/src/com/android/settings/network/NetworkResetActionMenuController.java
index 254834b..75db65e 100644
--- a/src/com/android/settings/network/NetworkResetActionMenuController.java
+++ b/src/com/android/settings/network/NetworkResetActionMenuController.java
@@ -27,19 +27,20 @@
public class NetworkResetActionMenuController {
- private static final int MENU_NETWORK_RESET = Menu.FIRST + 200;
private final Context mContext;
private final NetworkResetRestrictionChecker mRestrictionChecker;
+ private final int mMenuId;
- public NetworkResetActionMenuController(Context context) {
+ public NetworkResetActionMenuController(Context context, int menuId) {
mContext = context;
mRestrictionChecker = new NetworkResetRestrictionChecker(context);
+ mMenuId = menuId;
}
public void buildMenuItem(Menu menu) {
MenuItem item = null;
if (isAvailable() && menu != null) {
- item = menu.add(0, MENU_NETWORK_RESET, 0, R.string.reset_network_title);
+ item = menu.add(0, mMenuId, 0, R.string.reset_network_title);
}
if (item != null) {
item.setOnMenuItemClickListener(target -> {
diff --git a/src/com/android/settings/network/PrivateDnsMenuController.java b/src/com/android/settings/network/PrivateDnsMenuController.java
new file mode 100644
index 0000000..a811775
--- /dev/null
+++ b/src/com/android/settings/network/PrivateDnsMenuController.java
@@ -0,0 +1,44 @@
+/*
+ * 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.network;
+
+import android.app.FragmentManager;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.android.settings.R;
+
+public class PrivateDnsMenuController {
+ private final FragmentManager mFragmentManager;
+ private final int mMenuId;
+
+ public PrivateDnsMenuController(FragmentManager fragmentManager, int menuId) {
+ mFragmentManager = fragmentManager;
+ mMenuId = menuId;
+ }
+
+ public void buildMenuItem(Menu menu) {
+ if (menu != null) {
+ MenuItem item = menu.add(0 /* groupId */, mMenuId, 0 /* order */,
+ R.string.select_private_dns_configuration_title);
+ item.setOnMenuItemClickListener(target -> {
+ PrivateDnsModeDialogFragment.show(mFragmentManager);
+ return true;
+ });
+ }
+ }
+}
diff --git a/src/com/android/settings/network/PrivateDnsModeDialogFragment.java b/src/com/android/settings/network/PrivateDnsModeDialogFragment.java
new file mode 100644
index 0000000..cb3079e
--- /dev/null
+++ b/src/com/android/settings/network/PrivateDnsModeDialogFragment.java
@@ -0,0 +1,168 @@
+/*
+ * 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.network;
+
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.FragmentManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.RadioGroup;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Dialog to set the private dns
+ */
+public class PrivateDnsModeDialogFragment extends InstrumentedDialogFragment implements
+ DialogInterface.OnClickListener, RadioGroup.OnCheckedChangeListener, TextWatcher {
+
+ private static final String TAG = "PrivateDnsModeDialogFragment";
+ // DNS_MODE -> RadioButton id
+ private static final Map<String, Integer> PRIVATE_DNS_MAP;
+
+ static {
+ PRIVATE_DNS_MAP = new HashMap<>();
+ PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_OFF, R.id.private_dns_mode_off);
+ PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_OPPORTUNISTIC, R.id.private_dns_mode_opportunistic);
+ PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, R.id.private_dns_mode_provider);
+ }
+
+ @VisibleForTesting
+ static final String MODE_KEY = Settings.Global.PRIVATE_DNS_MODE;
+ @VisibleForTesting
+ static final String HOSTNAME_KEY = Settings.Global.PRIVATE_DNS_SPECIFIER;
+
+ @VisibleForTesting
+ EditText mEditText;
+ @VisibleForTesting
+ RadioGroup mRadioGroup;
+ @VisibleForTesting
+ String mMode;
+
+ public static void show(FragmentManager fragmentManager) {
+ if (fragmentManager.findFragmentByTag(TAG) == null) {
+ final PrivateDnsModeDialogFragment fragment = new PrivateDnsModeDialogFragment();
+ fragment.show(fragmentManager, TAG);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Context context = getContext();
+
+ return new AlertDialog.Builder(context)
+ .setTitle(R.string.select_private_dns_configuration_title)
+ .setView(buildPrivateDnsView(context))
+ .setPositiveButton(R.string.save, this)
+ .setNegativeButton(R.string.dlg_cancel, null)
+ .create();
+ }
+
+ private View buildPrivateDnsView(final Context context) {
+ final ContentResolver contentResolver = context.getContentResolver();
+ final String mode = Settings.Global.getString(contentResolver, MODE_KEY);
+ final View view = LayoutInflater.from(context).inflate(R.layout.private_dns_mode_dialog,
+ null);
+
+ mEditText = view.findViewById(R.id.private_dns_mode_provider_hostname);
+ mEditText.addTextChangedListener(this);
+ mEditText.setText(Settings.Global.getString(contentResolver, HOSTNAME_KEY));
+
+ mRadioGroup = view.findViewById(R.id.private_dns_radio_group);
+ mRadioGroup.setOnCheckedChangeListener(this);
+ mRadioGroup.check(PRIVATE_DNS_MAP.getOrDefault(mode, R.id.private_dns_mode_opportunistic));
+
+ return view;
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ //TODO(b/34953048): add metric action
+ if (mMode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
+ // Only clickable if hostname is valid, so we could save it safely
+ Settings.Global.putString(getContext().getContentResolver(), HOSTNAME_KEY,
+ mEditText.getText().toString());
+ }
+
+ Settings.Global.putString(getContext().getContentResolver(), MODE_KEY, mMode);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ //TODO(b/68030013): add metric id
+ return 0;
+ }
+
+ @Override
+ public void onCheckedChanged(RadioGroup group, int checkedId) {
+ switch (checkedId) {
+ case R.id.private_dns_mode_off:
+ mMode = PRIVATE_DNS_MODE_OFF;
+ mEditText.setEnabled(false);
+ break;
+ case R.id.private_dns_mode_opportunistic:
+ mMode = PRIVATE_DNS_MODE_OPPORTUNISTIC;
+ mEditText.setEnabled(false);
+ break;
+ case R.id.private_dns_mode_provider:
+ mMode = PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+ mEditText.setEnabled(true);
+ break;
+ }
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ // TODO(b/68030013): Disable the "positive button" ("Save") when appearsValid is false.
+ final boolean valid = isWeaklyValidatedHostname(s.toString());
+ }
+
+ private boolean isWeaklyValidatedHostname(String hostname) {
+ // TODO(b/34953048): Find and use a better validation method. Specifically:
+ // [1] this should reject IP string literals, and
+ // [2] do the best, simplest, future-proof verification that
+ // the input approximates a DNS hostname.
+ final String WEAK_HOSTNAME_REGEX = "^[a-zA-Z0-9_.-]+$";
+ return hostname.matches(WEAK_HOSTNAME_REGEX);
+ }
+
+}
diff --git a/src/com/android/settings/nfc/AndroidBeam.java b/src/com/android/settings/nfc/AndroidBeam.java
index fcdc630..707017b 100644
--- a/src/com/android/settings/nfc/AndroidBeam.java
+++ b/src/com/android/settings/nfc/AndroidBeam.java
@@ -98,9 +98,7 @@
mSwitchBar.show();
}
- if (usePreferenceScreenTitle()) {
- activity.setTitle(R.string.android_beam_settings_title);
- }
+ activity.setTitle(R.string.android_beam_settings_title);
}
@Override
diff --git a/src/com/android/settings/nfc/NfcPreferenceController.java b/src/com/android/settings/nfc/NfcPreferenceController.java
index a034777..76977d2 100644
--- a/src/com/android/settings/nfc/NfcPreferenceController.java
+++ b/src/com/android/settings/nfc/NfcPreferenceController.java
@@ -26,9 +26,9 @@
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
@@ -55,8 +55,8 @@
@Override
public void displayPreference(PreferenceScreen screen) {
if (!isAvailable()) {
- removePreference(screen, KEY_TOGGLE_NFC);
- removePreference(screen, KEY_ANDROID_BEAM_SETTINGS);
+ setVisible(screen, KEY_TOGGLE_NFC, false /* visible */);
+ setVisible(screen, KEY_ANDROID_BEAM_SETTINGS, false /* visible */);
mNfcEnabler = null;
return;
}
diff --git a/src/com/android/settings/nfc/PaymentSettings.java b/src/com/android/settings/nfc/PaymentSettings.java
index a30cea3..c832dfc 100644
--- a/src/com/android/settings/nfc/PaymentSettings.java
+++ b/src/com/android/settings/nfc/PaymentSettings.java
@@ -63,13 +63,7 @@
mPaymentBackend = new PaymentBackend(getActivity());
setHasOptionsMenu(true);
- final PreferenceScreen screen;
- if (usePreferenceScreenTitle()) {
- screen = getPreferenceScreen();
- } else {
- PreferenceManager manager = getPreferenceManager();
- screen = manager.createPreferenceScreen(getActivity());
- }
+ final PreferenceScreen screen = getPreferenceScreen();
List<PaymentBackend.PaymentAppInfo> appInfos = mPaymentBackend.getPaymentAppInfos();
if (appInfos != null && appInfos.size() > 0) {
@@ -81,9 +75,6 @@
mPaymentBackend);
screen.addPreference(foreground);
}
- if (!usePreferenceScreenTitle()) {
- setPreferenceScreen(screen);
- }
}
@Override
diff --git a/src/com/android/settings/notification/AllowSoundPreferenceController.java b/src/com/android/settings/notification/AllowSoundPreferenceController.java
new file mode 100644
index 0000000..dcd5e45
--- /dev/null
+++ b/src/com/android/settings/notification/AllowSoundPreferenceController.java
@@ -0,0 +1,81 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
+import android.app.NotificationChannel;
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+public class AllowSoundPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String TAG = "AllowSoundPrefContr";
+ private static final String KEY_IMPORTANCE = "allow_sound";
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+
+ public AllowSoundPreferenceController(Context context,
+ NotificationSettingsBase.ImportanceListener importanceListener,
+ NotificationBackend backend) {
+ super(context, backend);
+ mImportanceListener = importanceListener;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_IMPORTANCE;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ return mChannel != null && NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId());
+
+ }
+
+ public void updateState(Preference preference) {
+ if (mChannel != null) {
+ RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
+ pref.setDisabledByAdmin(mAdmin);
+ pref.setEnabled(isChannelConfigurable() && !pref.isDisabledByAdmin());
+ pref.setChecked(mChannel.getImportance() >= IMPORTANCE_DEFAULT
+ || mChannel.getImportance() == IMPORTANCE_UNSPECIFIED);
+ } else { Log.i(TAG, "tried to updatestate on a null channel?!"); }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mChannel != null) {
+ final int importance =
+ ((Boolean) newValue ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_LOW);
+ mChannel.setImportance(importance);
+ mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+ saveChannel();
+ mImportanceListener.onImportanceChanged();
+ }
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/AppLinkPreferenceController.java b/src/com/android/settings/notification/AppLinkPreferenceController.java
new file mode 100644
index 0000000..ff5945b
--- /dev/null
+++ b/src/com/android/settings/notification/AppLinkPreferenceController.java
@@ -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.notification;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+
+/**
+ * Controls link to reach more preference settings inside the app.
+ */
+public class AppLinkPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin {
+
+ private static final String TAG = "AppLinkPrefContr";
+ private static final String KEY_APP_LINK = "app_link";
+
+ public AppLinkPreferenceController(Context context) {
+ super(context, null);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_APP_LINK;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ return mAppRow.settingsIntent != null;
+ }
+
+ public void updateState(Preference preference) {
+ if (mAppRow != null) {
+ preference.setIntent(mAppRow.settingsIntent);
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 95c9560..af168d6 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -16,12 +16,10 @@
package com.android.settings.notification;
-import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
+import android.content.Context;
import android.content.Intent;
-import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings;
@@ -29,43 +27,29 @@
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceGroup;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.Switch;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.AppInfoBase;
-import com.android.settings.applications.LayoutPreference;
-import com.android.settings.notification.NotificationBackend.AppRow;
-import com.android.settings.widget.EntityHeaderController;
import com.android.settings.widget.MasterSwitchPreference;
-import com.android.settings.widget.SwitchBar;
-import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.widget.FooterPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-import static android.app.NotificationManager.IMPORTANCE_NONE;
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
-
/** These settings are per app, so should not be returned in global search results. */
public class AppNotificationSettings extends NotificationSettingsBase {
private static final String TAG = "AppNotificationSettings";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static String KEY_GENERAL_CATEGORY = "categories";
- private static String KEY_DELETED = "deleted";
private List<NotificationChannelGroup> mChannelGroupList;
- private List<PreferenceCategory> mChannelGroups = new ArrayList();
- private FooterPreference mDeletedChannels;
@Override
public int getMetricsCategory() {
@@ -84,24 +68,13 @@
if (getPreferenceScreen() != null) {
getPreferenceScreen().removeAll();
- mChannelGroups.clear();
- mDeletedChannels = null;
- mShowLegacyChannelConfig = false;
+ mDynamicPreferences.clear();
}
- addPreferencesFromResource(R.xml.notification_settings);
- getPreferenceScreen().setOrderingAsAdded(true);
- setupBlock();
- addHeaderPref();
-
- mShowLegacyChannelConfig = mBackend.onlyHasDefaultChannel(mAppRow.pkg, mAppRow.uid);
if (mShowLegacyChannelConfig) {
- mChannel = mBackend.getChannel(
- mAppRow.pkg, mAppRow.uid, NotificationChannel.DEFAULT_CHANNEL_ID);
- populateDefaultChannelPrefs();
+ addPreferencesFromResource(R.xml.channel_notification_settings);
} else {
- addPreferencesFromResource(R.xml.upgraded_app_notification_settings);
- setupBadge();
+ addPreferencesFromResource(R.xml.app_notification_settings);
// Load channel settings
new AsyncTask<Void, Void, Void>() {
@Override
@@ -117,41 +90,59 @@
return;
}
populateList();
- addAppLinkPref();
}
}.execute();
}
+ getPreferenceScreen().setOrderingAsAdded(true);
- updateDependents(mAppRow.banned);
+ for (NotificationPreferenceController controller : mControllers) {
+ controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
+ controller.displayPreference(getPreferenceScreen());
+ }
+ updatePreferenceStates();
}
- private void addHeaderPref() {
- ArrayMap<String, AppRow> rows = new ArrayMap<>();
- rows.put(mAppRow.pkg, mAppRow);
- collectConfigActivities(rows);
- final Activity activity = getActivity();
- final Preference pref = EntityHeaderController
- .newInstance(activity, this /* fragment */, null /* header */)
- .setRecyclerView(getListView(), getLifecycle())
- .setIcon(mAppRow.icon)
- .setLabel(mAppRow.label)
- .setPackageName(mAppRow.pkg)
- .setUid(mAppRow.uid)
- .setHasAppInfoLink(true)
- .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
- EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE)
- .done(activity, getPrefContext());
- pref.setKey(KEY_HEADER);
- getPreferenceScreen().addPreference(pref);
+ @Override
+ protected String getLogTag() {
+ return TAG;
}
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.notification_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ mControllers = new ArrayList<>();
+ mControllers.add(new HeaderPreferenceController(context, this));
+ mControllers.add(new BlockPreferenceController(context, mImportanceListener, mBackend));
+ mControllers.add(new BadgePreferenceController(context, mBackend));
+ mControllers.add(new AllowSoundPreferenceController(
+ context, mImportanceListener, mBackend));
+ mControllers.add(new ImportancePreferenceController(context));
+ mControllers.add(new SoundPreferenceController(context, this,
+ mImportanceListener, mBackend));
+ mControllers.add(new LightsPreferenceController(context, mBackend));
+ mControllers.add(new VibrationPreferenceController(context, mBackend));
+ mControllers.add(new VisibilityPreferenceController(context, new LockPatternUtils(context),
+ mBackend));
+ mControllers.add(new DndPreferenceController(context, getLifecycle(), mBackend));
+ mControllers.add(new AppLinkPreferenceController(context));
+ mControllers.add(new DescriptionPreferenceController(context));
+ mControllers.add(new NotificationsOffPreferenceController(context));
+ mControllers.add(new DeletedChannelsPreferenceController(context, mBackend));
+ return new ArrayList<>(mControllers);
+ }
+
+
private void populateList() {
- if (!mChannelGroups.isEmpty()) {
+ if (!mDynamicPreferences.isEmpty()) {
// If there's anything in mChannelGroups, we've called populateChannelList twice.
// Clear out existing channels and log.
Log.w(TAG, "Notification channel group posted twice to settings - old size " +
- mChannelGroups.size() + ", new size " + mChannelGroupList.size());
- for (Preference p : mChannelGroups) {
+ mDynamicPreferences.size() + ", new size " + mChannelGroupList.size());
+ for (Preference p : mDynamicPreferences) {
getPreferenceScreen().removePreference(p);
}
}
@@ -160,7 +151,7 @@
groupCategory.setTitle(R.string.notification_channels);
groupCategory.setKey(KEY_GENERAL_CATEGORY);
getPreferenceScreen().addPreference(groupCategory);
- mChannelGroups.add(groupCategory);
+ mDynamicPreferences.add(groupCategory);
Preference empty = new Preference(getPrefContext());
empty.setTitle(R.string.no_channels);
@@ -168,20 +159,8 @@
groupCategory.addPreference(empty);
} else {
populateGroupList();
- int deletedChannelCount = mBackend.getDeletedChannelCount(mAppRow.pkg, mAppRow.uid);
- if (deletedChannelCount > 0 &&
- getPreferenceScreen().findPreference(KEY_DELETED) == null) {
- mDeletedChannels = new FooterPreference(getPrefContext());
- mDeletedChannels.setSelectable(false);
- mDeletedChannels.setTitle(getResources().getQuantityString(
- R.plurals.deleted_channels, deletedChannelCount, deletedChannelCount));
- mDeletedChannels.setEnabled(false);
- mDeletedChannels.setKey(KEY_DELETED);
- mDeletedChannels.setOrder(ORDER_LAST);
- getPreferenceScreen().addPreference(mDeletedChannels);
- }
+ mImportanceListener.onImportanceChanged();
}
- updateDependents(mAppRow.banned);
}
private void populateGroupList() {
@@ -190,7 +169,7 @@
groupCategory.setKey(KEY_GENERAL_CATEGORY);
groupCategory.setOrderingAsAdded(true);
getPreferenceScreen().addPreference(groupCategory);
- mChannelGroups.add(groupCategory);
+ mDynamicPreferences.add(groupCategory);
for (NotificationChannelGroup group : mChannelGroupList) {
final List<NotificationChannel> channels = group.getChannels();
int N = channels.size();
@@ -240,91 +219,6 @@
parent.addPreference(groupPref);
}
- void setupBadge() {
- mBadge = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BADGE);
- mBadge.setDisabledByAdmin(mSuspendedAppsAdmin);
- if (mChannel == null) {
- mBadge.setChecked(mAppRow.showBadge);
- } else {
- mBadge.setChecked(mChannel.canShowBadge());
- }
- mBadge.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final boolean value = (Boolean) newValue;
- if (mChannel == null) {
- mBackend.setShowBadge(mPkg, mUid, value);
- } else {
- mChannel.setShowBadge(value);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- }
- return true;
- }
- });
- }
-
- protected void setupBlock() {
- View switchBarContainer = LayoutInflater.from(
- getPrefContext()).inflate(R.layout.styled_switch_bar, null);
- mSwitchBar = switchBarContainer.findViewById(R.id.switch_bar);
- mSwitchBar.show();
- mSwitchBar.setDisabledByAdmin(mSuspendedAppsAdmin);
- mSwitchBar.setChecked(!mAppRow.banned);
- mSwitchBar.addOnSwitchChangeListener(new SwitchBar.OnSwitchChangeListener() {
- @Override
- public void onSwitchChanged(Switch switchView, boolean isChecked) {
- if (mShowLegacyChannelConfig && mChannel != null) {
- final int importance = isChecked ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_NONE;
- mImportanceToggle.setChecked(importance == IMPORTANCE_UNSPECIFIED);
- mChannel.setImportance(importance);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- }
- mBackend.setNotificationsEnabledForPackage(mPkgInfo.packageName, mUid, isChecked);
- mAppRow.banned = true;
- updateDependents(!isChecked);
- }
- });
-
- mBlockBar = new LayoutPreference(getPrefContext(), switchBarContainer);
- mBlockBar.setOrder(ORDER_FIRST);
- mBlockBar.setKey(KEY_BLOCK);
- getPreferenceScreen().addPreference(mBlockBar);
-
- if (mAppRow.systemApp && !mAppRow.banned) {
- setVisible(mBlockBar, false);
- }
-
- setupBlockDesc(R.string.app_notifications_off_desc);
- }
-
- protected void updateDependents(boolean banned) {
- for (PreferenceCategory category : mChannelGroups) {
- setVisible(category, !banned);
- }
- if (mDeletedChannels != null) {
- setVisible(mDeletedChannels, !banned);
- }
- setVisible(mBlockedDesc, banned);
- setVisible(mBadge, !banned);
- if (mShowLegacyChannelConfig) {
- setVisible(mImportanceToggle, !banned);
- setVisible(mPriority, checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
- || (checkCanBeVisible(NotificationManager.IMPORTANCE_LOW)
- && mDndVisualEffectsSuppressed));
- setVisible(mVisibilityOverride, !banned &&
- checkCanBeVisible(NotificationManager.IMPORTANCE_LOW) && isLockScreenSecure());
- }
- if (mAppLink != null) {
- setVisible(mAppLink, !banned);
- }
- if (mAppRow.systemApp && !mAppRow.banned) {
- setVisible(mBlockBar, false);
- }
- }
-
-
private Comparator<NotificationChannelGroup> mChannelGroupComparator =
new Comparator<NotificationChannelGroup>() {
diff --git a/src/com/android/settings/notification/BadgePreferenceController.java b/src/com/android/settings/notification/BadgePreferenceController.java
new file mode 100644
index 0000000..6b72c50
--- /dev/null
+++ b/src/com/android/settings/notification/BadgePreferenceController.java
@@ -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.notification;
+
+import static android.provider.Settings.Secure.NOTIFICATION_BADGING;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+public class BadgePreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String TAG = "BadgePrefContr";
+ private static final String KEY_BADGE = "badge";
+ private static final int SYSTEM_WIDE_ON = 1;
+ private static final int SYSTEM_WIDE_OFF = 0;
+
+ public BadgePreferenceController(Context context,
+ NotificationBackend backend) {
+ super(context, backend);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BADGE;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ if (mAppRow == null && mChannel == null) {
+ return false;
+ }
+ if (Settings.Secure.getInt(mContext.getContentResolver(),
+ NOTIFICATION_BADGING, SYSTEM_WIDE_ON) == SYSTEM_WIDE_OFF) {
+ return false;
+ }
+ if (mChannel != null && !mAppRow.showBadge) {
+ return false;
+ }
+ return true;
+ }
+
+ public void updateState(Preference preference) {
+ if (mAppRow != null) {
+ RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
+ pref.setDisabledByAdmin(mAdmin);
+ if (mChannel != null) {
+ pref.setChecked(mChannel.canShowBadge());
+ pref.setEnabled(isChannelConfigurable() && !pref.isDisabledByAdmin());
+ } else {
+ pref.setChecked(mAppRow.showBadge);
+ }
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean showBadge = (Boolean) newValue;
+ if (mChannel != null) {
+ mChannel.setShowBadge(showBadge);
+ saveChannel();
+ } else if (mAppRow != null){
+ mAppRow.showBadge = showBadge;
+ mBackend.setShowBadge(mAppRow.pkg, mAppRow.uid, showBadge);
+ }
+ return true;
+ }
+
+}
diff --git a/src/com/android/settings/notification/BlockPreferenceController.java b/src/com/android/settings/notification/BlockPreferenceController.java
new file mode 100644
index 0000000..5c366ea
--- /dev/null
+++ b/src/com/android/settings/notification/BlockPreferenceController.java
@@ -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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.widget.Switch;
+
+import com.android.settings.R;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.widget.SwitchBar;
+
+public class BlockPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, SwitchBar.OnSwitchChangeListener {
+
+ private static final String KEY_BLOCK = "block";
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+
+ public BlockPreferenceController(Context context,
+ NotificationSettingsBase.ImportanceListener importanceListener,
+ NotificationBackend backend) {
+ super(context, backend);
+ mImportanceListener = importanceListener;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BLOCK;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (mAppRow == null) {
+ return false;
+ }
+ if (mChannel != null) {
+ return isChannelBlockable();
+ } else if (mChannelGroup != null && mChannelGroup.getGroup() != null) {
+ return isChannelGroupBlockable();
+ } else {
+ return !mAppRow.systemApp || (mAppRow.systemApp && mAppRow.banned);
+ }
+ }
+
+ public void updateState(Preference preference) {
+ LayoutPreference pref = (LayoutPreference) preference;
+ SwitchBar bar = pref.findViewById(R.id.switch_bar);
+ if (bar != null) {
+ bar.show();
+ try {
+ bar.addOnSwitchChangeListener(this);
+ } catch (IllegalStateException e) {
+ // an exception is thrown if you try to add the listener twice
+ }
+ bar.setDisabledByAdmin(mAdmin);
+
+ if (mChannel != null) {
+ bar.setChecked(!mAppRow.banned
+ && mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE);
+ } else if (mChannelGroup != null && mChannelGroup.getGroup() != null) {
+ bar.setChecked(!mAppRow.banned && !mChannelGroup.isBlocked());
+ } else {
+ bar.setChecked(!mAppRow.banned);
+ }
+ }
+ }
+
+ @Override
+ public void onSwitchChanged(Switch switchView, boolean isChecked) {
+ boolean blocked = !isChecked;
+ if (mChannel != null) {
+ final int originalImportance = mChannel.getImportance();
+ // setting the initial state of the switch in updateState() triggers this callback.
+ // It's always safe to override the importance if it's meant to be blocked or if
+ // it was blocked and we are unblocking it.
+ if (blocked || originalImportance == IMPORTANCE_NONE) {
+ final int importance = blocked ? IMPORTANCE_NONE
+ : DEFAULT_CHANNEL_ID.equals(mChannel.getId())
+ ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_DEFAULT;
+ mChannel.setImportance(importance);
+ saveChannel();
+ }
+ } else if (mChannelGroup != null && mChannelGroup.getGroup() != null) {
+ mChannelGroup.setBlocked(blocked);
+ mBackend.updateChannelGroup(mAppRow.pkg, mAppRow.uid, mChannelGroup.getGroup());
+ } else if (mAppRow != null) {
+ mAppRow.banned = blocked;
+ mBackend.setNotificationsEnabledForPackage(mAppRow.pkg, mAppRow.uid, !blocked);
+ }
+ mImportanceListener.onImportanceChanged();
+ }
+}
diff --git a/src/com/android/settings/notification/ChannelGroupNotificationSettings.java b/src/com/android/settings/notification/ChannelGroupNotificationSettings.java
index 7837ec8..68dd91b 100644
--- a/src/com/android/settings/notification/ChannelGroupNotificationSettings.java
+++ b/src/com/android/settings/notification/ChannelGroupNotificationSettings.java
@@ -16,20 +16,15 @@
package com.android.settings.notification;
-import android.app.Activity;
import android.app.NotificationChannel;
+import android.content.Context;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
-import com.android.settings.widget.EntityHeaderController;
-import com.android.settingslib.widget.FooterPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.Collections;
@@ -38,12 +33,6 @@
public class ChannelGroupNotificationSettings extends NotificationSettingsBase {
private static final String TAG = "ChannelGroupSettings";
- private static String KEY_DELETED = "deleted";
-
- private EntityHeaderController mHeaderPref;
- private List<Preference> mChannels = new ArrayList();
- private FooterPreference mDeletedChannels;
-
@Override
public int getMetricsCategory() {
return MetricsEvent.NOTIFICATION_CHANNEL_GROUP;
@@ -52,137 +41,68 @@
@Override
public void onResume() {
super.onResume();
- if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null || mChannelGroup == null) {
+ if (mAppRow == null || mChannelGroup == null || mChannelGroup.getGroup() == null) {
Log.w(TAG, "Missing package or uid or packageinfo or group");
finish();
return;
}
- if (getPreferenceScreen() != null) {
- getPreferenceScreen().removeAll();
- }
- addPreferencesFromResource(R.xml.notification_settings);
- setupBlock();
- addHeaderPref();
- addAppLinkPref();
- addFooterPref();
populateChannelList();
-
- updateDependents(mChannelGroup.isBlocked());
+ for (NotificationPreferenceController controller : mControllers) {
+ controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
+ controller.displayPreference(getPreferenceScreen());
+ }
+ updatePreferenceStates();
}
@Override
- void setupBadge() {
+ protected String getLogTag() {
+ return TAG;
+ }
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.notification_group_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ mControllers = new ArrayList<>();
+ mControllers.add(new HeaderPreferenceController(context, this));
+ mControllers.add(new BlockPreferenceController(context, mImportanceListener, mBackend));
+ mControllers.add(new AppLinkPreferenceController(context));
+ mControllers.add(new NotificationsOffPreferenceController(context));
+ mControllers.add(new DescriptionPreferenceController(context));
+ return new ArrayList<>(mControllers);
}
private void populateChannelList() {
- if (!mChannels.isEmpty()) {
- // If there's anything in mChannels, we've called populateChannelList twice.
+ if (!mDynamicPreferences.isEmpty()) {
+ // If there's anything in mDynamicPreferences, we've called populateChannelList twice.
// Clear out existing channels and log.
Log.w(TAG, "Notification channel group posted twice to settings - old size " +
- mChannels.size() + ", new size " + mChannels.size());
- for (Preference p : mChannels) {
+ mDynamicPreferences.size() + ", new size " + mDynamicPreferences.size());
+ for (Preference p : mDynamicPreferences) {
getPreferenceScreen().removePreference(p);
}
}
- if (mChannelGroup.getChannels().isEmpty()) {
+ if (mChannelGroup.getGroup().getChannels().isEmpty()) {
Preference empty = new Preference(getPrefContext());
empty.setTitle(R.string.no_channels);
empty.setEnabled(false);
getPreferenceScreen().addPreference(empty);
- mChannels.add(empty);
+ mDynamicPreferences.add(empty);
} else {
- final List<NotificationChannel> channels = mChannelGroup.getChannels();
+ final List<NotificationChannel> channels = mChannelGroup.getGroup().getChannels();
Collections.sort(channels, mChannelComparator);
for (NotificationChannel channel : channels) {
- mChannels.add(populateSingleChannelPrefs(
- getPreferenceScreen(), channel, getImportanceSummary(channel)));
+ mDynamicPreferences.add(populateSingleChannelPrefs(
+ getPreferenceScreen(), channel,
+ ImportancePreferenceController.getImportanceSummary(
+ getPrefContext(), channel)));
}
- int deletedChannelCount = mBackend.getDeletedChannelCount(mAppRow.pkg, mAppRow.uid);
- if (deletedChannelCount > 0) {
- mDeletedChannels = new FooterPreference(getPrefContext());
- mDeletedChannels.setSelectable(false);
- mDeletedChannels.setTitle(getResources().getQuantityString(
- R.plurals.deleted_channels, deletedChannelCount, deletedChannelCount));
- mDeletedChannels.setEnabled(false);
- mDeletedChannels.setKey(KEY_DELETED);
- mDeletedChannels.setOrder(ORDER_LAST);
- getPreferenceScreen().addPreference(mDeletedChannels);
- mChannels.add(mDeletedChannels);
- }
}
-
- updateDependents(mAppRow.banned);
- }
-
- private void addHeaderPref() {
- ArrayMap<String, NotificationBackend.AppRow> rows = new ArrayMap<>();
- rows.put(mAppRow.pkg, mAppRow);
- collectConfigActivities(rows);
- final Activity activity = getActivity();
- mHeaderPref = EntityHeaderController
- .newInstance(activity, this /* fragment */, null /* header */)
- .setRecyclerView(getListView(), getLifecycle());
- final Preference pref = mHeaderPref
- .setIcon(mAppRow.icon)
- .setLabel(mChannelGroup.getName())
- .setSummary(mAppRow.label)
- .setPackageName(mAppRow.pkg)
- .setUid(mAppRow.uid)
- .setButtonActions(EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
- EntityHeaderController.ActionType.ACTION_NONE)
- .setHasAppInfoLink(true)
- .done(activity, getPrefContext());
- getPreferenceScreen().addPreference(pref);
- }
-
- private void addFooterPref() {
- if (!TextUtils.isEmpty(mChannelGroup.getDescription())) {
- FooterPreference descPref = new FooterPreference(getPrefContext());
- descPref.setOrder(ORDER_LAST);
- descPref.setSelectable(false);
- descPref.setTitle(mChannelGroup.getDescription());
- getPreferenceScreen().addPreference(descPref);
- mChannels.add(descPref);
- }
- }
-
- private void setupBlock() {
- View switchBarContainer = LayoutInflater.from(
- getPrefContext()).inflate(R.layout.styled_switch_bar, null);
- mSwitchBar = switchBarContainer.findViewById(R.id.switch_bar);
- mSwitchBar.show();
- mSwitchBar.setDisabledByAdmin(mSuspendedAppsAdmin);
- mSwitchBar.setChecked(!mChannelGroup.isBlocked());
- mSwitchBar.addOnSwitchChangeListener((switchView, isChecked) -> {
- mChannelGroup.setBlocked(!isChecked);
- mBackend.updateChannelGroup(mPkg, mUid, mChannelGroup);
- updateDependents(!isChecked);
- });
-
- mBlockBar = new LayoutPreference(getPrefContext(), switchBarContainer);
- mBlockBar.setOrder(ORDER_FIRST);
- mBlockBar.setKey(KEY_BLOCK);
- getPreferenceScreen().addPreference(mBlockBar);
-
- if (!isChannelGroupBlockable(mChannelGroup)) {
- setVisible(mBlockBar, false);
- }
-
- setupBlockDesc(R.string.channel_group_notifications_off_desc);
- }
-
- protected void updateDependents(boolean banned) {
- for (Preference channel : mChannels) {
- setVisible(channel, !banned);
- }
- if (mAppLink != null) {
- setVisible(mAppLink, !banned);
- }
- setVisible(mBlockBar, isChannelGroupBlockable(mChannelGroup));
- setVisible(mBlockedDesc, mAppRow.banned || mChannelGroup.isBlocked());
}
}
diff --git a/src/com/android/settings/notification/ChannelImportanceSettings.java b/src/com/android/settings/notification/ChannelImportanceSettings.java
index 9e9ffd6..27b23b8 100644
--- a/src/com/android/settings/notification/ChannelImportanceSettings.java
+++ b/src/com/android/settings/notification/ChannelImportanceSettings.java
@@ -37,6 +37,7 @@
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.RadioButtonPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
@@ -60,8 +61,8 @@
@Override
public void onResume() {
super.onResume();
- if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null || mChannel == null) {
- Log.w(TAG, "Missing package or uid or packageinfo or channel");
+ if (mAppRow == null || mChannel == null) {
+ Log.w(TAG, "Missing package or channel");
finish();
return;
}
@@ -69,10 +70,19 @@
}
@Override
- void setupBadge() {}
+ protected String getLogTag() {
+ return TAG;
+ }
@Override
- void updateDependents(boolean banned) {}
+ protected int getPreferenceScreenResId() {
+ return R.xml.notification_importance;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return null;
+ }
@Override
public void onPause() {
@@ -81,11 +91,6 @@
private PreferenceScreen createPreferenceHierarchy() {
PreferenceScreen root = getPreferenceScreen();
- if (root != null) {
- root.removeAll();
- }
- addPreferencesFromResource(R.xml.notification_importance);
- root = getPreferenceScreen();
for (int i = 0; i < root.getPreferenceCount(); i++) {
Preference pref = root.getPreference(i);
@@ -148,8 +153,9 @@
// but the sound you had selected was "Silence",
// then set sound for this channel to your default sound,
// because you probably intended to cause this channel to actually start making sound.
- if (oldImportance < IMPORTANCE_DEFAULT && !hasValidSound(mChannel) &&
- mChannel.getImportance() >= IMPORTANCE_DEFAULT) {
+ if (oldImportance < IMPORTANCE_DEFAULT
+ && !SoundPreferenceController.hasValidSound(mChannel)
+ && mChannel.getImportance() >= IMPORTANCE_DEFAULT) {
mChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
mChannel.getAudioAttributes());
mChannel.lockFields(USER_LOCKED_SOUND);
@@ -157,15 +163,4 @@
mChannel.lockFields(USER_LOCKED_IMPORTANCE);
mBackend.updateChannel(mAppRow.pkg, mAppRow.uid, mChannel);
}
-
- // This page exists per notification channel; should not be included
- // in search
- public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
- @Override
- public List<SearchIndexableResource> getXmlResourcesToIndex(
- Context context, boolean enabled) {
- return null;
- }
- };
}
diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java
index 9484f7e..ea17a05 100644
--- a/src/com/android/settings/notification/ChannelNotificationSettings.java
+++ b/src/com/android/settings/notification/ChannelNotificationSettings.java
@@ -16,59 +16,23 @@
package com.android.settings.notification;
-import android.app.Activity;
-import android.app.NotificationChannel;
-import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
+import android.content.Context;
import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.AsyncTask;
-import android.provider.Settings;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
+import android.preference.PreferenceManager;
import android.text.TextUtils;
-import android.text.BidiFormatter;
-import android.text.SpannableStringBuilder;
-import android.util.ArrayMap;
import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.Switch;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
-import com.android.settings.RingtonePreference;
-import com.android.settings.Utils;
-import com.android.settings.applications.AppInfoBase;
-import com.android.settings.applications.LayoutPreference;
-import com.android.settings.widget.EntityHeaderController;
-import com.android.settings.widget.SwitchBar;
-import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.widget.FooterPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_NONE;
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import java.util.ArrayList;
+import java.util.List;
public class ChannelNotificationSettings extends NotificationSettingsBase {
private static final String TAG = "ChannelSettings";
- private static final String KEY_LIGHTS = "lights";
- private static final String KEY_VIBRATE = "vibrate";
- private static final String KEY_RINGTONE = "ringtone";
- private static final String KEY_IMPORTANCE = "importance";
- private static final String KEY_ADVANCED = "advanced";
-
- private Preference mImportance;
- private RestrictedSwitchPreference mLights;
- private RestrictedSwitchPreference mVibrate;
- private NotificationSoundPreference mRingtone;
- private FooterPreference mFooter;
- private NotificationChannelGroup mChannelGroup;
- private EntityHeaderController mHeaderPref;
- private PreferenceGroup mAdvanced;
-
@Override
public int getMetricsCategory() {
return MetricsEvent.NOTIFICATION_TOPIC_NOTIFICATION;
@@ -83,308 +47,52 @@
return;
}
- if (getPreferenceScreen() != null) {
- getPreferenceScreen().removeAll();
+ for (NotificationPreferenceController controller : mControllers) {
+ controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
+ controller.displayPreference(getPreferenceScreen());
}
- addPreferencesFromResource(R.xml.notification_settings);
- setupBlock();
- addHeaderPref();
- addAppLinkPref();
- addFooterPref();
-
- if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())) {
- populateDefaultChannelPrefs();
- mShowLegacyChannelConfig = true;
- } else {
- populateUpgradedChannelPrefs();
-
- if (mChannel.getGroup() != null) {
- mChannelGroup = mBackend.getGroup(mPkg, mUid, mChannel.getGroup());
- if (mChannelGroup != null) {
- setChannelGroupLabel(mChannelGroup.getName());
- }
- }
- }
-
- updateDependents(mChannel.getImportance() == IMPORTANCE_NONE);
- }
-
- private void populateUpgradedChannelPrefs() {
- addPreferencesFromResource(R.xml.upgraded_channel_notification_settings);
- setupBadge();
- setupPriorityPref(mChannel.canBypassDnd());
- setupVisOverridePref(mChannel.getLockscreenVisibility());
- setupLights();
- setupVibrate();
- setupRingtone();
- setupImportance();
- mAdvanced = (PreferenceGroup) findPreference(KEY_ADVANCED);
- }
-
- private void addHeaderPref() {
- ArrayMap<String, NotificationBackend.AppRow> rows = new ArrayMap<>();
- rows.put(mAppRow.pkg, mAppRow);
- collectConfigActivities(rows);
- final Activity activity = getActivity();
- mHeaderPref = EntityHeaderController
- .newInstance(activity, this /* fragment */, null /* header */)
- .setRecyclerView(getListView(), getLifecycle());
- final Preference pref = mHeaderPref
- .setIcon(mAppRow.icon)
- .setLabel(mChannel.getName())
- .setSummary(mAppRow.label)
- .setPackageName(mAppRow.pkg)
- .setUid(mAppRow.uid)
- .setButtonActions(EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
- EntityHeaderController.ActionType.ACTION_NONE)
- .setHasAppInfoLink(true)
- .done(activity, getPrefContext());
- getPreferenceScreen().addPreference(pref);
- }
-
- private void setChannelGroupLabel(CharSequence groupName) {
- final SpannableStringBuilder summary = new SpannableStringBuilder();
- BidiFormatter bidi = BidiFormatter.getInstance();
- summary.append(bidi.unicodeWrap(mAppRow.label.toString()));
- if (groupName != null) {
- summary.append(bidi.unicodeWrap(mContext.getText(
- R.string.notification_header_divider_symbol_with_spaces)));
- summary.append(bidi.unicodeWrap(groupName.toString()));
- }
- final Activity activity = getActivity();
- mHeaderPref.setSummary(summary.toString());
- mHeaderPref.done(activity, getPrefContext());
- }
-
- private void addFooterPref() {
- if (!TextUtils.isEmpty(mChannel.getDescription())) {
- FooterPreference descPref = new FooterPreference(getPrefContext());
- descPref.setOrder(ORDER_LAST);
- descPref.setSelectable(false);
- descPref.setTitle(mChannel.getDescription());
- getPreferenceScreen().addPreference(descPref);
- }
- }
-
- protected void setupBadge() {
- mBadge = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BADGE);
- mBadge.setDisabledByAdmin(mSuspendedAppsAdmin);
- mBadge.setEnabled(mAppRow.showBadge);
- mBadge.setChecked(mChannel.canShowBadge());
-
- mBadge.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final boolean value = (Boolean) newValue;
- mChannel.setShowBadge(value);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- return true;
- }
- });
- }
-
- private void setupLights() {
- mLights = (RestrictedSwitchPreference) findPreference(KEY_LIGHTS);
- mLights.setDisabledByAdmin(mSuspendedAppsAdmin);
- mLights.setChecked(mChannel.shouldShowLights());
- mLights.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final boolean lights = (Boolean) newValue;
- mChannel.enableLights(lights);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_LIGHTS);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- return true;
- }
- });
- }
-
- private void setupVibrate() {
- mVibrate = (RestrictedSwitchPreference) findPreference(KEY_VIBRATE);
- mVibrate.setDisabledByAdmin(mSuspendedAppsAdmin);
- mVibrate.setEnabled(!mVibrate.isDisabledByAdmin() && isChannelConfigurable(mChannel));
- mVibrate.setChecked(mChannel.shouldVibrate());
- mVibrate.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final boolean vibrate = (Boolean) newValue;
- mChannel.enableVibration(vibrate);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_VIBRATION);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- return true;
- }
- });
- }
-
- private void setupRingtone() {
- mRingtone = (NotificationSoundPreference) findPreference(KEY_RINGTONE);
- mRingtone.setRingtone(mChannel.getSound());
- mRingtone.setEnabled(isChannelConfigurable(mChannel));
- mRingtone.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mChannel.setSound((Uri) newValue, mChannel.getAudioAttributes());
- mChannel.lockFields(NotificationChannel.USER_LOCKED_SOUND);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- return false;
- }
- });
- }
-
- private void setupBlock() {
- View switchBarContainer = LayoutInflater.from(
- getPrefContext()).inflate(R.layout.styled_switch_bar, null);
- mSwitchBar = switchBarContainer.findViewById(R.id.switch_bar);
- mSwitchBar.show();
- mSwitchBar.setDisabledByAdmin(mSuspendedAppsAdmin);
- mSwitchBar.setChecked(mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE);
- mSwitchBar.addOnSwitchChangeListener(new SwitchBar.OnSwitchChangeListener() {
- @Override
- public void onSwitchChanged(Switch switchView, boolean isChecked) {
- int importance = 0;
- if (mShowLegacyChannelConfig) {
- importance = isChecked ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_NONE;
- mImportanceToggle.setChecked(importance == IMPORTANCE_UNSPECIFIED);
- } else {
- importance = isChecked ? IMPORTANCE_LOW : IMPORTANCE_NONE;
- mImportance.setSummary(getImportanceSummary(importance));
- }
- mChannel.setImportance(importance);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- updateDependents(mChannel.getImportance() == IMPORTANCE_NONE);
- }
- });
-
- mBlockBar = new LayoutPreference(getPrefContext(), switchBarContainer);
- mBlockBar.setOrder(ORDER_FIRST);
- mBlockBar.setKey(KEY_BLOCK);
- getPreferenceScreen().addPreference(mBlockBar);
-
- if (!isChannelBlockable(mChannel)) {
- setVisible(mBlockBar, false);
- }
-
- setupBlockDesc(R.string.channel_notifications_off_desc);
- }
-
- private void setupImportance() {
- mImportance = findPreference(KEY_IMPORTANCE);
- Bundle channelArgs = new Bundle();
- channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
- channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
- channelArgs.putString(Settings.EXTRA_CHANNEL_ID, mChannel.getId());
- mImportance.setEnabled(mSuspendedAppsAdmin == null && isChannelConfigurable(mChannel));
- // Set up intent to show importance selection only if this setting is enabled.
- if (mImportance.isEnabled()) {
- Intent channelIntent = Utils.onBuildStartFragmentIntent(getActivity(),
- ChannelImportanceSettings.class.getName(),
- channelArgs, null, R.string.notification_importance_title, null,
- false, getMetricsCategory());
- mImportance.setIntent(channelIntent);
- }
- mImportance.setSummary(getImportanceSummary(mChannel.getImportance()));
- }
-
- private String getImportanceSummary(int importance) {
- String title;
- String summary = null;
- switch (importance) {
- case IMPORTANCE_UNSPECIFIED:
- title = getContext().getString(R.string.notification_importance_unspecified);
- break;
- case NotificationManager.IMPORTANCE_MIN:
- title = getContext().getString(R.string.notification_importance_min_title);
- summary = getContext().getString(R.string.notification_importance_min);
- break;
- case NotificationManager.IMPORTANCE_LOW:
- title = getContext().getString(R.string.notification_importance_low_title);
- summary = getContext().getString(R.string.notification_importance_low);
- break;
- case NotificationManager.IMPORTANCE_DEFAULT:
- title = getContext().getString(R.string.notification_importance_default_title);
- if (hasValidSound(mChannel)) {
- summary = getContext().getString(R.string.notification_importance_default);
- } else {
- summary = getContext().getString(R.string.notification_importance_low);
- }
- break;
- case NotificationManager.IMPORTANCE_HIGH:
- case NotificationManager.IMPORTANCE_MAX:
- title = getContext().getString(R.string.notification_importance_high_title);
- if (hasValidSound(mChannel)) {
- summary = getContext().getString(R.string.notification_importance_high);
- } else {
- summary = getContext().getString(R.string.notification_importance_high_silent);
- }
- break;
- default:
- return "";
- }
-
- if (summary != null) {
- return getContext().getString(R.string.notification_importance_divider, title, summary);
- } else {
- return title;
- }
- }
-
- @Override
- public boolean onPreferenceTreeClick(Preference preference) {
- if (preference instanceof RingtonePreference) {
- mRingtone.onPrepareRingtonePickerIntent(mRingtone.getIntent());
- startActivityForResult(preference.getIntent(), 200);
- return true;
- }
- return super.onPreferenceTreeClick(preference);
+ updatePreferenceStates();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (mRingtone != null) {
- mRingtone.onActivityResult(requestCode, resultCode, data);
- }
- if (mChannel != null) {
- mImportance.setSummary(getImportanceSummary(mChannel.getImportance()));
+ for (NotificationPreferenceController controller : mControllers) {
+ if (controller instanceof PreferenceManager.OnActivityResultListener) {
+ ((PreferenceManager.OnActivityResultListener) controller)
+ .onActivityResult(requestCode, resultCode, data);
+ }
}
}
- boolean canPulseLight() {
- if (!getResources()
- .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed)) {
- return false;
- }
- return Settings.System.getInt(getContentResolver(),
- Settings.System.NOTIFICATION_LIGHT_PULSE, 0) == 1;
+ @Override
+ protected String getLogTag() {
+ return TAG;
}
- void updateDependents(boolean banned) {
- PreferenceGroup parent;
- if (mShowLegacyChannelConfig) {
- parent = getPreferenceScreen();
- setVisible(mImportanceToggle, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
- } else {
- setVisible(mAdvanced, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
- setVisible(mImportance, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
- setVisible(mAdvanced, mLights, checkCanBeVisible(
- NotificationManager.IMPORTANCE_DEFAULT) && canPulseLight());
- setVisible(mVibrate, checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT));
- setVisible(mRingtone, checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT));
- parent = mAdvanced;
- }
- setVisible(parent, mBadge, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
- setVisible(parent, mPriority, checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
- || (checkCanBeVisible(NotificationManager.IMPORTANCE_LOW)
- && mDndVisualEffectsSuppressed));
- setVisible(parent, mVisibilityOverride, isLockScreenSecure()
- &&checkCanBeVisible(NotificationManager.IMPORTANCE_LOW));
- setVisible(mBlockedDesc, mChannel.getImportance() == IMPORTANCE_NONE);
- if (mAppLink != null) {
- setVisible(mAppLink, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
- }
- if (mFooter != null) {
- setVisible(mFooter, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
- }
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.channel_notification_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ mControllers = new ArrayList<>();
+ mControllers.add(new HeaderPreferenceController(context, this));
+ mControllers.add(new BlockPreferenceController(context, mImportanceListener, mBackend));
+ mControllers.add(new ImportancePreferenceController(context));
+ mControllers.add(new AllowSoundPreferenceController(
+ context, mImportanceListener, mBackend));
+ mControllers.add(new SoundPreferenceController(context, this,
+ mImportanceListener, mBackend));
+ mControllers.add(new VibrationPreferenceController(context, mBackend));
+ mControllers.add(new AppLinkPreferenceController(context));
+ mControllers.add(new DescriptionPreferenceController(context));
+ mControllers.add(new VisibilityPreferenceController(context, new LockPatternUtils(context),
+ mBackend));
+ mControllers.add(new LightsPreferenceController(context, mBackend));
+ mControllers.add(new BadgePreferenceController(context, mBackend));
+ mControllers.add(new DndPreferenceController(context, getLifecycle(), mBackend));
+ mControllers.add(new NotificationsOffPreferenceController(context));
+ return new ArrayList<>(mControllers);
}
}
diff --git a/src/com/android/settings/notification/DeletedChannelsPreferenceController.java b/src/com/android/settings/notification/DeletedChannelsPreferenceController.java
new file mode 100644
index 0000000..16eb9ed
--- /dev/null
+++ b/src/com/android/settings/notification/DeletedChannelsPreferenceController.java
@@ -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.notification;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+
+public class DeletedChannelsPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin {
+
+ private static final String KEY_DELETED = "deleted";
+
+ public DeletedChannelsPreferenceController(Context context, NotificationBackend backend) {
+ super(context, backend);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_DELETED;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ // only visible on app screen
+ if (mChannel != null || hasValidGroup()) {
+ return false;
+ }
+
+ return mBackend.getDeletedChannelCount(mAppRow.pkg, mAppRow.uid) > 0;
+ }
+
+ public void updateState(Preference preference) {
+ if (mAppRow != null) {
+ int deletedChannelCount = mBackend.getDeletedChannelCount(mAppRow.pkg, mAppRow.uid);
+ preference.setTitle(mContext.getResources().getQuantityString(
+ R.plurals.deleted_channels, deletedChannelCount, deletedChannelCount));
+ }
+ preference.setEnabled(false);
+ preference.setSelectable(false);
+ }
+}
diff --git a/src/com/android/settings/notification/DescriptionPreferenceController.java b/src/com/android/settings/notification/DescriptionPreferenceController.java
new file mode 100644
index 0000000..fae2f5f
--- /dev/null
+++ b/src/com/android/settings/notification/DescriptionPreferenceController.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.text.TextUtils;
+
+import com.android.settings.core.PreferenceControllerMixin;
+
+public class DescriptionPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin {
+
+ private static final String KEY_DESC = "desc";
+
+ public DescriptionPreferenceController(Context context) {
+ super(context, null);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_DESC;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ if (mChannel == null && !hasValidGroup()) {
+ return false;
+ }
+ if (mChannel != null && !TextUtils.isEmpty(mChannel.getDescription())) {
+ return true;
+ }
+ if (hasValidGroup() && !TextUtils.isEmpty(mChannelGroup.getDescription())) {
+ return true;
+ }
+ return false;
+ }
+
+ public void updateState(Preference preference) {
+ if (mAppRow != null) {
+ if (mChannel != null) {
+ preference.setTitle(mChannel.getDescription());
+ } else if (hasValidGroup()) {
+ preference.setTitle(mChannelGroup.getDescription());
+ }
+ }
+ preference.setEnabled(false);
+ preference.setSelectable(false);
+ }
+}
diff --git a/src/com/android/settings/notification/DndPreferenceController.java b/src/com/android/settings/notification/DndPreferenceController.java
new file mode 100644
index 0000000..af60401
--- /dev/null
+++ b/src/com/android/settings/notification/DndPreferenceController.java
@@ -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.notification;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+
+public class DndPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
+ LifecycleObserver, OnResume {
+
+ private static final String KEY_BYPASS_DND = "bypass_dnd";
+ private boolean mVisualEffectsSuppressed;
+
+ public DndPreferenceController(Context context, Lifecycle lifecycle,
+ NotificationBackend backend) {
+ super(context, backend);
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public void onResume() {
+ NotificationManager.Policy policy = mNm.getNotificationPolicy();
+ mVisualEffectsSuppressed = policy != null && policy.suppressedVisualEffects != 0;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BYPASS_DND;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
+ || (checkCanBeVisible(NotificationManager.IMPORTANCE_LOW)
+ && mVisualEffectsSuppressed);
+ }
+
+ public void updateState(Preference preference) {
+ if (mChannel != null) {
+ RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
+ pref.setDisabledByAdmin(mAdmin);
+ pref.setEnabled(isChannelConfigurable() && !pref.isDisabledByAdmin());
+ pref.setChecked(mChannel.canBypassDnd());
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mChannel != null) {
+ final boolean bypassZenMode = (Boolean) newValue;
+ mChannel.setBypassDnd(bypassZenMode);
+ mChannel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
+ saveChannel();
+ }
+ return true;
+ }
+
+}
diff --git a/src/com/android/settings/notification/HeaderPreferenceController.java b/src/com/android/settings/notification/HeaderPreferenceController.java
new file mode 100644
index 0000000..3d51b25
--- /dev/null
+++ b/src/com/android/settings/notification/HeaderPreferenceController.java
@@ -0,0 +1,100 @@
+/*
+ * 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.notification;
+
+import static com.android.settings.widget.EntityHeaderController.PREF_KEY_APP_HEADER;
+
+import android.content.Context;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
+import android.text.BidiFormatter;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.widget.EntityHeaderController;
+
+public class HeaderPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin {
+
+ private final PreferenceFragment mFragment;
+
+ public HeaderPreferenceController(Context context, PreferenceFragment fragment) {
+ super(context, null);
+ mFragment = fragment;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return PREF_KEY_APP_HEADER;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mAppRow != null;
+ }
+
+ public void updateState(Preference preference) {
+ if (mAppRow != null && mFragment != null) {
+ LayoutPreference pref = (LayoutPreference) preference;
+ EntityHeaderController controller = EntityHeaderController
+ .newInstance(mFragment.getActivity(), mFragment,
+ pref.findViewById(R.id.entity_header));
+ pref = controller.setIcon(mAppRow.icon)
+ .setLabel(getLabel())
+ .setSummary(getSummary())
+ .setPackageName(mAppRow.pkg)
+ .setUid(mAppRow.uid)
+ .setButtonActions(EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
+ EntityHeaderController.ActionType.ACTION_NONE)
+ .setHasAppInfoLink(true)
+ .done(mFragment.getActivity(), mContext);
+ pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
+ }
+ }
+
+ CharSequence getLabel() {
+ return mChannel != null ? mChannel.getName()
+ : mChannelGroup != null && mChannelGroup.getGroup() != null
+ ? mChannelGroup.getGroup().getName()
+ : mAppRow.label;
+ }
+
+ CharSequence getSummary() {
+ if (mChannel != null) {
+ if (mChannelGroup != null && mChannelGroup.getGroup() != null
+ && !TextUtils.isEmpty(mChannelGroup.getGroup().getName())) {
+ final SpannableStringBuilder summary = new SpannableStringBuilder();
+ BidiFormatter bidi = BidiFormatter.getInstance();
+ summary.append(bidi.unicodeWrap(mAppRow.label.toString()));
+ summary.append(bidi.unicodeWrap(mContext.getText(
+ R.string.notification_header_divider_symbol_with_spaces)));
+ summary.append(bidi.unicodeWrap(mChannelGroup.getGroup().getName().toString()));
+ return summary;
+ } else {
+ return mAppRow.label;
+ }
+ } else if (mChannelGroup != null && mChannelGroup.getGroup() != null) {
+ return mAppRow.label;
+ } else {
+ return "";
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ImportancePreferenceController.java b/src/com/android/settings/notification/ImportancePreferenceController.java
new file mode 100644
index 0000000..ba47c54
--- /dev/null
+++ b/src/com/android/settings/notification/ImportancePreferenceController.java
@@ -0,0 +1,127 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.applications.AppInfoBase;
+import com.android.settings.core.PreferenceControllerMixin;
+
+public class ImportancePreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin {
+
+ private static final String KEY_IMPORTANCE = "importance";
+
+ // Ironically doesn't take an importance listener because the importance is not changed
+ // by this controller's preference but by the screen it links to.
+ public ImportancePreferenceController(Context context) {
+ super(context, null);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_IMPORTANCE;
+ }
+
+ private int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.NOTIFICATION_TOPIC_NOTIFICATION;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ if (mChannel == null) {
+ return false;
+ }
+ return !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId());
+ }
+
+ public void updateState(Preference preference) {
+ if (mAppRow!= null && mChannel != null) {
+ preference.setEnabled(mAdmin == null && isChannelConfigurable());
+ Bundle channelArgs = new Bundle();
+ channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mAppRow.uid);
+ channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mAppRow.pkg);
+ channelArgs.putString(Settings.EXTRA_CHANNEL_ID, mChannel.getId());
+ if (preference.isEnabled()) {
+ Intent channelIntent = Utils.onBuildStartFragmentIntent(mContext,
+ ChannelImportanceSettings.class.getName(),
+ channelArgs, null, R.string.notification_importance_title, null,
+ false, getMetricsCategory());
+ preference.setIntent(channelIntent);
+ preference.setSummary(getImportanceSummary(mContext, mChannel));
+ }
+ }
+ }
+
+ protected static String getImportanceSummary(Context context, NotificationChannel channel) {
+ String title;
+ String summary = null;
+ int importance = channel.getImportance();
+ switch (importance) {
+ case IMPORTANCE_UNSPECIFIED:
+ title = context.getString(R.string.notification_importance_unspecified);
+ break;
+ case NotificationManager.IMPORTANCE_MIN:
+ title = context.getString(R.string.notification_importance_min_title);
+ summary = context.getString(R.string.notification_importance_min);
+ break;
+ case NotificationManager.IMPORTANCE_LOW:
+ title = context.getString(R.string.notification_importance_low_title);
+ summary = context.getString(R.string.notification_importance_low);
+ break;
+ case NotificationManager.IMPORTANCE_DEFAULT:
+ title = context.getString(R.string.notification_importance_default_title);
+ if (SoundPreferenceController.hasValidSound(channel)) {
+ summary = context.getString(R.string.notification_importance_default);
+ } else {
+ summary = context.getString(R.string.notification_importance_low);
+ }
+ break;
+ case NotificationManager.IMPORTANCE_HIGH:
+ case NotificationManager.IMPORTANCE_MAX:
+ title = context.getString(R.string.notification_importance_high_title);
+ if (SoundPreferenceController.hasValidSound(channel)) {
+ summary = context.getString(R.string.notification_importance_high);
+ } else {
+ summary = context.getString(R.string.notification_importance_high_silent);
+ }
+ break;
+ default:
+ return "";
+ }
+
+ if (summary != null) {
+ return context.getString(R.string.notification_importance_divider, title, summary);
+ } else {
+ return title;
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/LightsPreferenceController.java b/src/com/android/settings/notification/LightsPreferenceController.java
new file mode 100644
index 0000000..230c3e2
--- /dev/null
+++ b/src/com/android/settings/notification/LightsPreferenceController.java
@@ -0,0 +1,85 @@
+/*
+ * 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.notification;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+
+public class LightsPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String KEY_LIGHTS = "lights";
+
+ public LightsPreferenceController(Context context, NotificationBackend backend) {
+ super(context, backend);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_LIGHTS;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ if (mChannel == null) {
+ return false;
+ }
+ return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT) && canPulseLight()
+ && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId());
+ }
+
+ public void updateState(Preference preference) {
+ if (mChannel != null) {
+ RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
+ pref.setDisabledByAdmin(mAdmin);
+ pref.setEnabled(isChannelConfigurable() && !pref.isDisabledByAdmin());
+ pref.setChecked(mChannel.shouldShowLights());
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mChannel != null) {
+ final boolean lights = (Boolean) newValue;
+ mChannel.enableLights(lights);
+ saveChannel();
+ }
+ return true;
+ }
+
+ boolean canPulseLight() {
+ if (!mContext.getResources()
+ .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed)) {
+ return false;
+ }
+ return Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.NOTIFICATION_LIGHT_PULSE, 0) == 1;
+ }
+
+}
diff --git a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
index 9855751..dd7b0fb 100644
--- a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
@@ -98,8 +98,8 @@
mLockscreenProfile = (RestrictedDropDownPreference) screen.findPreference(
mWorkSettingKey);
} else {
- removePreference(screen, mWorkSettingKey);
- removePreference(screen, mWorkSettingCategoryKey);
+ setVisible(screen, mWorkSettingKey, false /* visible */);
+ setVisible(screen, mWorkSettingCategoryKey, false /* visible */);
}
mSettingObserver = new SettingObserver();
initLockScreenNotificationPrefDisplay();
diff --git a/src/com/android/settings/notification/NotificationFooterPreference.java b/src/com/android/settings/notification/NotificationFooterPreference.java
new file mode 100644
index 0000000..d44ebee
--- /dev/null
+++ b/src/com/android/settings/notification/NotificationFooterPreference.java
@@ -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.notification;
+
+import android.content.Context;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.text.method.LinkMovementMethod;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.android.settingslib.R;
+
+/**
+ * FooterPreference that can have any key or ordering.
+ */
+public class NotificationFooterPreference extends Preference {
+
+ public NotificationFooterPreference(Context context, AttributeSet attrs) {
+ super(context, attrs, TypedArrayUtils.getAttr(
+ context, R.attr.footerPreferenceStyle, android.R.attr.preferenceStyle));
+ init();
+ }
+
+ public NotificationFooterPreference(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ TextView title = holder.itemView.findViewById(android.R.id.title);
+ title.setMovementMethod(new LinkMovementMethod());
+ title.setClickable(false);
+ title.setLongClickable(false);
+ }
+
+ private void init() {
+ setIcon(R.drawable.ic_info_outline_24dp);
+ setSelectable(false);
+ }
+}
diff --git a/src/com/android/settings/notification/NotificationPreferenceController.java b/src/com/android/settings/notification/NotificationPreferenceController.java
new file mode 100644
index 0000000..b1ef69e
--- /dev/null
+++ b/src/com/android/settings/notification/NotificationPreferenceController.java
@@ -0,0 +1,188 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import android.annotation.Nullable;
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.UserManager;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceGroup;
+import android.support.v7.preference.PreferenceScreen;
+import android.util.Log;
+
+import com.android.settings.wrapper.NotificationChannelGroupWrapper;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.Objects;
+
+/**
+ * Parent class for preferences appearing on notification setting pages at the app,
+ * notification channel group, or notification channel level.
+ */
+public abstract class NotificationPreferenceController extends AbstractPreferenceController
+{
+ private static final String TAG = "ChannelPrefContr";
+ @Nullable protected NotificationChannel mChannel;
+ @Nullable protected NotificationChannelGroupWrapper mChannelGroup;
+ protected RestrictedLockUtils.EnforcedAdmin mAdmin;
+ protected NotificationBackend.AppRow mAppRow;
+ protected final NotificationManager mNm;
+ protected final NotificationBackend mBackend;
+ protected final Context mContext;
+ protected final UserManager mUm;
+ protected final PackageManager mPm;
+ protected Preference mPreference;
+
+ public NotificationPreferenceController(Context context, NotificationBackend backend) {
+ super(context);
+ mContext = context;
+ mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ mBackend = backend;
+ mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ mPm = mContext.getPackageManager();
+ }
+
+ /**
+ * Returns true if field's parent object is not blocked.
+ */
+ @Override
+ public boolean isAvailable() {
+ if (mAppRow == null) {
+ return false;
+ }
+ if (mAppRow.banned) {
+ return false;
+ }
+ if (mChannel != null) {
+ return mChannel.getImportance() != IMPORTANCE_NONE;
+ }
+ if (mChannelGroup != null && mChannelGroup.getGroup() == null) {
+ return !mChannelGroup.isBlocked();
+ }
+ return true;
+ }
+
+ /**
+ * Displays or removes preference in this controller.
+ */
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ if (isAvailable()) {
+ final Preference preference = screen.findPreference(getPreferenceKey());
+ if (mPreference != null && preference == null) {
+ screen.addPreference(mPreference);
+ }
+ if (preference != null) {
+ mPreference = preference;
+ }
+ if (this instanceof Preference.OnPreferenceChangeListener) {
+ mPreference.setOnPreferenceChangeListener(
+ (Preference.OnPreferenceChangeListener) this);
+ }
+ } else {
+ findAndRemovePreference(screen, getPreferenceKey());
+ }
+ }
+
+ // finds the preference recursively and removes it from its parent
+ private void findAndRemovePreference(PreferenceGroup prefGroup, String key) {
+ final int preferenceCount = prefGroup.getPreferenceCount();
+ for (int i = preferenceCount - 1; i >= 0; i--) {
+ final Preference preference = prefGroup.getPreference(i);
+ final String curKey = preference.getKey();
+
+ if (curKey != null && curKey.equals(key)) {
+ mPreference = preference;
+ prefGroup.removePreference(preference);
+ }
+
+ if (preference instanceof PreferenceGroup) {
+ findAndRemovePreference((PreferenceGroup) preference, key);
+ }
+ }
+ }
+
+ protected void onResume(NotificationBackend.AppRow appRow,
+ @Nullable NotificationChannel channel, @Nullable NotificationChannelGroupWrapper group,
+ RestrictedLockUtils.EnforcedAdmin admin) {
+ mAppRow = appRow;
+ mChannel = channel;
+ mChannelGroup = group;
+ mAdmin = admin;
+ }
+
+ protected boolean checkCanBeVisible(int minImportanceVisible) {
+ if (mChannel == null) {
+ Log.w(TAG, "No channel");
+ return false;
+ }
+
+ int importance = mChannel.getImportance();
+ if (importance == NotificationManager.IMPORTANCE_UNSPECIFIED) {
+ return true;
+ }
+ return importance >= minImportanceVisible;
+ }
+
+ protected void saveChannel() {
+ if (mChannel != null && mAppRow != null) {
+ mBackend.updateChannel(mAppRow.pkg, mAppRow.uid, mChannel);
+ }
+ }
+
+ protected boolean isChannelConfigurable() {
+ if (mChannel != null && mAppRow != null) {
+ return !Objects.equals(mChannel.getId(), mAppRow.lockedChannelId);
+ }
+ return false;
+ }
+
+ protected boolean isChannelBlockable() {
+ if (mChannel != null && mAppRow != null) {
+ if (!mAppRow.systemApp) {
+ return true;
+ }
+
+ return mChannel.isBlockableSystem()
+ || mChannel.getImportance() == IMPORTANCE_NONE;
+ }
+ return false;
+ }
+
+ protected boolean isChannelGroupBlockable() {
+ if (mChannelGroup != null && mChannelGroup.getGroup() == null && mAppRow != null) {
+ if (!mAppRow.systemApp) {
+ return true;
+ }
+
+ return mChannelGroup.isBlocked();
+ }
+ return false;
+ }
+
+ protected boolean hasValidGroup() {
+ return mChannelGroup != null && mChannelGroup.getGroup() != null;
+ }
+}
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index 3f366e1..9afb618 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -27,10 +27,15 @@
import com.android.settings.Utils;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.applications.LayoutPreference;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
import com.android.settings.widget.MasterSwitchPreference;
import com.android.settings.widget.SwitchBar;
+import com.android.settings.wrapper.NotificationChannelGroupWrapper;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.widget.FooterPreference;
import android.app.Notification;
@@ -53,10 +58,12 @@
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
+import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -68,66 +75,30 @@
import java.util.Comparator;
import java.util.List;
-abstract public class NotificationSettingsBase extends SettingsPreferenceFragment {
+abstract public class NotificationSettingsBase extends DashboardFragment {
private static final String TAG = "NotifiSettingsBase";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final Intent APP_NOTIFICATION_PREFS_CATEGORY_INTENT
- = new Intent(Intent.ACTION_MAIN)
- .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES);
-
- protected static final int ORDER_FIRST = -500;
- protected static final int ORDER_LAST = 1000;
-
- protected static final String KEY_APP_LINK = "app_link";
- protected static final String KEY_HEADER = "header";
- protected static final String KEY_BLOCK = "block";
- protected static final String KEY_BADGE = "badge";
- protected static final String KEY_BYPASS_DND = "bypass_dnd";
- protected static final String KEY_VISIBILITY_OVERRIDE = "visibility_override";
- protected static final String KEY_BLOCKED_DESC = "block_desc";
- protected static final String KEY_ALLOW_SOUND = "allow_sound";
-
protected PackageManager mPm;
- protected UserManager mUm;
protected NotificationBackend mBackend = new NotificationBackend();
- protected LockPatternUtils mLockPatternUtils;
protected NotificationManager mNm;
protected Context mContext;
- protected boolean mCreated;
+
protected int mUid;
protected int mUserId;
protected String mPkg;
protected PackageInfo mPkgInfo;
- protected RestrictedSwitchPreference mBadge;
- protected RestrictedSwitchPreference mPriority;
- protected RestrictedDropDownPreference mVisibilityOverride;
- protected RestrictedSwitchPreference mImportanceToggle;
- protected LayoutPreference mBlockBar;
- protected SwitchBar mSwitchBar;
- protected FooterPreference mBlockedDesc;
- protected Preference mAppLink;
-
protected EnforcedAdmin mSuspendedAppsAdmin;
- protected boolean mDndVisualEffectsSuppressed;
-
- protected NotificationChannelGroup mChannelGroup;
+ protected NotificationChannelGroupWrapper mChannelGroup;
protected NotificationChannel mChannel;
protected NotificationBackend.AppRow mAppRow;
- protected boolean mShowLegacyChannelConfig = false;
+ protected boolean mShowLegacyChannelConfig = false;
protected boolean mListeningToPackageRemove;
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- if (DEBUG) Log.d(TAG, "onActivityCreated mCreated=" + mCreated);
- if (mCreated) {
- Log.w(TAG, "onActivityCreated: ignoring duplicate call");
- return;
- }
- mCreated = true;
- }
+ protected List<NotificationPreferenceController> mControllers = new ArrayList<>();
+ protected List<Preference> mDynamicPreferences = new ArrayList<>();
+ protected ImportanceListener mImportanceListener = new ImportanceListener();
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -143,7 +114,6 @@
}
mPm = getPackageManager();
- mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mNm = NotificationManager.from(mContext);
mPkg = args != null && args.containsKey(AppInfoBase.ARG_PACKAGE_NAME)
@@ -187,35 +157,41 @@
return;
}
mAppRow = mBackend.loadAppRow(mContext, mPm, mPkgInfo);
+ if (mAppRow == null) {
+ Log.w(TAG, "Can't load package");
+ finish();
+ return;
+ }
+ collectConfigActivities();
Bundle args = getArguments();
mChannel = (args != null && args.containsKey(Settings.EXTRA_CHANNEL_ID)) ?
mBackend.getChannel(mPkg, mUid, args.getString(Settings.EXTRA_CHANNEL_ID)) : null;
- mChannelGroup = (args != null && args.containsKey(Settings.EXTRA_CHANNEL_GROUP_ID)) ?
- mBackend.getGroupWithChannels(mPkg, mUid,
+ NotificationChannelGroup group =
+ (args != null && args.containsKey(Settings.EXTRA_CHANNEL_GROUP_ID))
+ ? mBackend.getGroupWithChannels(mPkg, mUid,
args.getString(Settings.EXTRA_CHANNEL_GROUP_ID))
- : null;
+ : null;
+ if (group != null) {
+ mChannelGroup = new NotificationChannelGroupWrapper(group);
+ }
mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended(
mContext, mPkg, mUserId);
- NotificationManager.Policy policy = mNm.getNotificationPolicy();
- mDndVisualEffectsSuppressed = policy == null ? false : policy.suppressedVisualEffects != 0;
- mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended(
- mContext, mPkg, mUserId);
- }
+ mShowLegacyChannelConfig = mBackend.onlyHasDefaultChannel(mAppRow.pkg, mAppRow.uid)
+ || (mChannel != null
+ && NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId()));
- protected void setVisible(Preference p, boolean visible) {
- setVisible(getPreferenceScreen(), p, visible);
- }
-
- protected void setVisible(PreferenceGroup parent, Preference p, boolean visible) {
- final boolean isVisible = parent.findPreference(p.getKey()) != null;
- if (isVisible == visible) return;
- if (visible) {
- parent.addPreference(p);
- } else {
- parent.removePreference(p);
+ if (mShowLegacyChannelConfig) {
+ mChannel = mBackend.getChannel(
+ mAppRow.pkg, mAppRow.uid, NotificationChannel.DEFAULT_CHANNEL_ID);
+ }
+ if (mChannel != null && !TextUtils.isEmpty(mChannel.getGroup())) {
+ group = mBackend.getGroup(mPkg, mUid, mChannel.getGroup());
+ if (group != null) {
+ mChannelGroup = new NotificationChannelGroupWrapper(group);
+ }
}
}
@@ -224,49 +200,38 @@
getActivity().finish();
}
- private List<ResolveInfo> queryNotificationConfigActivities() {
- if (DEBUG) Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is "
- + APP_NOTIFICATION_PREFS_CATEGORY_INTENT);
+ protected void collectConfigActivities() {
+ Intent intent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES)
+ .setPackage(mAppRow.pkg);
final List<ResolveInfo> resolveInfos = mPm.queryIntentActivities(
- APP_NOTIFICATION_PREFS_CATEGORY_INTENT,
+ intent,
0 //PackageManager.MATCH_DEFAULT_ONLY
);
- return resolveInfos;
- }
-
- protected void collectConfigActivities(ArrayMap<String, NotificationBackend.AppRow> rows) {
- final List<ResolveInfo> resolveInfos = queryNotificationConfigActivities();
- applyConfigActivities(rows, resolveInfos);
- }
-
- private void applyConfigActivities(ArrayMap<String, NotificationBackend.AppRow> rows,
- List<ResolveInfo> resolveInfos) {
- if (DEBUG) Log.d(TAG, "Found " + resolveInfos.size() + " preference activities"
- + (resolveInfos.size() == 0 ? " ;_;" : ""));
+ if (DEBUG) {
+ Log.d(TAG, "Found " + resolveInfos.size() + " preference activities"
+ + (resolveInfos.size() == 0 ? " ;_;" : ""));
+ }
for (ResolveInfo ri : resolveInfos) {
final ActivityInfo activityInfo = ri.activityInfo;
final ApplicationInfo appInfo = activityInfo.applicationInfo;
- final NotificationBackend.AppRow row = rows.get(appInfo.packageName);
- if (row == null) {
- if (DEBUG) Log.v(TAG, "Ignoring notification preference activity ("
- + activityInfo.name + ") for unknown package "
- + activityInfo.packageName);
+ if (mAppRow.settingsIntent != null) {
+ if (DEBUG) {
+ Log.d(TAG, "Ignoring duplicate notification preference activity ("
+ + activityInfo.name + ") for package "
+ + activityInfo.packageName);
+ }
continue;
}
- if (row.settingsIntent != null) {
- if (DEBUG) Log.v(TAG, "Ignoring duplicate notification preference activity ("
- + activityInfo.name + ") for package "
- + activityInfo.packageName);
- continue;
- }
- row.settingsIntent = new Intent(APP_NOTIFICATION_PREFS_CATEGORY_INTENT)
+ mAppRow.settingsIntent = intent
+ .setPackage(null)
.setClassName(activityInfo.packageName, activityInfo.name);
if (mChannel != null) {
- row.settingsIntent.putExtra(Notification.EXTRA_CHANNEL_ID, mChannel.getId());
+ mAppRow.settingsIntent.putExtra(Notification.EXTRA_CHANNEL_ID, mChannel.getId());
}
if (mChannelGroup != null) {
- row.settingsIntent.putExtra(
- Notification.EXTRA_CHANNEL_GROUP_ID, mChannelGroup.getId());
+ mAppRow.settingsIntent.putExtra(
+ Notification.EXTRA_CHANNEL_GROUP_ID, mChannelGroup.getGroup().getId());
}
}
}
@@ -292,134 +257,6 @@
return null;
}
- protected void addAppLinkPref() {
- if (mAppRow.settingsIntent != null && mAppLink == null) {
- addPreferencesFromResource(R.xml.inapp_notification_settings);
- mAppLink = findPreference(KEY_APP_LINK);
- mAppLink.setIntent(mAppRow.settingsIntent);
- }
- }
-
- protected void populateDefaultChannelPrefs() {
- if (mPkgInfo != null && mChannel != null) {
- addPreferencesFromResource(R.xml.legacy_channel_notification_settings);
- setupPriorityPref(mChannel.canBypassDnd());
- setupVisOverridePref(mChannel.getLockscreenVisibility());
- setupImportanceToggle();
- setupBadge();
- }
- mSwitchBar.setChecked(!mAppRow.banned
- && mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE);
- }
-
- abstract void setupBadge();
-
- abstract void updateDependents(boolean banned);
-
- // 'allow sound'
- private void setupImportanceToggle() {
- mImportanceToggle = (RestrictedSwitchPreference) findPreference(KEY_ALLOW_SOUND);
- mImportanceToggle.setDisabledByAdmin(mSuspendedAppsAdmin);
- mImportanceToggle.setEnabled(isChannelConfigurable(mChannel)
- && !mImportanceToggle.isDisabledByAdmin());
- mImportanceToggle.setChecked(mChannel.getImportance() >= IMPORTANCE_DEFAULT
- || mChannel.getImportance() == IMPORTANCE_UNSPECIFIED);
- mImportanceToggle.setOnPreferenceChangeListener(
- new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final int importance =
- ((Boolean) newValue ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_LOW);
- mChannel.setImportance(importance);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- updateDependents(mChannel.getImportance() == IMPORTANCE_NONE);
- return true;
- }
- });
- }
-
- protected void setupPriorityPref(boolean priority) {
- mPriority = (RestrictedSwitchPreference) findPreference(KEY_BYPASS_DND);
- mPriority.setDisabledByAdmin(mSuspendedAppsAdmin);
- mPriority.setEnabled(isChannelConfigurable(mChannel) && !mPriority.isDisabledByAdmin());
- mPriority.setChecked(priority);
- mPriority.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final boolean bypassZenMode = (Boolean) newValue;
- mChannel.setBypassDnd(bypassZenMode);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- return true;
- }
- });
- }
-
- protected void setupVisOverridePref(int sensitive) {
- mVisibilityOverride =
- (RestrictedDropDownPreference) findPreference(KEY_VISIBILITY_OVERRIDE);
- ArrayList<CharSequence> entries = new ArrayList<>();
- ArrayList<CharSequence> values = new ArrayList<>();
-
- mVisibilityOverride.clearRestrictedItems();
- if (getLockscreenNotificationsEnabled() && getLockscreenAllowPrivateNotifications()) {
- final String summaryShowEntry =
- getString(R.string.lock_screen_notifications_summary_show);
- final String summaryShowEntryValue =
- Integer.toString(NotificationManager.VISIBILITY_NO_OVERRIDE);
- entries.add(summaryShowEntry);
- values.add(summaryShowEntryValue);
- setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue,
- DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS
- | DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
- }
-
- final String summaryHideEntry = getString(R.string.lock_screen_notifications_summary_hide);
- final String summaryHideEntryValue = Integer.toString(Notification.VISIBILITY_PRIVATE);
- entries.add(summaryHideEntry);
- values.add(summaryHideEntryValue);
- setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue,
- DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
- entries.add(getString(R.string.lock_screen_notifications_summary_disable));
- values.add(Integer.toString(Notification.VISIBILITY_SECRET));
- mVisibilityOverride.setEntries(entries.toArray(new CharSequence[entries.size()]));
- mVisibilityOverride.setEntryValues(values.toArray(new CharSequence[values.size()]));
-
- if (sensitive == NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
- mVisibilityOverride.setValue(Integer.toString(getGlobalVisibility()));
- } else {
- mVisibilityOverride.setValue(Integer.toString(sensitive));
- }
- mVisibilityOverride.setSummary("%s");
-
- mVisibilityOverride.setOnPreferenceChangeListener(
- new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- int sensitive = Integer.parseInt((String) newValue);
- if (sensitive == getGlobalVisibility()) {
- sensitive = NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
- }
- mChannel.setLockscreenVisibility(sensitive);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_VISIBILITY);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- return true;
- }
- });
- mVisibilityOverride.setDisabledByAdmin(mSuspendedAppsAdmin);
- }
-
- protected void setupBlockDesc(int summaryResId) {
- mBlockedDesc = new FooterPreference(getPrefContext());
- mBlockedDesc.setSelectable(false);
- mBlockedDesc.setTitle(summaryResId);
- mBlockedDesc.setEnabled(false);
- mBlockedDesc.setOrder(50);
- mBlockedDesc.setKey(KEY_BLOCKED_DESC);
- getPreferenceScreen().addPreference(mBlockedDesc);
- }
-
protected Preference populateSingleChannelPrefs(PreferenceGroup parent,
final NotificationChannel channel, String summary) {
MasterSwitchPreference channelPref = new MasterSwitchPreference(
@@ -447,7 +284,7 @@
public boolean onPreferenceChange(Preference preference,
Object o) {
boolean value = (Boolean) o;
- int importance = value ? IMPORTANCE_LOW : IMPORTANCE_NONE;
+ int importance = value ? IMPORTANCE_LOW : IMPORTANCE_NONE;
channel.setImportance(importance);
channel.lockFields(
NotificationChannel.USER_LOCKED_IMPORTANCE);
@@ -461,105 +298,48 @@
return channelPref;
}
- protected boolean checkCanBeVisible(int minImportanceVisible) {
- int importance = mChannel.getImportance();
- if (importance == NotificationManager.IMPORTANCE_UNSPECIFIED) {
- return true;
- }
- return importance >= minImportanceVisible;
- }
-
- protected String getImportanceSummary(NotificationChannel channel) {
- switch (channel.getImportance()) {
- case NotificationManager.IMPORTANCE_UNSPECIFIED:
- return getContext().getString(R.string.notification_importance_unspecified);
- case NotificationManager.IMPORTANCE_NONE:
- return getContext().getString(R.string.notification_toggle_off);
- case NotificationManager.IMPORTANCE_MIN:
- return getContext().getString(R.string.notification_importance_min);
- case NotificationManager.IMPORTANCE_LOW:
- return getContext().getString(R.string.notification_importance_low);
- case NotificationManager.IMPORTANCE_DEFAULT:
- if (hasValidSound(channel)) {
- return getContext().getString(R.string.notification_importance_default);
- } else { // Silent
- return getContext().getString(R.string.notification_importance_low);
- }
- case NotificationManager.IMPORTANCE_HIGH:
- case NotificationManager.IMPORTANCE_MAX:
- default:
- if (hasValidSound(channel)) {
- return getContext().getString(R.string.notification_importance_high);
- } else { // Silent
- return getContext().getString(R.string.notification_importance_high_silent);
- }
- }
- }
-
- private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
- CharSequence entryValue, int keyguardNotificationFeatures) {
- RestrictedLockUtils.EnforcedAdmin admin =
- RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
- mContext, keyguardNotificationFeatures, mUserId);
- if (admin != null) {
- RestrictedDropDownPreference.RestrictedItem item =
- new RestrictedDropDownPreference.RestrictedItem(entry, entryValue, admin);
- mVisibilityOverride.addRestrictedItem(item);
- }
- }
-
- private int getGlobalVisibility() {
- int globalVis = NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
- if (!getLockscreenNotificationsEnabled()) {
- globalVis = Notification.VISIBILITY_SECRET;
- } else if (!getLockscreenAllowPrivateNotifications()) {
- globalVis = Notification.VISIBILITY_PRIVATE;
- }
- return globalVis;
- }
-
- private boolean getLockscreenNotificationsEnabled() {
- return Settings.Secure.getInt(getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0;
- }
-
- private boolean getLockscreenAllowPrivateNotifications() {
- return Settings.Secure.getInt(getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0) != 0;
- }
-
- protected boolean isLockScreenSecure() {
- if (mLockPatternUtils == null) {
- mLockPatternUtils = new LockPatternUtils(getActivity());
- }
- boolean lockscreenSecure = mLockPatternUtils.isSecure(UserHandle.myUserId());
- UserInfo parentUser = mUm.getProfileParent(UserHandle.myUserId());
- if (parentUser != null){
- lockscreenSecure |= mLockPatternUtils.isSecure(parentUser.id);
- }
-
- return lockscreenSecure;
- }
-
protected boolean isChannelConfigurable(NotificationChannel channel) {
- return !channel.getId().equals(mAppRow.lockedChannelId);
+ if (channel != null && mAppRow != null) {
+ return !channel.getId().equals(mAppRow.lockedChannelId);
+ }
+ return false;
}
protected boolean isChannelBlockable(NotificationChannel channel) {
- if (!mAppRow.systemApp) {
- return true;
- }
+ if (channel != null && mAppRow != null) {
+ if (!mAppRow.systemApp) {
+ return true;
+ }
- return channel.isBlockableSystem()
- || channel.getImportance() == NotificationManager.IMPORTANCE_NONE;
+ return channel.isBlockableSystem()
+ || channel.getImportance() == NotificationManager.IMPORTANCE_NONE;
+ }
+ return false;
}
protected boolean isChannelGroupBlockable(NotificationChannelGroup group) {
- if (!mAppRow.systemApp) {
- return true;
- }
+ if (group != null && mAppRow != null) {
+ if (!mAppRow.systemApp) {
+ return true;
+ }
- return group.isBlocked();
+ return group.isBlocked();
+ }
+ return false;
+ }
+
+ protected void setVisible(Preference p, boolean visible) {
+ setVisible(getPreferenceScreen(), p, visible);
+ }
+
+ protected void setVisible(PreferenceGroup parent, Preference p, boolean visible) {
+ final boolean isVisible = parent.findPreference(p.getKey()) != null;
+ if (isVisible == visible) return;
+ if (visible) {
+ parent.addPreference(p);
+ } else {
+ parent.removePreference(p);
+ }
}
protected void startListeningToPackageRemove() {
@@ -589,8 +369,10 @@
public void onReceive(Context context, Intent intent) {
String packageName = intent.getData().getSchemeSpecificPart();
if (mPkgInfo == null || TextUtils.equals(mPkgInfo.packageName, packageName)) {
- if (DEBUG) Log.d(TAG, "Package (" + packageName + ") removed. Removing"
- + "NotificationSettingsBase.");
+ if (DEBUG) {
+ Log.d(TAG, "Package (" + packageName + ") removed. Removing"
+ + "NotificationSettingsBase.");
+ }
onPackageRemoved();
}
}
@@ -604,7 +386,27 @@
return left.getId().compareTo(right.getId());
};
- boolean hasValidSound(NotificationChannel channel) {
- return channel.getSound() != null && !Uri.EMPTY.equals(channel.getSound());
+ protected class ImportanceListener {
+ protected void onImportanceChanged() {
+ final PreferenceScreen screen = getPreferenceScreen();
+ for (NotificationPreferenceController controller : mControllers) {
+ controller.displayPreference(screen);
+ }
+ updatePreferenceStates();
+
+ boolean hideDynamicFields = false;
+ if (mAppRow == null || mAppRow.banned) {
+ hideDynamicFields = true;
+ } else {
+ if (mChannel != null) {
+ hideDynamicFields = mChannel.getImportance() == IMPORTANCE_NONE;
+ } else if (mChannelGroup != null) {
+ hideDynamicFields = mChannelGroup.isBlocked();
+ }
+ }
+ for (Preference preference : mDynamicPreferences) {
+ setVisible(getPreferenceScreen(), preference, !hideDynamicFields);
+ }
+ }
}
}
diff --git a/src/com/android/settings/notification/NotificationsOffPreferenceController.java b/src/com/android/settings/notification/NotificationsOffPreferenceController.java
new file mode 100644
index 0000000..74591cf
--- /dev/null
+++ b/src/com/android/settings/notification/NotificationsOffPreferenceController.java
@@ -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.notification;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.widget.FooterPreference;
+
+public class NotificationsOffPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin {
+
+ private static final String KEY_BLOCKED_DESC = "block_desc";
+
+ public NotificationsOffPreferenceController(Context context) {
+ super(context, null);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BLOCKED_DESC;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (mAppRow == null) {
+ return false;
+ }
+ // Available only when other controllers are unavailable - this UI replaces the UI that
+ // would give more detailed notification controls.
+ return !super.isAvailable();
+ }
+
+ public void updateState(Preference preference) {
+ if (mAppRow != null) {
+ if (mChannel != null) {
+ preference.setTitle(R.string.channel_notifications_off_desc);
+ } else if (mChannelGroup != null && mChannelGroup.getGroup() == null) {
+ preference.setTitle(R.string.channel_group_notifications_off_desc);
+ } else {
+ preference.setTitle(R.string.app_notifications_off_desc);
+ }
+ }
+ preference.setEnabled(false);
+ preference.setSelectable(false);
+ }
+}
diff --git a/src/com/android/settings/notification/SoundPreferenceController.java b/src/com/android/settings/notification/SoundPreferenceController.java
new file mode 100644
index 0000000..e4414b6
--- /dev/null
+++ b/src/com/android/settings/notification/SoundPreferenceController.java
@@ -0,0 +1,119 @@
+/*
+ * 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.notification;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.preference.PreferenceManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.core.PreferenceControllerMixin;
+
+public class SoundPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
+ PreferenceManager.OnActivityResultListener {
+
+ private static final String KEY_SOUND = "ringtone";
+ private final SettingsPreferenceFragment mFragment;
+ private final NotificationSettingsBase.ImportanceListener mListener;
+ private NotificationSoundPreference mPreference;
+ protected static final int CODE = 200;
+
+ public SoundPreferenceController(Context context, SettingsPreferenceFragment hostFragment,
+ NotificationSettingsBase.ImportanceListener importanceListener,
+ NotificationBackend backend) {
+ super(context, backend);
+ mFragment = hostFragment;
+ mListener = importanceListener;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_SOUND;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ if (mChannel == null) {
+ return false;
+ }
+ return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
+ && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId());
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+
+ mPreference = (NotificationSoundPreference) screen.findPreference(getPreferenceKey());
+ }
+
+ public void updateState(Preference preference) {
+ if (mAppRow!= null && mChannel != null) {
+ NotificationSoundPreference pref = (NotificationSoundPreference) preference;
+ pref.setEnabled(mAdmin == null && isChannelConfigurable());
+ pref.setRingtone(mChannel.getSound());
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mChannel != null) {
+ mChannel.setSound((Uri) newValue, mChannel.getAudioAttributes());
+ saveChannel();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (KEY_SOUND.equals(preference.getKey()) && mFragment != null) {
+ NotificationSoundPreference pref = (NotificationSoundPreference) preference;
+ pref.onPrepareRingtonePickerIntent(pref.getIntent());
+ mFragment.startActivityForResult(preference.getIntent(), CODE);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (CODE == requestCode) {
+ if (mPreference != null) {
+ mPreference.onActivityResult(requestCode, resultCode, data);
+ }
+ // the importance hasn't changed, but the importance description might as a result of
+ // user's selection.
+ mListener.onImportanceChanged();
+ return true;
+ }
+ return false;
+ }
+
+ protected static boolean hasValidSound(NotificationChannel channel) {
+ return channel != null
+ && channel.getSound() != null && !Uri.EMPTY.equals(channel.getSound());
+ }
+}
diff --git a/src/com/android/settings/notification/VibrationPreferenceController.java b/src/com/android/settings/notification/VibrationPreferenceController.java
new file mode 100644
index 0000000..f9b786d
--- /dev/null
+++ b/src/com/android/settings/notification/VibrationPreferenceController.java
@@ -0,0 +1,73 @@
+/*
+ * 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.notification;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Vibrator;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+public class VibrationPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String KEY_VIBRATE = "vibrate";
+ private final Vibrator mVibrator;
+
+ public VibrationPreferenceController(Context context, NotificationBackend backend) {
+ super(context, backend);
+ mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_VIBRATE;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable() || mChannel == null) {
+ return false;
+ }
+ return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
+ && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())
+ && mVibrator != null
+ && mVibrator.hasVibrator();
+ }
+
+ public void updateState(Preference preference) {
+ if (mChannel != null) {
+ RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
+ pref.setDisabledByAdmin(mAdmin);
+ pref.setEnabled(!pref.isDisabledByAdmin() && isChannelConfigurable());
+ pref.setChecked(mChannel.shouldVibrate());
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mChannel != null) {
+ final boolean vibrate = (Boolean) newValue;
+ mChannel.enableVibration(vibrate);
+ saveChannel();
+ }
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/VisibilityPreferenceController.java b/src/com/android/settings/notification/VisibilityPreferenceController.java
new file mode 100644
index 0000000..76caac0
--- /dev/null
+++ b/src/com/android/settings/notification/VisibilityPreferenceController.java
@@ -0,0 +1,165 @@
+/*
+ * 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.notification;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.notification.NotificationListenerService;
+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.RestrictedLockUtils;
+
+import java.util.ArrayList;
+
+public class VisibilityPreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String TAG = "ChannelVisPrefContr";
+ private static final String KEY_VISIBILITY_OVERRIDE = "visibility_override";
+ private LockPatternUtils mLockPatternUtils;
+
+ public VisibilityPreferenceController(Context context, LockPatternUtils utils,
+ NotificationBackend backend) {
+ super(context, backend);
+ mLockPatternUtils = utils;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_VISIBILITY_OVERRIDE;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ if (mChannel == null || mAppRow.banned) {
+ return false;
+ }
+ return checkCanBeVisible(NotificationManager.IMPORTANCE_LOW) && isLockScreenSecure();
+ }
+
+ public void updateState(Preference preference) {
+ if (mChannel != null && mAppRow != null) {
+ RestrictedDropDownPreference pref = (RestrictedDropDownPreference) preference;
+ ArrayList<CharSequence> entries = new ArrayList<>();
+ ArrayList<CharSequence> values = new ArrayList<>();
+
+ pref.clearRestrictedItems();
+ if (getLockscreenNotificationsEnabled() && getLockscreenAllowPrivateNotifications()) {
+ final String summaryShowEntry =
+ mContext.getString(R.string.lock_screen_notifications_summary_show);
+ final String summaryShowEntryValue =
+ Integer.toString(NotificationManager.VISIBILITY_NO_OVERRIDE);
+ entries.add(summaryShowEntry);
+ values.add(summaryShowEntryValue);
+ setRestrictedIfNotificationFeaturesDisabled(pref, summaryShowEntry,
+ summaryShowEntryValue,
+ DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS
+ | DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+ }
+
+ final String summaryHideEntry =
+ mContext.getString(R.string.lock_screen_notifications_summary_hide);
+ final String summaryHideEntryValue = Integer.toString(Notification.VISIBILITY_PRIVATE);
+ entries.add(summaryHideEntry);
+ values.add(summaryHideEntryValue);
+ setRestrictedIfNotificationFeaturesDisabled(pref,
+ summaryHideEntry, summaryHideEntryValue,
+ DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+ entries.add(mContext.getString(R.string.lock_screen_notifications_summary_disable));
+ values.add(Integer.toString(Notification.VISIBILITY_SECRET));
+ pref.setEntries(entries.toArray(new CharSequence[entries.size()]));
+ pref.setEntryValues(values.toArray(new CharSequence[values.size()]));
+
+ if (mChannel.getLockscreenVisibility()
+ == NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
+ pref.setValue(Integer.toString(getGlobalVisibility()));
+ } else {
+ pref.setValue(Integer.toString(mChannel.getLockscreenVisibility()));
+ }
+ pref.setSummary("%s");
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mChannel != null) {
+ int sensitive = Integer.parseInt((String) newValue);
+ if (sensitive == getGlobalVisibility()) {
+ sensitive = NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
+ }
+ mChannel.setLockscreenVisibility(sensitive);
+ mChannel.lockFields(NotificationChannel.USER_LOCKED_VISIBILITY);
+ saveChannel();
+ }
+ return true;
+ }
+
+ private void setRestrictedIfNotificationFeaturesDisabled(RestrictedDropDownPreference pref,
+ CharSequence entry, CharSequence entryValue, int keyguardNotificationFeatures) {
+ RestrictedLockUtils.EnforcedAdmin admin =
+ RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+ mContext, keyguardNotificationFeatures, mAppRow.userId);
+ if (admin != null) {
+ RestrictedDropDownPreference.RestrictedItem item =
+ new RestrictedDropDownPreference.RestrictedItem(entry, entryValue, admin);
+ pref.addRestrictedItem(item);
+ }
+ }
+
+ private int getGlobalVisibility() {
+ int globalVis = NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
+ if (!getLockscreenNotificationsEnabled()) {
+ globalVis = Notification.VISIBILITY_SECRET;
+ } else if (!getLockscreenAllowPrivateNotifications()) {
+ globalVis = Notification.VISIBILITY_PRIVATE;
+ }
+ return globalVis;
+ }
+
+ private boolean getLockscreenNotificationsEnabled() {
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0;
+ }
+
+ private boolean getLockscreenAllowPrivateNotifications() {
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0) != 0;
+ }
+
+ protected boolean isLockScreenSecure() {
+ boolean lockscreenSecure = mLockPatternUtils.isSecure(UserHandle.myUserId());
+ UserInfo parentUser = mUm.getProfileParent(UserHandle.myUserId());
+ if (parentUser != null){
+ lockscreenSecure |= mLockPatternUtils.isSecure(parentUser.id);
+ }
+
+ return lockscreenSecure;
+ }
+
+}
diff --git a/src/com/android/settings/notification/ZenAccessSettings.java b/src/com/android/settings/notification/ZenAccessSettings.java
index 0a4915a..d92bc5a 100644
--- a/src/com/android/settings/notification/ZenAccessSettings.java
+++ b/src/com/android/settings/notification/ZenAccessSettings.java
@@ -77,9 +77,6 @@
mContext = getActivity();
mPkgMan = mContext.getPackageManager();
mNoMan = mContext.getSystemService(NotificationManager.class);
- if (!usePreferenceScreenTitle()) {
- setPreferenceScreen(getPreferenceManager().createPreferenceScreen(mContext));
- }
}
@Override
diff --git a/src/com/android/settings/print/PrintJobSettingsFragment.java b/src/com/android/settings/print/PrintJobSettingsFragment.java
index 349d9fc..7142e49 100644
--- a/src/com/android/settings/print/PrintJobSettingsFragment.java
+++ b/src/com/android/settings/print/PrintJobSettingsFragment.java
@@ -17,6 +17,8 @@
package com.android.settings.print;
import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.print.PrintJob;
import android.print.PrintJobId;
@@ -31,8 +33,8 @@
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-
import android.view.ViewGroup;
+
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
@@ -220,16 +222,28 @@
info.getCreationTime(), info.getCreationTime(), DateFormat.SHORT,
DateFormat.SHORT)));
+ TypedArray a = getActivity().obtainStyledAttributes(new int[]{
+ android.R.attr.colorControlNormal});
+ int tintColor = a.getColor(0, 0);
+ a.recycle();
+
switch (info.getState()) {
case PrintJobInfo.STATE_QUEUED:
case PrintJobInfo.STATE_STARTED: {
- mPrintJobPreference.setIcon(R.drawable.ic_print);
- } break;
+ Drawable icon = getActivity().getDrawable(com.android.internal.R.drawable.ic_print);
+ icon.setTint(tintColor);
+ mPrintJobPreference.setIcon(icon);
+ break;
+ }
case PrintJobInfo.STATE_FAILED:
case PrintJobInfo.STATE_BLOCKED: {
- mPrintJobPreference.setIcon(R.drawable.ic_print_error);
- } break;
+ Drawable icon = getActivity().getDrawable(
+ com.android.internal.R.drawable.ic_print_error);
+ icon.setTint(tintColor);
+ mPrintJobPreference.setIcon(icon);
+ break;
+ }
}
CharSequence status = info.getStatus(getPackageManager());
diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java
index 26e760c..3d63000 100644
--- a/src/com/android/settings/print/PrintSettingsFragment.java
+++ b/src/com/android/settings/print/PrintSettingsFragment.java
@@ -24,6 +24,7 @@
import android.content.Intent;
import android.content.Loader;
import android.content.pm.PackageManager;
+import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
@@ -359,15 +360,29 @@
printJob.getCreationTime(), printJob.getCreationTime(),
DateFormat.SHORT, DateFormat.SHORT)));
+ TypedArray a = getActivity().obtainStyledAttributes(new int[]{
+ android.R.attr.colorControlNormal});
+ int tintColor = a.getColor(0, 0);
+ a.recycle();
+
switch (printJob.getState()) {
case PrintJobInfo.STATE_QUEUED:
- case PrintJobInfo.STATE_STARTED:
- preference.setIcon(R.drawable.ic_print);
+ case PrintJobInfo.STATE_STARTED: {
+ Drawable icon = getActivity().getDrawable(
+ com.android.internal.R.drawable.ic_print);
+ icon.setTint(tintColor);
+ preference.setIcon(icon);
break;
+ }
+
case PrintJobInfo.STATE_FAILED:
- case PrintJobInfo.STATE_BLOCKED:
- preference.setIcon(R.drawable.ic_print_error);
+ case PrintJobInfo.STATE_BLOCKED: {
+ Drawable icon = getActivity().getDrawable(
+ com.android.internal.R.drawable.ic_print_error);
+ icon.setTint(tintColor);
+ preference.setIcon(icon);
break;
+ }
}
Bundle extras = preference.getExtras();
diff --git a/src/com/android/settings/search/DatabaseIndexingUtils.java b/src/com/android/settings/search/DatabaseIndexingUtils.java
index 8d63ea5..39bcdf84 100644
--- a/src/com/android/settings/search/DatabaseIndexingUtils.java
+++ b/src/com/android/settings/search/DatabaseIndexingUtils.java
@@ -60,8 +60,9 @@
args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
final Intent searchDestination = Utils.onBuildStartFragmentIntent(context,
className, args, null, 0, screenTitle, false, sourceMetricsCategory);
- searchDestination.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
- searchDestination.setClass(context, SearchResultTrampoline.class);
+ searchDestination.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key)
+ .setAction("com.android.settings.SEARCH_RESULT_TRAMPOLINE")
+ .setComponent(null);
return searchDestination;
}
diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java
index 42afee9..d0c0cd9 100644
--- a/src/com/android/settings/search/SearchFeatureProvider.java
+++ b/src/com/android/settings/search/SearchFeatureProvider.java
@@ -17,11 +17,16 @@
package com.android.settings.search;
import android.annotation.NonNull;
+import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.util.FeatureFlagUtils;
import android.util.Pair;
import android.view.View;
+import android.widget.Toolbar;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.dashboard.SiteMapManager;
import java.util.List;
@@ -34,11 +39,6 @@
public interface SearchFeatureProvider {
/**
- * @return true to use the new version of search
- */
- boolean isEnabled(Context context);
-
- /**
* Ensures the caller has necessary privilege to launch search result page.
*
* @throws IllegalArgumentException when caller is null
@@ -164,4 +164,22 @@
default FutureTask<List<Pair<String, Float>>> getRankerTask(Context context, String query) {
return null;
}
+
+ /**
+ * Initializes the search toolbar.
+ */
+ default void initSearchToolbar(Activity activity, Toolbar toolbar) {
+ if (activity == null || toolbar == null) {
+ return;
+ }
+ toolbar.setOnClickListener(tb -> {
+ final Intent intent;
+ if (FeatureFlagUtils.isEnabled(activity, FeatureFlags.SEARCH_V2)) {
+ intent = new Intent("com.android.settings.action.SETTINGS_SEARCH");
+ } else {
+ intent = new Intent(activity, SearchActivity.class);
+ }
+ activity.startActivityForResult(intent, 0 /* requestCode */);
+ });
+ }
}
diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java
index e0fbfd7..1c96714 100644
--- a/src/com/android/settings/search/SearchFeatureProviderImpl.java
+++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java
@@ -40,26 +40,26 @@
private static final String TAG = "SearchFeatureProvider";
private static final String METRICS_ACTION_SETTINGS_INDEX = "search_synchronous_indexing";
-
private DatabaseIndexingManager mDatabaseIndexingManager;
private SiteMapManager mSiteMapManager;
private ExecutorService mExecutorService;
@Override
- public boolean isEnabled(Context context) {
- return true;
- }
-
- @Override
public void verifyLaunchSearchResultPageCaller(Context context, ComponentName caller) {
if (caller == null) {
throw new IllegalArgumentException("ExternalSettingsTrampoline intents "
+ "must be called with startActivityForResult");
}
final String packageName = caller.getPackageName();
- if (!TextUtils.equals(packageName, context.getPackageName())) {
- throw new SecurityException("Only Settings app can launch search result page");
+ final boolean isSettingsPackage = TextUtils.equals(packageName, context.getPackageName())
+ || TextUtils.equals(getSettingsIntelligencePkgName(), packageName);
+ final boolean isWhitelistedPackage =
+ isSignatureWhitelisted(context, caller.getPackageName());
+ if (isSettingsPackage || isWhitelistedPackage) {
+ return;
}
+ throw new SecurityException("Search result intents must be called with from a "
+ + "whitelisted package.");
}
@Override
@@ -141,6 +141,14 @@
return mExecutorService;
}
+ protected boolean isSignatureWhitelisted(Context context, String callerPackage) {
+ return false;
+ }
+
+ protected String getSettingsIntelligencePkgName() {
+ return "com.android.settings.intelligence";
+ }
+
/**
* A generic method to make the query suitable for searching the database.
*
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 47d17b6..46e693d 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -16,9 +16,7 @@
package com.android.settings.search;
-import android.provider.SearchIndexableResource;
import android.support.annotation.VisibleForTesting;
-import android.support.annotation.XmlRes;
import com.android.settings.DateTimeSettings;
import com.android.settings.DeviceInfoSettings;
@@ -62,11 +60,11 @@
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
import com.android.settings.inputmethod.VirtualKeyboardFragment;
import com.android.settings.language.LanguageAndInputSettings;
+import com.android.settings.location.LocationMode;
import com.android.settings.location.LocationSettings;
import com.android.settings.location.ScanningSettings;
import com.android.settings.network.NetworkDashboardFragment;
import com.android.settings.nfc.PaymentSettings;
-import com.android.settings.notification.ChannelImportanceSettings;
import com.android.settings.notification.ConfigureNotificationSettings;
import com.android.settings.notification.SoundSettings;
import com.android.settings.notification.ZenModeAutomationSettings;
@@ -89,22 +87,17 @@
import com.android.settings.wifi.WifiSettings;
import java.util.Collection;
-import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
public final class SearchIndexableResources {
- @XmlRes
- public static final int NO_RES_ID = 0;
@VisibleForTesting
- static final HashMap<String, SearchIndexableResource> sResMap = new HashMap<>();
+ static final Set<Class> sProviders = new HashSet<>();
@VisibleForTesting
- static void addIndex(Class<?> indexClass) {
- String className = indexClass.getName();
- SearchIndexableResource resource = new SearchIndexableResource(
- 0 /* rank */, NO_RES_ID, className, NO_RES_ID);
-
- sResMap.put(className, resource);
+ static void addIndex(Class indexClass) {
+ sProviders.add(indexClass);
}
static {
@@ -137,6 +130,7 @@
addIndex(GestureSettings.class);
addIndex(LanguageAndInputSettings.class);
addIndex(LocationSettings.class);
+ addIndex(LocationMode.class);
addIndex(ScanningSettings.class);
addIndex(SecuritySettings.class);
addIndex(ScreenLockSettings.class);
@@ -165,7 +159,6 @@
addIndex(TtsEnginePreferenceFragment.class);
addIndex(MagnificationPreferenceFragment.class);
addIndex(AccessibilityShortcutPreferenceFragment.class);
- addIndex(ChannelImportanceSettings.class);
addIndex(DreamSettings.class);
addIndex(SupportDashboardActivity.class);
addIndex(AutomaticStorageManagerSettings.class);
@@ -180,15 +173,5 @@
private SearchIndexableResources() {
}
- public static int size() {
- return sResMap.size();
- }
-
- public static SearchIndexableResource getResourceByName(String className) {
- return sResMap.get(className);
- }
-
- public static Collection<SearchIndexableResource> values() {
- return sResMap.values();
- }
+ public static Collection<Class> providerValues() { return sProviders;}
}
\ No newline at end of file
diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
index 622378b..968847b 100644
--- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
+++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
@@ -17,6 +17,19 @@
package com.android.settings.search;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_CLASS_NAME;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ENTRIES;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ICON_RESID;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_ACTION;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_CLASS;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEY;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEYWORDS;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SCREEN_TITLE;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_OFF;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_ON;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_TITLE;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_USER_ID;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION;
@@ -33,11 +46,12 @@
import android.database.MatrixCursor;
import android.provider.SearchIndexableResource;
import android.provider.SearchIndexablesProvider;
+import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
+import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
@@ -60,8 +74,9 @@
@Override
public Cursor queryXmlResources(String[] projection) {
MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS);
- Collection<SearchIndexableResource> values = SearchIndexableResources.values();
- for (SearchIndexableResource val : values) {
+ final List<SearchIndexableResource> resources =
+ getSearchIndexableResourcesFromProvider(getContext());
+ for (SearchIndexableResource val : resources) {
Object[] ref = new Object[INDEXABLES_XML_RES_COLUMNS.length];
ref[COLUMN_INDEX_XML_RES_RANK] = val.rank;
ref[COLUMN_INDEX_XML_RES_RESID] = val.xmlResId;
@@ -72,13 +87,33 @@
ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = null; // intent target class
cursor.addRow(ref);
}
+
return cursor;
}
@Override
public Cursor queryRawData(String[] projection) {
- MatrixCursor result = new MatrixCursor(INDEXABLES_RAW_COLUMNS);
- return result;
+ MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS);
+ final List<SearchIndexableRaw> raws = getSearchIndexableRawFromProvider(getContext());
+ for (SearchIndexableRaw val : raws) {
+ Object[] ref = new Object[INDEXABLES_RAW_COLUMNS.length];
+ ref[COLUMN_INDEX_RAW_TITLE] = val.title;
+ ref[COLUMN_INDEX_RAW_SUMMARY_ON] = val.summaryOn;
+ ref[COLUMN_INDEX_RAW_SUMMARY_OFF] = val.summaryOff;
+ ref[COLUMN_INDEX_RAW_ENTRIES] = val.entries;
+ ref[COLUMN_INDEX_RAW_KEYWORDS] = val.keywords;
+ ref[COLUMN_INDEX_RAW_SCREEN_TITLE] = val.screenTitle;
+ ref[COLUMN_INDEX_RAW_CLASS_NAME] = val.className;
+ ref[COLUMN_INDEX_RAW_ICON_RESID] = val.iconResId;
+ ref[COLUMN_INDEX_RAW_INTENT_ACTION] = val.intentAction;
+ ref[COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE] = val.intentTargetPackage;
+ ref[COLUMN_INDEX_RAW_INTENT_TARGET_CLASS] = val.intentTargetClass;
+ ref[COLUMN_INDEX_RAW_KEY] = val.key;
+ ref[COLUMN_INDEX_RAW_USER_ID] = val.userId;
+ cursor.addRow(ref);
+ }
+
+ return cursor;
}
/**
@@ -89,29 +124,24 @@
@Override
public Cursor queryNonIndexableKeys(String[] projection) {
MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS);
- final Collection<String> values = new HashSet<>();
- final Context context = getContext();
+ final List<String> nonIndexableKeys = getNonIndexableKeysFromProvider(getContext());
+ for (String nik : nonIndexableKeys) {
+ final Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length];
+ ref[COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE] = nik;
+ cursor.addRow(ref);
+ }
- for (SearchIndexableResource sir : SearchIndexableResources.values()) {
- if (DEBUG) {
- Log.d(TAG, "Getting non-indexable from " + sir.className);
- }
+ return cursor;
+ }
+
+ private List<String> getNonIndexableKeysFromProvider(Context context) {
+ final Collection<Class> values = SearchIndexableResources.providerValues();
+ final List<String> nonIndexableKeys = new ArrayList<>();
+
+ for (Class<?> clazz : values) {
final long startTime = System.currentTimeMillis();
- final Class<?> clazz = DatabaseIndexingUtils.getIndexableClass(sir.className);
- if (clazz == null) {
- Log.d(TAG, "SearchIndexableResource '" + sir.className +
- "' should implement the " + Indexable.class.getName() + " interface!");
- continue;
- }
-
- final Indexable.SearchIndexProvider provider =
- DatabaseIndexingUtils.getSearchIndexProvider(clazz);
-
- if (provider == null) {
- Log.d(TAG, "Unable to get SearchIndexableProvider from " + clazz);
- continue;
- }
-
+ Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(
+ clazz);
List<String> providerNonIndexableKeys = provider.getNonIndexableKeys(context);
if (providerNonIndexableKeys == null || providerNonIndexableKeys.isEmpty()) {
@@ -123,22 +153,71 @@
}
if (providerNonIndexableKeys.removeAll(INVALID_KEYS)) {
- Log.v(TAG, clazz.getName() + " tried to add an empty non-indexable key");
+ Log.v(TAG, provider + " tried to add an empty non-indexable key");
}
+
if (DEBUG) {
final long totalTime = System.currentTimeMillis() - startTime;
Log.d(TAG, "Non-indexables " + providerNonIndexableKeys.size() + ", total time "
+ totalTime);
}
- values.addAll(providerNonIndexableKeys);
+
+ nonIndexableKeys.addAll(providerNonIndexableKeys);
}
- for (String nik : values) {
+ return nonIndexableKeys;
+ }
- final Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length];
- ref[COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE] = nik;
- cursor.addRow(ref);
+ private List<SearchIndexableResource> getSearchIndexableResourcesFromProvider(Context context) {
+ Collection<Class> values = SearchIndexableResources.providerValues();
+ List<SearchIndexableResource> resourceList = new ArrayList<>();
+
+ for (Class<?> clazz : values) {
+ Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(
+ clazz);
+
+ final List<SearchIndexableResource> resList =
+ provider.getXmlResourcesToIndex(context, true);
+
+ if (resList == null) {
+ continue;
+ }
+
+ for (SearchIndexableResource item : resList) {
+ item.className = TextUtils.isEmpty(item.className)
+ ? clazz.getName()
+ : item.className;
+ }
+
+ resourceList.addAll(resList);
}
- return cursor;
+
+ return resourceList;
+ }
+
+ private List<SearchIndexableRaw> getSearchIndexableRawFromProvider(Context context) {
+ final Collection<Class> values = SearchIndexableResources.providerValues();
+ final List<SearchIndexableRaw> rawList = new ArrayList<>();
+
+ for (Class<?> clazz : values) {
+ Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(
+ clazz);
+ final List<SearchIndexableRaw> providerRaws = provider.getRawDataToIndex(context,
+ true /* enabled */);
+
+ if (providerRaws == null) {
+ continue;
+ }
+
+ for (SearchIndexableRaw raw : providerRaws) {
+ // The classname and intent information comes from the PreIndexData
+ // This will be more clear when provider conversion is done at PreIndex time.
+ raw.className = clazz.getName();
+
+ }
+ rawList.addAll(providerRaws);
+ }
+
+ return rawList;
}
}
diff --git a/src/com/android/settings/search/indexing/IndexDataConverter.java b/src/com/android/settings/search/indexing/IndexDataConverter.java
index ab60f62..65fa279 100644
--- a/src/com/android/settings/search/indexing/IndexDataConverter.java
+++ b/src/com/android/settings/search/indexing/IndexDataConverter.java
@@ -31,7 +31,6 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.search.DatabaseIndexingUtils;
-import com.android.settings.search.Indexable;
import com.android.settings.search.ResultPayload;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.search.XmlParserUtils;
@@ -89,21 +88,8 @@
final SearchIndexableResource sir = (SearchIndexableResource) data;
final Set<String> resourceNonIndexableKeys =
getNonIndexableKeysForResource(nonIndexableKeys, sir.packageName);
-
- if (sir.xmlResId == 0) {
- // Index from provider
- final Indexable.SearchIndexProvider provider = getSearchProvider(sir);
- if (provider == null) {
- continue;
- }
- indexData.addAll(convertIndexProvider(provider, sir, resourceNonIndexableKeys));
-
- } else {
- final List<IndexData> resourceData = convertResource(sir,
- resourceNonIndexableKeys);
- indexData.addAll(resourceData);
- }
-
+ final List<IndexData> resourceData = convertResource(sir, resourceNonIndexableKeys);
+ indexData.addAll(resourceData);
}
}
@@ -305,84 +291,10 @@
return resourceIndexData;
}
- private List<IndexData> convertIndexProvider(Indexable.SearchIndexProvider provider,
- SearchIndexableResource sir, Set<String> nonIndexableKeys) {
- final List<IndexData> indexData = new ArrayList<>();
-
- final String className = sir.className;
- final String intentAction = sir.intentAction;
- final String intentTargetPackage = sir.intentTargetPackage;
-
- // TODO (b/65376542) Move provider conversion to PreIndexTime
- // TODO (b/37741509) Providers don't use general non-indexable keys
- nonIndexableKeys.addAll(provider.getNonIndexableKeys(mContext));
-
- final List<SearchIndexableRaw> rawList = provider.getRawDataToIndex(mContext,
- true /* enabled */);
-
- if (rawList != null) {
- for (SearchIndexableRaw raw : rawList) {
- // The classname and intent information comes from the PreIndexData
- // This will be more clear when provider conversion is done at PreIndex time.
- raw.className = className;
- raw.intentAction = intentAction;
- raw.intentTargetPackage = intentTargetPackage;
-
- IndexData.Builder builder = convertRaw(raw, nonIndexableKeys);
- if (builder != null) {
- indexData.add(builder.build(mContext));
- }
- }
- }
-
- final List<SearchIndexableResource> resList =
- provider.getXmlResourcesToIndex(mContext, true);
-
- if (resList != null) {
- for (SearchIndexableResource item : resList) {
- item.className = TextUtils.isEmpty(item.className)
- ? className
- : item.className;
- item.intentAction = TextUtils.isEmpty(item.intentAction)
- ? intentAction
- : item.intentAction;
- item.intentTargetPackage = TextUtils.isEmpty(item.intentTargetPackage)
- ? intentTargetPackage
- : item.intentTargetPackage;
-
- indexData.addAll(convertResource(item, nonIndexableKeys));
- }
- }
-
- return indexData;
- }
-
private Set<String> getNonIndexableKeysForResource(Map<String, Set<String>> nonIndexableKeys,
String packageName) {
return nonIndexableKeys.containsKey(packageName)
? nonIndexableKeys.get(packageName)
: new HashSet<>();
}
-
- /**
- * @return Return the {@link Indexable.SearchIndexProvider} corresponding to the
- * class specified by the Class name specified by {@param sir}.
- */
- private Indexable.SearchIndexProvider getSearchProvider(SearchIndexableResource sir) {
- if (TextUtils.isEmpty(sir.className)) {
- Log.w(LOG_TAG, "Cannot index an empty Search Provider name!");
- return null;
- }
-
- final Class<?> clazz = DatabaseIndexingUtils.getIndexableClass(sir.className);
- if (clazz == null) {
- Log.d(LOG_TAG, "SearchIndexableResource '" + sir.className +
- "' should implement the " + Indexable.class.getName() + " interface!");
- return null;
- }
-
- // Will be non null only for a Local provider implementing a
- // SEARCH_INDEX_DATA_PROVIDER field
- return DatabaseIndexingUtils.getSearchIndexProvider(clazz);
- }
}
diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java
index 02beaaa..35ce909 100644
--- a/src/com/android/settings/security/SecuritySettings.java
+++ b/src/com/android/settings/security/SecuritySettings.java
@@ -206,7 +206,7 @@
mManageDeviceAdminPreferenceController
= new ManageDeviceAdminPreferenceController(activity);
mEnterprisePrivacyPreferenceController
- = new EnterprisePrivacyPreferenceController(activity, null /* lifecycle */);
+ = new EnterprisePrivacyPreferenceController(activity);
mLockScreenNotificationPreferenceController
= new LockScreenNotificationPreferenceController(activity);
}
@@ -400,7 +400,9 @@
mManageDeviceAdminPreferenceController.updateState(
root.findPreference(KEY_MANAGE_DEVICE_ADMIN));
mEnterprisePrivacyPreferenceController.displayPreference(root);
- mEnterprisePrivacyPreferenceController.onResume();
+ final Preference enterprisePrivacyPreference = root.findPreference(
+ mEnterprisePrivacyPreferenceController.getPreferenceKey());
+ mEnterprisePrivacyPreferenceController.updateState(enterprisePrivacyPreference);
return root;
}
@@ -893,7 +895,7 @@
keys.add(KEY_MANAGE_TRUST_AGENTS);
}
- if (!(new EnterprisePrivacyPreferenceController(context, null /* lifecycle */))
+ if (!(new EnterprisePrivacyPreferenceController(context))
.isAvailable()) {
keys.add(KEY_ENTERPRISE_PRIVACY);
}
diff --git a/src/com/android/settings/security/screenlock/ScreenLockSettings.java b/src/com/android/settings/security/screenlock/ScreenLockSettings.java
index 8d48325..029a556 100644
--- a/src/com/android/settings/security/screenlock/ScreenLockSettings.java
+++ b/src/com/android/settings/security/screenlock/ScreenLockSettings.java
@@ -39,6 +39,8 @@
private static final String TAG = "ScreenLockSettings";
+ private static final String KEY_LOCK_SCREEN_TITLE = "security_settings_password_sub_screen";
+
private static final int MY_USER_ID = UserHandle.myUserId();
private LockPatternUtils mLockPatternUtils;
@@ -102,5 +104,12 @@
return buildPreferenceControllers(context, null /* parent */,
null /* lifecycle */, new LockPatternUtils(context));
}
+
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ final List<String> keys = super.getNonIndexableKeys(context);
+ keys.add(KEY_LOCK_SCREEN_TITLE);
+ return keys;
+ }
};
}
diff --git a/src/com/android/settings/users/ProfileUpdateReceiver.java b/src/com/android/settings/users/ProfileUpdateReceiver.java
index d532089..80fa10a 100644
--- a/src/com/android/settings/users/ProfileUpdateReceiver.java
+++ b/src/com/android/settings/users/ProfileUpdateReceiver.java
@@ -38,13 +38,13 @@
// Profile changed, lets get the photo and write to user manager
new Thread() {
public void run() {
- Utils.copyMeProfilePhoto(context, null);
+ UserSettings.copyMeProfilePhoto(context, null);
copyProfileName(context);
}
}.start();
}
- static void copyProfileName(Context context) {
+ private static void copyProfileName(Context context) {
SharedPreferences prefs = context.getSharedPreferences("profile", Context.MODE_PRIVATE);
if (prefs.contains(KEY_PROFILE_NAME_COPIED_ONCE)) {
return;
@@ -55,7 +55,8 @@
String profileName = Utils.getMeProfileName(context, false /* partial name */);
if (profileName != null && profileName.length() > 0) {
um.setUserName(userId, profileName);
- // Flag that we've written the profile one time at least. No need to do it in the future.
+ // Flag that we've written the profile one time at least. No need to do it in the
+ // future.
prefs.edit().putBoolean(KEY_PROFILE_NAME_COPIED_ONCE, true).commit();
}
}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 642f289..906c9d4 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -30,7 +30,9 @@
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
@@ -38,7 +40,10 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.ContactsContract;
import android.provider.Settings.Global;
+import android.support.annotation.VisibleForTesting;
+import android.support.annotation.WorkerThread;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.support.v7.preference.PreferenceGroup;
@@ -53,6 +58,7 @@
import android.widget.SimpleAdapter;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.UserIcons;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -68,6 +74,8 @@
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.drawable.CircleFramedDrawable;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -134,7 +142,8 @@
private boolean mShouldUpdateUserList = true;
private final Object mUserLock = new Object();
private UserManager mUserManager;
- private SparseArray<Bitmap> mUserIcons = new SparseArray<Bitmap>();
+ private SparseArray<Bitmap> mUserIcons = new SparseArray<>();
+ private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<>();
private EditUserInfoController mEditUserInfoController =
new EditUserInfoController();
@@ -324,7 +333,7 @@
UserInfo user = mUserManager.getUserInfo(UserHandle.myUserId());
if (user.iconPath == null || user.iconPath.equals("")) {
// Assign profile photo.
- Utils.copyMeProfilePhoto(getActivity(), user);
+ copyMeProfilePhoto(getActivity(), user);
}
return user.name;
}
@@ -397,7 +406,7 @@
private UserInfo createRestrictedProfile() {
UserInfo newUserInfo = mUserManager.createRestrictedProfile(mAddingUserName);
- if (newUserInfo != null && !Utils.assignDefaultPhoto(getActivity(), newUserInfo.id)) {
+ if (newUserInfo != null && !assignDefaultPhoto(getActivity(), newUserInfo.id)) {
return null;
}
return newUserInfo;
@@ -405,7 +414,7 @@
private UserInfo createTrustedUser() {
UserInfo newUserInfo = mUserManager.createUser(mAddingUserName, 0);
- if (newUserInfo != null && !Utils.assignDefaultPhoto(getActivity(), newUserInfo.id)) {
+ if (newUserInfo != null && !assignDefaultPhoto(getActivity(), newUserInfo.id)) {
return null;
}
return newUserInfo;
@@ -914,7 +923,7 @@
for (int userId : values[0]) {
Bitmap bitmap = mUserManager.getUserIcon(userId);
if (bitmap == null) {
- bitmap = Utils.getDefaultUserIconAsBitmap(userId);
+ bitmap = getDefaultUserIconAsBitmap(userId);
}
mUserIcons.append(userId, bitmap);
}
@@ -925,7 +934,7 @@
private Drawable getEncircledDefaultIcon() {
if (mDefaultIconDrawable == null) {
- mDefaultIconDrawable = encircle(Utils.getDefaultUserIconAsBitmap(UserHandle.USER_NULL));
+ mDefaultIconDrawable = encircle(getDefaultUserIconAsBitmap(UserHandle.USER_NULL));
}
return mDefaultIconDrawable;
}
@@ -1025,6 +1034,65 @@
mMePreference.setTitle(label);
}
+ /**
+ * Returns a default user icon (as a {@link Bitmap}) for the given user.
+ *
+ * Note that for guest users, you should pass in {@code UserHandle.USER_NULL}.
+ * @param userId the user id or {@code UserHandle.USER_NULL} for a non-user specific icon
+ */
+ private static Bitmap getDefaultUserIconAsBitmap(int userId) {
+ Bitmap bitmap = null;
+ // Try finding the corresponding bitmap in the dark bitmap cache
+ bitmap = sDarkDefaultUserBitmapCache.get(userId);
+ if (bitmap == null) {
+ bitmap = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(userId, false));
+ // Save it to cache
+ sDarkDefaultUserBitmapCache.put(userId, bitmap);
+ }
+ return bitmap;
+ }
+
+ /**
+ * Assign the default photo to user with {@paramref userId}
+ * @param context used to get the {@link UserManager}
+ * @param userId used to get the icon bitmap
+ * @return true if assign photo successfully, false if failed
+ */
+ @VisibleForTesting
+ static boolean assignDefaultPhoto(Context context, int userId) {
+ if (context == null) {
+ return false;
+ }
+ UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ Bitmap bitmap = getDefaultUserIconAsBitmap(userId);
+ um.setUserIcon(userId, bitmap);
+
+ return true;
+ }
+
+ @WorkerThread
+ static void copyMeProfilePhoto(Context context, UserInfo user) {
+ Uri contactUri = ContactsContract.Profile.CONTENT_URI;
+
+ int userId = user != null ? user.id : UserHandle.myUserId();
+
+ InputStream avatarDataStream = ContactsContract.Contacts.openContactPhotoInputStream(
+ context.getContentResolver(),
+ contactUri, true);
+ // If there's no profile photo, assign a default avatar
+ if (avatarDataStream == null) {
+ assignDefaultPhoto(context, userId);
+ return;
+ }
+
+ UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ Bitmap icon = BitmapFactory.decodeStream(avatarDataStream);
+ um.setUserIcon(userId, icon);
+ try {
+ avatarDataStream.close();
+ } catch (IOException ioe) { }
+ }
+
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
private final Context mContext;
diff --git a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
index ca37b64..77142ed 100644
--- a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
+++ b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
@@ -51,9 +51,9 @@
@VisibleForTesting
void startFallbackSuggestion() {
// fall back to default wallpaper picker
- Utils.startWithFragment(this, WallpaperTypeSettings.class.getName(), null, null, 0,
- R.string.wallpaper_suggestion_title, null,
- MetricsProto.MetricsEvent.DASHBOARD_SUMMARY);
+ Utils.startWithFragment(this, WallpaperTypeSettings.class.getName(),
+ R.string.wallpaper_suggestion_title, MetricsProto.MetricsEvent.DASHBOARD_SUMMARY,
+ Intent.FLAG_ACTIVITY_FORWARD_RESULT);
}
@VisibleForTesting
diff --git a/src/com/android/settings/wallpaper/WallpaperTypeSettings.java b/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
index 1ca8ac7..3c95785 100644
--- a/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
+++ b/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
@@ -16,6 +16,7 @@
package com.android.settings.wallpaper;
+import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -67,7 +68,7 @@
// Add Preference items for each of the matching activities
for (ResolveInfo info : rList) {
Preference pref = new Preference(getPrefContext());
- Intent prefIntent = new Intent(intent);
+ Intent prefIntent = new Intent(intent).addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
prefIntent.setComponent(new ComponentName(
info.activityInfo.packageName, info.activityInfo.name));
pref.setIntent(prefIntent);
@@ -79,6 +80,16 @@
}
}
+ @Override
+ public boolean onPreferenceTreeClick(Preference preference) {
+ if (preference.getIntent() == null) {
+ return super.onPreferenceTreeClick(preference);
+ }
+ startActivity(preference.getIntent());
+ finish();
+ return true;
+ }
+
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
diff --git a/src/com/android/settings/widget/RadioButtonPickerFragment.java b/src/com/android/settings/widget/RadioButtonPickerFragment.java
index c768909..b3e8746 100644
--- a/src/com/android/settings/widget/RadioButtonPickerFragment.java
+++ b/src/com/android/settings/widget/RadioButtonPickerFragment.java
@@ -68,9 +68,6 @@
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
- if (!usePreferenceScreenTitle()) {
- addPreferencesFromResource(R.xml.placeholder_prefs);
- }
updateCandidates();
}
diff --git a/src/com/android/settings/wifi/ConnectedAccessPointPreference.java b/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
new file mode 100644
index 0000000..6b9c788
--- /dev/null
+++ b/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
@@ -0,0 +1,78 @@
+/*
+ * 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 android.content.Context;
+import android.support.annotation.DrawableRes;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settingslib.wifi.AccessPoint;
+import com.android.settingslib.wifi.AccessPointPreference;
+
+/**
+ * An AP preference for the currently connected AP
+ */
+public class ConnectedAccessPointPreference extends AccessPointPreference implements
+ View.OnClickListener {
+
+ private OnGearClickListener mOnGearClickListener;
+
+ public ConnectedAccessPointPreference(AccessPoint accessPoint, Context context,
+ UserBadgeCache cache, @DrawableRes int iconResId, boolean forSavedNetworks) {
+ super(accessPoint, context, cache, iconResId, forSavedNetworks);
+ }
+
+ public void setOnGearClickListener(OnGearClickListener l) {
+ mOnGearClickListener = l;
+ notifyChanged();
+ }
+
+ @Override
+ protected int getSecondTargetResId() {
+ return R.layout.preference_widget_gear;
+ }
+
+ @Override
+ protected boolean shouldHideSecondTarget() {
+ return mOnGearClickListener == null;
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ final View gear = holder.findViewById(R.id.settings_button);
+ if (gear != null) {
+ gear.setOnClickListener(this);
+ }
+ setDividerVisibility(holder, View.VISIBLE);
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.settings_button) {
+ if (mOnGearClickListener != null) {
+ mOnGearClickListener.onGearClick(this);
+ }
+ }
+ }
+
+ public interface OnGearClickListener {
+ void onGearClick(ConnectedAccessPointPreference p);
+ }
+}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 5490889..14db3d3 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -782,7 +782,7 @@
continue;
}
LongPressAccessPointPreference preference =
- createLongPressActionPointPreference(accessPoint);
+ createLongPressAccessPointPreference(accessPoint);
preference.setKey(key);
preference.setOrder(index);
if (mOpenSsid != null && mOpenSsid.equals(accessPoint.getSsidStr())
@@ -817,10 +817,17 @@
}
@NonNull
- private LongPressAccessPointPreference createLongPressActionPointPreference(
+ private LongPressAccessPointPreference createLongPressAccessPointPreference(
AccessPoint accessPoint) {
return new LongPressAccessPointPreference(accessPoint, getPrefContext(), mUserBadgeCache,
- false, R.drawable.ic_wifi_signal_0, this);
+ false /* forSavedNetworks */, R.drawable.ic_wifi_signal_0, this);
+ }
+
+ @NonNull
+ private ConnectedAccessPointPreference createConnectedAccessPointPreference(
+ AccessPoint accessPoint) {
+ return new ConnectedAccessPointPreference(accessPoint, getPrefContext(), mUserBadgeCache,
+ R.drawable.ic_wifi_signal_0, false /* forSavedNetworks */);
}
/**
@@ -859,7 +866,7 @@
// Else same AP is connected, simply refresh the connected access point preference
// (first and only access point in this category).
- ((LongPressAccessPointPreference) mConnectedAccessPointPreferenceCategory.getPreference(0))
+ ((AccessPointPreference) mConnectedAccessPointPreferenceCategory.getPreference(0))
.refresh();
return true;
}
@@ -869,20 +876,19 @@
* {@link #mConnectedAccessPointPreferenceCategory}.
*/
private void addConnectedAccessPointPreference(AccessPoint connectedAp) {
- final LongPressAccessPointPreference pref = getOrCreatePreference(connectedAp);
+ final ConnectedAccessPointPreference pref = createConnectedAccessPointPreference(
+ connectedAp);
// Launch details page on click.
- pref.setOnPreferenceClickListener(preference -> {
- // Save the state of the current access point in the bundle so that we can restore it
- // in the Wifi Network Details Fragment
+ pref.setOnGearClickListener(l -> {
pref.getAccessPoint().saveWifiState(pref.getExtras());
SettingsActivity activity = (SettingsActivity) WifiSettings.this.getActivity();
activity.startPreferencePanel(this,
WifiNetworkDetailsFragment.class.getName(), pref.getExtras(),
R.string.wifi_details_title, null, null, 0);
- return true;
});
+
pref.refresh();
mConnectedAccessPointPreferenceCategory.addPreference(pref);
@@ -893,15 +899,6 @@
}
}
- private LongPressAccessPointPreference getOrCreatePreference(AccessPoint ap) {
- LongPressAccessPointPreference pref = (LongPressAccessPointPreference)
- getCachedPreference(AccessPointPreference.generatePreferenceKey(ap));
- if (pref == null) {
- pref = createLongPressActionPointPreference(ap);
- }
- return pref;
- }
-
/** Removes all preferences and hide the {@link #mConnectedAccessPointPreferenceCategory}. */
private void removeConnectedAccessPointPreference() {
mConnectedAccessPointPreferenceCategory.removeAll();
@@ -1093,7 +1090,7 @@
public void run() {
Object tag = accessPoint.getTag();
if (tag != null) {
- ((LongPressAccessPointPreference) tag).refresh();
+ ((AccessPointPreference) tag).refresh();
}
}
});
@@ -1102,7 +1099,7 @@
@Override
public void onLevelChanged(AccessPoint accessPoint) {
- ((LongPressAccessPointPreference) accessPoint.getTag()).onLevelChanged();
+ ((AccessPointPreference) accessPoint.getTag()).onLevelChanged();
}
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
diff --git a/src/com/android/settings/wrapper/NotificationChannelGroupWrapper.java b/src/com/android/settings/wrapper/NotificationChannelGroupWrapper.java
new file mode 100644
index 0000000..dbfff1a
--- /dev/null
+++ b/src/com/android/settings/wrapper/NotificationChannelGroupWrapper.java
@@ -0,0 +1,64 @@
+/*
+ * 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.wrapper;
+
+import android.app.NotificationChannelGroup;
+
+/**
+ * Wrapper for {@link NotificationChannelGroup} until roboletric supports O MR1.
+ */
+public class NotificationChannelGroupWrapper {
+
+ private final NotificationChannelGroup mGroup;
+
+ public NotificationChannelGroupWrapper(NotificationChannelGroup group) {
+ mGroup = group;
+ }
+
+ /**
+ * Get the real group object so we can call APIs directly on it.
+ */
+ public NotificationChannelGroup getGroup() {
+ return mGroup;
+ }
+
+ public String getDescription() {
+ if (mGroup != null) {
+ return mGroup.getDescription();
+ }
+ return null;
+ }
+
+ public void setDescription(String desc) {
+ if (mGroup != null) {
+ mGroup.setDescription(desc);
+ }
+ }
+
+ public boolean isBlocked() {
+ if (mGroup != null) {
+ return mGroup.isBlocked();
+ }
+ return true;
+ }
+
+ public void setBlocked(boolean blocked) {
+ if (mGroup != null) {
+ mGroup.setBlocked(blocked);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index fda5c8a..6704fc3 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -7,6 +7,10 @@
com.android.settings.development.featureflags.FeatureFlagsDashboard
com.android.settings.development.qstile.DevelopmentTileConfigFragment
com.android.settings.deviceinfo.StorageProfileFragment
+com.android.settings.notification.ChannelNotificationSettings
+com.android.settings.notification.ChannelImportanceSettings
+com.android.settings.notification.ChannelGroupNotificationSettings
+com.android.settings.notification.AppNotificationSettings
com.android.settings.wifi.details.WifiNetworkDetailsFragment
com.android.settings.wifi.p2p.WifiP2pSettings
com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionCamera
@@ -15,4 +19,4 @@
com.android.settings.enterprise.ApplicationListFragment$EnterpriseInstalledPackages
com.android.settings.enterprise.EnterpriseSetDefaultAppsListFragment
com.android.settings.wifi.tether.WifiTetherSettings
-com.android.settings.wifi.SavedAccessPointsWifiSettings
+com.android.settings.wifi.SavedAccessPointsWifiSettings
\ No newline at end of file
diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable
index 4ea5338..8c44112 100644
--- a/tests/robotests/assets/grandfather_not_implementing_indexable
+++ b/tests/robotests/assets/grandfather_not_implementing_indexable
@@ -1,4 +1,3 @@
-com.android.settings.location.LocationMode
com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragment
com.android.settings.deviceinfo.SimStatus
com.android.settings.deviceinfo.PrivateVolumeForget
@@ -19,8 +18,6 @@
com.android.settings.applications.VrListenerSettings
com.android.settings.inputmethod.UserDictionaryList
com.android.settings.datausage.DataSaverSummary
-com.android.settings.notification.ChannelNotificationSettings
-com.android.settings.notification.ChannelGroupNotificationSettings
com.android.settings.datausage.AppDataUsage
com.android.settings.datausage.DataPlanUsageSummary
com.android.settings.accessibility.FontSizePreferenceFragmentForSetupWizard
@@ -55,7 +52,6 @@
com.android.settings.accessibility.ToggleAccessibilityServicePreferenceFragment
com.android.settings.print.PrintServiceSettingsFragment
com.android.settings.wfd.WifiDisplaySettings
-com.android.settings.notification.AppNotificationSettings
com.android.settings.deviceinfo.PrivateVolumeSettings
com.android.settings.users.AppRestrictionsFragment
com.android.settings.deviceinfo.PrivateVolumeUnmount
@@ -82,4 +78,4 @@
com.android.settings.TetherSettings
com.android.settings.ApnEditor
com.android.settings.UserCredentialsSettings
-com.android.settings.TestingSettings
+com.android.settings.TestingSettings
\ No newline at end of file
diff --git a/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider b/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider
index b329072..a71b040 100644
--- a/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider
+++ b/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider
@@ -1 +1 @@
-com.android.settings.fuelgauge.PowerUsageSummary
+com.android.settings.fuelgauge.PowerUsageSummary
\ No newline at end of file
diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml
index 33a1d95..c2909ac 100644
--- a/tests/robotests/res/values-mcc999/config.xml
+++ b/tests/robotests/res/values-mcc999/config.xml
@@ -15,7 +15,6 @@
-->
<resources>
- <bool name="config_show_camera_hal_hdrplus">false</bool>
<bool name="config_enableColorTemperature">false</bool>
<bool name="config_show_camera_laser_sensor">false</bool>
<bool name="config_show_connectivity_monitor">false</bool>
diff --git a/tests/robotests/res/values/config.xml b/tests/robotests/res/values/config.xml
index 0afbe29..9e2d911 100644
--- a/tests/robotests/res/values/config.xml
+++ b/tests/robotests/res/values/config.xml
@@ -19,6 +19,5 @@
<bool name="config_new_device_intro_suggestion_supported">true</bool>
<bool name="config_enableColorTemperature">true</bool>
<bool name="config_show_camera_laser_sensor">true</bool>
- <bool name="config_show_camera_hal_hdrplus">true</bool>
<bool name="config_show_connectivity_monitor">true</bool>
</resources>
\ No newline at end of file
diff --git a/tests/robotests/src/android/util/FeatureFlagUtils.java b/tests/robotests/src/android/util/FeatureFlagUtils.java
index 500884a..189336b 100644
--- a/tests/robotests/src/android/util/FeatureFlagUtils.java
+++ b/tests/robotests/src/android/util/FeatureFlagUtils.java
@@ -16,6 +16,7 @@
package android.util;
+import android.content.Context;
import android.os.SystemProperties;
import android.text.TextUtils;
@@ -35,7 +36,7 @@
* @param feature the flag name
* @return true if the flag is enabled (either by default in system, or override by user)
*/
- public static boolean isEnabled(String feature) {
+ public static boolean isEnabled(Context context, String feature) {
// Tries to get feature flag from system property.
// Step 1: check if feature flag has any override. Flag name: sys.fflag.override.<feature>
String value = SystemProperties.get(FFLAG_OVERRIDE_PREFIX + feature);
@@ -54,7 +55,6 @@
SystemProperties.set(FFLAG_OVERRIDE_PREFIX + feature, enabled ? "true" : "false");
}
-
public static Map<String, String> getAllFeatureFlags() {
final Map<String, String> features = new HashMap<>();
features.put(FFLAG_PREFIX + "abc", "false");
diff --git a/tests/robotests/src/com/android/internal/app/NightDisplayController.java b/tests/robotests/src/com/android/internal/app/ColorDisplayController.java
similarity index 97%
rename from tests/robotests/src/com/android/internal/app/NightDisplayController.java
rename to tests/robotests/src/com/android/internal/app/ColorDisplayController.java
index b20de68..74e7d8a 100644
--- a/tests/robotests/src/com/android/internal/app/NightDisplayController.java
+++ b/tests/robotests/src/com/android/internal/app/ColorDisplayController.java
@@ -19,7 +19,7 @@
* Fake controller to make robolectric test compile. Should be removed when Robolectric supports
* API 25.
*/
-public class NightDisplayController {
+public class ColorDisplayController {
public static final int AUTO_MODE_DISABLED = 0;
public static final int AUTO_MODE_CUSTOM = 1;
diff --git a/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java b/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java
index 09ee15f..8cedaf1 100644
--- a/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java
@@ -46,7 +46,7 @@
@RunWith(SettingsRobolectricTestRunner.class)
@Config(
manifest = TestConfig.MANIFEST_PATH,
- sdk = TestConfig.SDK_VERSION,
+ sdk = TestConfig.SDK_VERSION_O,
shadows = {ShadowUtils.class, ShadowConnectivityManager.class}
)
public class DeviceInfoSettingsTest {
diff --git a/tests/robotests/src/com/android/settings/SettingsActivityTest.java b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
index fac136c..509ecda 100644
--- a/tests/robotests/src/com/android/settings/SettingsActivityTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
@@ -17,7 +17,6 @@
package com.android.settings;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
@@ -29,13 +28,11 @@
import android.app.ActivityManager;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
-import com.android.settings.search.SearchActivity;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
@@ -46,7 +43,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -97,15 +93,4 @@
assertThat((boolean) bundle.get(SettingsActivity.SAVE_KEY_SHOW_HOME_AS_UP)).isTrue();
}
-
- @Test
- public void testOnClick() {
- doReturn("com.android.settings").when(mActivity).getPackageName();
-
- mActivity.onClick(null);
-
- Intent intent = ShadowApplication.getInstance().getNextStartedActivity();
- assertThat(intent.getComponent()).isEqualTo(
- new ComponentName("com.android.settings", SearchActivity.class.getName()));
- }
}
diff --git a/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java
index dc4166d..c84c1c6 100644
--- a/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java
@@ -16,9 +16,9 @@
package com.android.settings;
-
import android.app.Activity;
import android.content.Context;
+import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceManager;
@@ -39,19 +39,19 @@
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 com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class SettingsPreferenceFragmentTest {
private static final int ITEM_COUNT = 5;
@Mock
- private PreferenceManager mPreferenceManager;
- @Mock
private Activity mActivity;
@Mock
private View mListContainer;
@@ -142,6 +142,36 @@
assertThat(mEmptyView.getVisibility()).isEqualTo(View.GONE);
}
+ @Test
+ @Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
+ public void onCreate_hasExtraFragmentKey_shouldExpandPreferences() {
+ doReturn(mContext.getTheme()).when(mActivity).getTheme();
+ doReturn(mContext.getResources()).when(mFragment).getResources();
+ doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
+ final Bundle bundle = new Bundle();
+ bundle.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, "test_key");
+ doReturn(bundle).when(mFragment).getArguments();
+
+ mFragment.onCreate(null /* icicle */);
+
+ verify(mPreferenceScreen).setInitialExpandedChildrenCount(Integer.MAX_VALUE);
+ }
+
+ @Test
+ @Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
+ public void onCreate_noPreferenceScreen_shouldNotCrash() {
+ doReturn(mContext.getTheme()).when(mActivity).getTheme();
+ doReturn(mContext.getResources()).when(mFragment).getResources();
+ doReturn(null).when(mFragment).getPreferenceScreen();
+ final Bundle bundle = new Bundle();
+ bundle.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, "test_key");
+ doReturn(bundle).when(mFragment).getArguments();
+
+ mFragment.onCreate(null /* icicle */);
+
+ // no crash
+ }
+
public static class TestFragment extends SettingsPreferenceFragment {
@Override
@@ -150,5 +180,4 @@
}
}
-
}
diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java
index ca02c1d..f813457 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -47,9 +47,8 @@
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class UtilsTest {
- private static final String TIME_DESCRIPTION = "1 day 20 hours 30 minutes";
private static final String PACKAGE_NAME = "com.android.app";
- private Context mContext;
+
@Mock
private WifiManager wifiManager;
@Mock
@@ -60,6 +59,7 @@
private DevicePolicyManagerWrapper mDevicePolicyManager;
@Mock
private UserManager mUserManager;
+ private Context mContext;
@Before
public void setUp() {
@@ -100,12 +100,6 @@
}
@Test
- public void testAssignDefaultPhoto_ContextNull_ReturnFalseAndNotCrash() {
- // Should not crash here
- assertThat(Utils.assignDefaultPhoto(null, 0)).isFalse();
- }
-
- @Test
public void testFormatElapsedTime_WithSeconds_ShowSeconds() {
final double testMillis = 5 * DateUtils.MINUTE_IN_MILLIS + 30 * DateUtils.SECOND_IN_MILLIS;
final String expectedTime = "5m 30s";
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java
index db1db10..4380e5c 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java
@@ -16,7 +16,10 @@
package com.android.settings.accounts;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
@@ -71,6 +74,9 @@
private AccountHeaderPreferenceController mController;
+ private Lifecycle mLifecycle =
+ new Lifecycle(() -> AccountHeaderPreferenceControllerTest.this.mLifecycle);
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -78,32 +84,32 @@
mHeaderPreference = new LayoutPreference(
RuntimeEnvironment.application, R.layout.settings_entity_header);
doReturn(mContext).when(mActivity).getApplicationContext();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
}
@Test
public void isAvailable_noArgs_shouldReturnNull() {
mController = new AccountHeaderPreferenceController(RuntimeEnvironment.application,
- new Lifecycle(), mActivity, mFragment, null /* args */);
+ mLifecycle, mActivity, mFragment, null /* args */);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void onResume_shouldDisplayAccountInEntityHeader() {
- final Lifecycle lifecycle = new Lifecycle();
final Account account = new Account("name1@abc.com", "com.abc");
Bundle args = new Bundle();
args.putParcelable(AccountDetailDashboardFragment.KEY_ACCOUNT, account);
args.putParcelable(AccountDetailDashboardFragment.KEY_USER_HANDLE, UserHandle.CURRENT);
mController = new AccountHeaderPreferenceController(RuntimeEnvironment.application,
- lifecycle, mActivity, mFragment, args);
+ mLifecycle, mActivity, mFragment, args);
assertThat(mController.isAvailable()).isTrue();
when(mScreen.findPreference(anyString())).thenReturn(mHeaderPreference);
mController.displayPreference(mScreen);
- lifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
final CharSequence label =
((TextView) mHeaderPreference.findViewById(R.id.entity_header_title)).getText();
diff --git a/tests/robotests/src/com/android/settings/accounts/AddUserWhenLockedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AddUserWhenLockedPreferenceControllerTest.java
index d399838..faaf7db 100644
--- a/tests/robotests/src/com/android/settings/accounts/AddUserWhenLockedPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AddUserWhenLockedPreferenceControllerTest.java
@@ -17,7 +17,6 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -27,7 +26,6 @@
import android.content.pm.UserInfo;
import android.os.UserManager;
import android.provider.Settings.Global;
-import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.TestConfig;
@@ -70,13 +68,12 @@
when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
when(mUserInfo.isAdmin()).thenReturn(false);
final RestrictedSwitchPreference preference = mock(RestrictedSwitchPreference.class);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(preference);
when(preference.getKey()).thenReturn(mController.getPreferenceKey());
+ when(mScreen.findPreference(preference.getKey())).thenReturn(preference);
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ verify(preference).setVisible(false);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/accounts/AutoSyncDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AutoSyncDataPreferenceControllerTest.java
index b8ad837..4715f88 100644
--- a/tests/robotests/src/com/android/settings/accounts/AutoSyncDataPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AutoSyncDataPreferenceControllerTest.java
@@ -15,19 +15,23 @@
*/
package com.android.settings.accounts;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.when;
+
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.UserInfo;
import android.os.UserManager;
+import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-import android.support.v14.preference.SwitchPreference;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import java.util.ArrayList;
-import java.util.List;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -36,14 +40,8 @@
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import java.util.ArrayList;
+import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -55,9 +53,8 @@
private UserManager mUserManager;
@Mock(answer = RETURNS_DEEP_STUBS)
private Fragment mFragment;
- @Mock
- private Preference mPreference;
+ private Preference mPreference;
private Context mContext;
private AutoSyncDataPreferenceController mController;
private AutoSyncDataPreferenceController.ConfirmAutoSyncChangeFragment mConfirmSyncFragment;
@@ -71,9 +68,9 @@
mController = new AutoSyncDataPreferenceController(mContext, mFragment);
mConfirmSyncFragment = new AutoSyncDataPreferenceController.ConfirmAutoSyncChangeFragment();
mConfirmSyncFragment.setTargetFragment(mFragment, 0);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(mPreference);
- when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+ mPreference = new Preference(mContext);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
}
@Test
@@ -82,7 +79,7 @@
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
@@ -92,7 +89,7 @@
mController.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isTrue();
}
@Test
@@ -105,7 +102,7 @@
mController.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isTrue();
}
@Test
@@ -119,7 +116,7 @@
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
@@ -135,5 +132,4 @@
mConfirmSyncFragment.onClick(null, DialogInterface.BUTTON_NEGATIVE);
assertThat(preference.isChecked()).isFalse();
}
-
}
diff --git a/tests/robotests/src/com/android/settings/accounts/AutoSyncPersonalDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AutoSyncPersonalDataPreferenceControllerTest.java
index ab462c0..597fbd4 100644
--- a/tests/robotests/src/com/android/settings/accounts/AutoSyncPersonalDataPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AutoSyncPersonalDataPreferenceControllerTest.java
@@ -15,17 +15,21 @@
*/
package com.android.settings.accounts;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.when;
+
import android.app.Fragment;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import java.util.ArrayList;
-import java.util.List;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,12 +38,8 @@
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
-import static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import java.util.ArrayList;
+import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -51,10 +51,9 @@
private UserManager mUserManager;
@Mock(answer = RETURNS_DEEP_STUBS)
private Fragment mFragment;
- @Mock
- private Preference mPreference;
private Context mContext;
+ private Preference mPreference;
private AutoSyncPersonalDataPreferenceController mController;
@Before
@@ -64,9 +63,9 @@
shadowContext.setSystemService(Context.USER_SERVICE, mUserManager);
mContext = shadowContext.getApplicationContext();
mController = new AutoSyncPersonalDataPreferenceController(mContext, mFragment);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(mPreference);
- when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+ mPreference = new Preference(mContext);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
}
@Test
@@ -75,7 +74,7 @@
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
@@ -85,7 +84,7 @@
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
@@ -98,11 +97,11 @@
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
- public void displayPref_prefAvaiable_shouldDisplay() {
+ public void displayPref_prefAvailable_shouldDisplay() {
List<UserInfo> infos = new ArrayList<>();
infos.add(new UserInfo(1, "user 1", 0));
infos.add(new UserInfo(2, "user 2", 0));
@@ -112,7 +111,7 @@
mController.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isTrue();
}
}
diff --git a/tests/robotests/src/com/android/settings/accounts/EmergencyInfoPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/EmergencyInfoPreferenceControllerTest.java
index 0f7de46..29a011e 100644
--- a/tests/robotests/src/com/android/settings/accounts/EmergencyInfoPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/EmergencyInfoPreferenceControllerTest.java
@@ -15,31 +15,6 @@
*/
package com.android.settings.accounts;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.os.UserManager;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import com.android.settings.search.SearchIndexableRaw;
-import com.android.settings.testutils.shadow.ShadowAccountManager;
-import com.android.settings.testutils.shadow.ShadowContentResolver;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowApplication;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.Matchers.any;
@@ -49,8 +24,35 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.search.SearchIndexableRaw;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowAccountManager;
+import com.android.settings.testutils.shadow.ShadowContentResolver;
+
+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.shadows.ShadowApplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class EmergencyInfoPreferenceControllerTest {
@Mock(answer = RETURNS_DEEP_STUBS)
@@ -61,15 +63,19 @@
private UserManager mUserManager;
private EmergencyInfoPreferenceController mController;
+ private Preference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new EmergencyInfoPreferenceController(mContext);
+ mPreference = new Preference(RuntimeEnvironment.application);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
}
@Test
- public void updateRawDataToIndex_prefUnavaiable_shouldNotUpdate() {
+ public void updateRawDataToIndex_prefUnavailable_shouldNotUpdate() {
final List<SearchIndexableRaw> data = new ArrayList<>();
when(mContext.getPackageManager().queryIntentActivities(
any(Intent.class), anyInt()))
@@ -81,7 +87,7 @@
}
@Test
- public void updateRawDataToIndex_prefAvaiable_shouldUpdate() {
+ public void updateRawDataToIndex_prefAvailable_shouldUpdate() {
final List<SearchIndexableRaw> data = new ArrayList<>();
final List<ResolveInfo> infos = new ArrayList<>();
infos.add(new ResolveInfo());
@@ -95,23 +101,18 @@
}
@Test
- public void displayPref_prefUnAvaiable_shouldNotDisplay() {
+ public void displayPref_prefUnAvailable_shouldNotDisplay() {
when(mContext.getPackageManager().queryIntentActivities(
any(Intent.class), anyInt()))
.thenReturn(null);
- final Preference preference = mock(Preference.class);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(preference);
- when(preference.getKey()).thenReturn(mController.getPreferenceKey());
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
- public void displayPref_prefAvaiable_shouldDisplay() {
- final List<SearchIndexableRaw> data = new ArrayList<>();
+ public void displayPref_prefAvailable_shouldDisplay() {
final List<ResolveInfo> infos = new ArrayList<>();
infos.add(new ResolveInfo());
when(mContext.getPackageManager().queryIntentActivities(
diff --git a/tests/robotests/src/com/android/settings/applications/LayoutPreferenceTest.java b/tests/robotests/src/com/android/settings/applications/LayoutPreferenceTest.java
index 583a004..35d1194 100644
--- a/tests/robotests/src/com/android/settings/applications/LayoutPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/applications/LayoutPreferenceTest.java
@@ -24,11 +24,10 @@
import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.support.v7.preference.PreferenceViewHolder;
import android.view.LayoutInflater;
-import android.view.View;
import com.android.settings.R;
-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;
@@ -37,19 +36,17 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class LayoutPreferenceTest {
private Context mContext;
private LayoutPreference mPreference;
- private View mRootView;
private PreferenceViewHolder mHolder;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mPreference = new LayoutPreference(mContext, R.layout.two_action_buttons);
- mRootView = mPreference.mRootView;
mHolder = PreferenceViewHolder.createInstanceForTests(LayoutInflater.from(mContext)
.inflate(R.layout.layout_preference_frame, null, false));
}
diff --git a/tests/robotests/src/com/android/settings/applications/ManageDomainUrlsTest.java b/tests/robotests/src/com/android/settings/applications/ManageDomainUrlsTest.java
new file mode 100644
index 0000000..3e89647
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/ManageDomainUrlsTest.java
@@ -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.applications;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.applications.ApplicationsState;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ManageDomainUrlsTest {
+
+ @Mock
+ private ApplicationsState.AppEntry mAppEntry;
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ }
+
+ @Test
+ public void domainAppPreferenceShouldUseAppPreferenceLayout() {
+ mAppEntry.info = new ApplicationInfo();
+ mAppEntry.info.packageName = "com.android.settings.test";
+ final ManageDomainUrls.DomainAppPreference pref =
+ new ManageDomainUrls.DomainAppPreference(mContext, null, mAppEntry);
+
+ assertThat(pref.getLayoutResource()).isEqualTo(R.layout.preference_app);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/assist/AssistContextPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/assist/AssistContextPreferenceControllerTest.java
index c71bc29..c59ac18 100644
--- a/tests/robotests/src/com/android/settings/applications/assist/AssistContextPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/assist/AssistContextPreferenceControllerTest.java
@@ -16,7 +16,10 @@
package com.android.settings.applications.assist;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
@@ -60,7 +63,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mContext = RuntimeEnvironment.application;
mController = new AssistContextPreferenceController(mContext, mLifecycle);
ReflectionHelpers.setField(mController, "mSettingObserver", mObserver);
@@ -88,7 +91,7 @@
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1);
- mLifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
verify(mObserver).register(any(ContentResolver.class), eq(true));
verify(mPreference).setChecked(true);
}
diff --git a/tests/robotests/src/com/android/settings/applications/assist/AssistFlashScreenPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/assist/AssistFlashScreenPreferenceControllerTest.java
index d68229f..1dec8d0 100644
--- a/tests/robotests/src/com/android/settings/applications/assist/AssistFlashScreenPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/assist/AssistFlashScreenPreferenceControllerTest.java
@@ -16,6 +16,18 @@
package com.android.settings.applications.assist;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+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.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -23,8 +35,8 @@
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.TwoStatePreference;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowSecureSettings;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -38,15 +50,6 @@
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AssistFlashScreenPreferenceControllerTest {
@@ -67,7 +70,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mContext = RuntimeEnvironment.application;
mController = spy(new AssistFlashScreenPreferenceController(mContext, mLifecycle));
mLifecycle.addObserver(mController);
@@ -116,7 +119,7 @@
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ASSIST_DISCLOSURE_ENABLED, 1);
- mLifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
verify(mObserver).register(any(ContentResolver.class), eq(true));
verify(mPreference).setChecked(true);
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java
index ca5c10b..8a8cc29 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java
@@ -17,6 +17,9 @@
package com.android.settings.applications.defaultapps;
import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.anyList;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
@@ -26,6 +29,8 @@
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
import android.os.UserManager;
import android.support.v7.preference.Preference;
@@ -42,6 +47,9 @@
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
+import java.util.Arrays;
+
+
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class DefaultHomePreferenceControllerTest {
@@ -112,4 +120,32 @@
assertThat(DefaultHomePreferenceController.isHomeDefault(pkgName, mPackageManager))
.isFalse();
}
+
+ @Test
+ public void testGetSettingIntent_homeHasNoSetting_shouldNotReturnSettingIntent() {
+ when(mPackageManager.getHomeActivities(anyList())).thenReturn(
+ new ComponentName("test.pkg", "class"));
+ assertThat(mController.getSettingIntent(mController.getDefaultAppInfo())).isNull();
+ }
+
+ @Test
+ public void testGetSettingIntent_homeHasOneSetting_shouldReturnSettingIntent() {
+ when(mPackageManager.getHomeActivities(anyList())).thenReturn(
+ new ComponentName("test.pkg", "class"));
+ when(mPackageManager.queryIntentActivities(any(), eq(0))).thenReturn(
+ Arrays.asList(mock(ResolveInfo.class)));
+
+ Intent intent = mController.getSettingIntent(mController.getDefaultAppInfo());
+ assertThat(intent).isNotNull();
+ assertThat(intent.getPackage()).isEqualTo("test.pkg");
+ }
+
+ @Test
+ public void testGetSettingIntent_homeHasMultipleSettings_shouldNotReturnSettingIntent() {
+ when(mPackageManager.getHomeActivities(anyList())).thenReturn(
+ new ComponentName("test.pkg", "class"));
+ when(mPackageManager.queryIntentActivities(any(), eq(0))).thenReturn(
+ Arrays.asList(mock(ResolveInfo.class), mock(ResolveInfo.class)));
+ assertThat(mController.getSettingIntent(mController.getDefaultAppInfo())).isNull();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
index a0b0146..dfe8e4c 100644
--- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
@@ -22,7 +22,9 @@
.LIST_TYPE_MAIN;
import static com.android.settings.applications.manageapplications.ManageApplications
.LIST_TYPE_NOTIFICATION;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
@@ -52,7 +54,6 @@
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
import com.android.settings.widget.LoadingViewController;
import com.android.settingslib.applications.ApplicationsState;
-import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
@@ -100,7 +101,6 @@
when(mState.getBackgroundLooper()).thenReturn(mBgLooper);
mFragment = new ManageApplications();
- ReflectionHelpers.setField(mFragment, "mLifecycle", new Lifecycle());
}
@Test
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerEventsTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerEventsTest.java
index 240ece1..62e4986 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerEventsTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerEventsTest.java
@@ -36,7 +36,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
shadows=SettingsShadowBluetoothDevice.class)
public class BluetoothDetailsControllerEventsTest extends BluetoothDetailsControllerTestBase {
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
index 3b8db04..33a5ed5 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
@@ -37,7 +37,7 @@
import org.robolectric.RuntimeEnvironment;
public class BluetoothDetailsControllerTestBase {
- protected Context mContext = RuntimeEnvironment.application;
+ protected Context mContext;
protected Lifecycle mLifecycle;
protected DeviceConfig mDeviceConfig;
protected BluetoothDevice mDevice;
@@ -58,6 +58,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
mPreferenceManager = new PreferenceManager(mContext);
mScreen = mPreferenceManager.createPreferenceScreen(mContext);
mDeviceConfig = makeDefaultDeviceConfig();
@@ -66,7 +67,7 @@
when(mFragment.getContext()).thenReturn(mContext);
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
- mLifecycle = spy(new Lifecycle());
+ mLifecycle = spy(new Lifecycle(() -> mLifecycle));
mBluetoothManager = new BluetoothManager(mContext);
mBluetoothAdapter = mBluetoothManager.getAdapter();
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
index 98a3580..2dc411c 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
@@ -45,7 +45,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
shadows={SettingsShadowBluetoothDevice.class, ShadowEntityHeaderController.class,
SettingsShadowResources.class})
public class BluetoothDetailsHeaderControllerTest extends BluetoothDetailsControllerTestBase {
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressControllerTest.java
index 24b28a1..4edcc74 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressControllerTest.java
@@ -17,8 +17,8 @@
import static com.google.common.truth.Truth.assertThat;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowBluetoothDevice;
import com.android.settingslib.widget.FooterPreference;
@@ -27,9 +27,10 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows=SettingsShadowBluetoothDevice.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
+ shadows = SettingsShadowBluetoothDevice.class)
public class BluetoothDetailsMacAddressControllerTest extends BluetoothDetailsControllerTestBase {
+
private BluetoothDetailsMacAddressController mController;
@Override
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java
index 445e4e3..eca5df9 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java
@@ -54,7 +54,7 @@
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
shadows=SettingsShadowBluetoothDevice.class)
public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsControllerTestBase {
private BluetoothDetailsProfilesController mController;
diff --git a/tests/robotests/src/com/android/settings/core/DynamicAvailabilityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/DynamicAvailabilityPreferenceControllerTest.java
deleted file mode 100644
index 9bf73ce..0000000
--- a/tests/robotests/src/com/android/settings/core/DynamicAvailabilityPreferenceControllerTest.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.core;
-
-import android.content.Context;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-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.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-/**
- * Tests for {@link DynamicAvailabilityPreferenceController}.
- */
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public final class DynamicAvailabilityPreferenceControllerTest {
-
- private final String PREFERENCE_KEY = "preference_key";
-
- private @Mock Context mContext;
- private @Mock Preference mPreference;
- private @Mock PreferenceScreen mScreen;
- private @Mock Lifecycle mLifecycle;
- private @Mock PreferenceAvailabilityObserver mObserver;
-
- private boolean mIsAvailable;
- private Preference mUpdatedPreference = null;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- when(mPreference.getKey()).thenReturn(PREFERENCE_KEY);
- when(mScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(mPreference);
- }
-
- @Test
- public void testAvailableToUnavailable() {
- mIsAvailable = true;
-
- final DynamicAvailabilityPreferenceController controller
- = new DynamicAvailabilityPreferenceControllerTestable(mLifecycle);
- verify(mLifecycle).addObserver(controller);
-
- controller.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(mPreference);
- verify(mScreen, never()).addPreference(mPreference);
- assertThat(mUpdatedPreference).isNull();
-
- controller.onResume();
- verify(mScreen, never()).removePreference(mPreference);
- verify(mScreen, never()).addPreference(mPreference);
- assertThat(mUpdatedPreference).isEqualTo(mPreference);
-
- mUpdatedPreference = null;
- mIsAvailable = false;
- controller.onResume();
- verify(mScreen).removePreference(mPreference);
- verify(mScreen, never()).addPreference(mPreference);
- assertThat(mUpdatedPreference).isNull();
- }
-
- @Test
- public void testUnavailableToAvailable() {
- mIsAvailable = false;
-
- final DynamicAvailabilityPreferenceController controller
- = new DynamicAvailabilityPreferenceControllerTestable(mLifecycle);
- verify(mLifecycle).addObserver(controller);
-
- controller.displayPreference(mScreen);
- verify(mScreen).removePreference(mPreference);
- verify(mScreen, never()).addPreference(mPreference);
- assertThat(mUpdatedPreference).isNull();
-
- reset(mScreen);
- controller.onResume();
- verify(mScreen, never()).removePreference(mPreference);
- verify(mScreen, never()).addPreference(mPreference);
- assertThat(mUpdatedPreference).isNull();
-
- mIsAvailable = true;
- controller.onResume();
- verify(mScreen, never()).removePreference(mPreference);
- verify(mScreen).addPreference(mPreference);
- assertThat(mUpdatedPreference).isEqualTo(mPreference);
- }
-
- @Test
- public void testNotifyOnAvailabilityUpdate() {
- final DynamicAvailabilityPreferenceController controller
- = new DynamicAvailabilityPreferenceControllerTestable(mLifecycle);
- controller.setAvailabilityObserver(mObserver);
- assertThat(controller.getAvailabilityObserver()).isEqualTo(mObserver);
-
- mIsAvailable = false;
- controller.isAvailable();
- verify(mObserver).onPreferenceAvailabilityUpdated(PREFERENCE_KEY, false);
-
- mIsAvailable = true;
- controller.isAvailable();
- verify(mObserver).onPreferenceAvailabilityUpdated(PREFERENCE_KEY, true);
- }
-
- private class DynamicAvailabilityPreferenceControllerTestable
- extends DynamicAvailabilityPreferenceController {
- public DynamicAvailabilityPreferenceControllerTestable(Lifecycle lifecycle) {
- super(DynamicAvailabilityPreferenceControllerTest.this.mContext, lifecycle);
- }
-
- @Override
- public boolean isAvailable() {
- notifyOnAvailabilityUpdate(mIsAvailable);
- return mIsAvailable;
- }
-
- @Override
- public void updateState(Preference preference) {
- mUpdatedPreference = preference;
- }
-
- @Override
- public String getPreferenceKey() {
- return PREFERENCE_KEY;
- }
- }
-}
diff --git a/tests/robotests/src/com/android/settings/core/InstrumentedPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/core/InstrumentedPreferenceFragmentTest.java
index 30d60cc..8814ecb 100644
--- a/tests/robotests/src/com/android/settings/core/InstrumentedPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/core/InstrumentedPreferenceFragmentTest.java
@@ -27,13 +27,12 @@
import android.os.Bundle;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceScreen;
-import android.util.FeatureFlagUtils;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
+import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
-import com.android.settings.TestConfig;
import org.junit.After;
import org.junit.Before;
@@ -45,7 +44,7 @@
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows = {
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O, shadows = {
SettingsShadowSystemProperties.class
})
public class InstrumentedPreferenceFragmentTest {
@@ -75,10 +74,6 @@
@Test
public void onCreatePreferences_noPreferenceScreenResId_shouldNotAddPreference() {
- SettingsShadowSystemProperties.set(
- FeatureFlagUtils.FFLAG_PREFIX + mFragment.FEATURE_FLAG_USE_PREFERENCE_SCREEN_TITLE,
- "true");
-
mFragment.onCreatePreferences(Bundle.EMPTY, null /* rootKey */);
verify(mFragment, never()).addPreferencesFromResource(anyInt());
@@ -86,9 +81,6 @@
@Test
public void onCreatePreferences_gotPreferenceScreenResId_shouldAddPreferences() {
- SettingsShadowSystemProperties.set(
- FeatureFlagUtils.FFLAG_PREFIX + mFragment.FEATURE_FLAG_USE_PREFERENCE_SCREEN_TITLE,
- "true");
mFragment.setPreferenceScreenResId(R.xml.screen_pinning_settings);
when(mFragment.getActivity()).thenReturn(mActivity);
@@ -100,9 +92,6 @@
@Test
public void onCreatePreferences_gotPrefScreenResIdAndTitle_shouldAddPreferencesAndSetTitle() {
- SettingsShadowSystemProperties.set(
- FeatureFlagUtils.FFLAG_PREFIX + mFragment.FEATURE_FLAG_USE_PREFERENCE_SCREEN_TITLE,
- "true");
mFragment.setPreferenceScreenResId(R.xml.screen_pinning_settings);
when(mFragment.getActivity()).thenReturn(mActivity);
final CharSequence title = "Test Title";
@@ -114,14 +103,11 @@
verify(mActivity).setTitle(title);
}
- private static class InstrumentedPreferenceFragmentTestable
+ public static class InstrumentedPreferenceFragmentTestable
extends InstrumentedPreferenceFragment {
private int mScreenId = -1;
- public InstrumentedPreferenceFragmentTestable() {
- }
-
@Override
public int getMetricsCategory() {
return MetricsEvent.VIEW_UNKNOWN;
diff --git a/tests/robotests/src/com/android/settings/core/codeinspection/CodeInspectionTest.java b/tests/robotests/src/com/android/settings/core/codeinspection/CodeInspectionTest.java
index 126a346..16b1f61 100644
--- a/tests/robotests/src/com/android/settings/core/codeinspection/CodeInspectionTest.java
+++ b/tests/robotests/src/com/android/settings/core/codeinspection/CodeInspectionTest.java
@@ -35,7 +35,7 @@
* for conformance.
*/
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
assetDir = "/tests/robotests/assets")
public class CodeInspectionTest {
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
index a927306..88c184c 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
@@ -15,18 +15,20 @@
*/
package com.android.settings.core.instrumentation;
+import static com.google.common.truth.Truth.assertThat;
+
import android.os.Bundle;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
-import static com.google.common.truth.Truth.assertThat;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class InstrumentedDialogFragmentTest {
public static class TestDialogFragment extends InstrumentedDialogFragment {
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
index ff91c40..a7c95b6 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
@@ -15,15 +15,22 @@
*/
package com.android.settings.core.instrumentation;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.Pair;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
@@ -39,15 +46,8 @@
import java.util.ArrayList;
import java.util.List;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class MetricsFeatureProviderTest {
private static int CATEGORY = 10;
private static boolean SUBTYPE_BOOLEAN = true;
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java
index bb41cf0..3ad70ab 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java
@@ -15,13 +15,24 @@
*/
package com.android.settings.core.instrumentation;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Pair;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.google.common.truth.Platform;
@@ -34,23 +45,8 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent
- .ACTION_SETTINGS_PREFERENCE_CHANGE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent
- .FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent
- .FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent
- .FIELD_SETTINGS_PREFERENCE_CHANGE_NAME;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class SharedPreferenceLoggerTest {
private static final String TEST_TAG = "tag";
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java
index 1a47a66..b12d9d6 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java
@@ -44,7 +44,7 @@
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class VisibilityLoggerMixinTest {
@Mock
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
index 696ea4b..c48978c 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
@@ -16,7 +16,11 @@
package com.android.settings.dashboard.suggestions;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -56,7 +60,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
when(mContext.getApplicationContext()).thenReturn(mContext);
}
@@ -69,10 +73,10 @@
public void goThroughLifecycle_onStartStop_shouldStartStopController() {
mMixin = new SuggestionControllerMixin(mContext, mHost, mLifecycle);
- mLifecycle.onStart();
+ mLifecycle.handleLifecycleEvent(ON_START);
assertThat(ShadowSuggestionController.sStartCalled).isTrue();
- mLifecycle.onStop();
+ mLifecycle.handleLifecycleEvent(ON_STOP);
assertThat(ShadowSuggestionController.sStopCalled).isTrue();
}
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
index 8feef92..b74453c 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
@@ -42,6 +42,7 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.Settings.NightDisplaySuggestionActivity;
import com.android.settings.TestConfig;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
@@ -67,7 +68,7 @@
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows = {
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O, shadows = {
ShadowSecureSettings.class,
SettingsShadowResources.class,
SettingsShadowSystemProperties.class
@@ -136,7 +137,7 @@
public void isSuggestionV2Enabled_isNotLowMemoryDevice_sysPropOn_shouldReturnTrue() {
when(mActivityManager.isLowRamDevice()).thenReturn(false);
SettingsShadowSystemProperties.set(
- FeatureFlagUtils.FFLAG_PREFIX + mProvider.FEATURE_FLAG_SUGGESTIONS_V2, "true");
+ FeatureFlagUtils.FFLAG_PREFIX + FeatureFlags.SUGGESTIONS_V2, "true");
assertThat(mProvider.isSuggestionV2Enabled(mContext)).isTrue();
}
diff --git a/tests/robotests/src/com/android/settings/datetime/ZonePickerComparatorTest.java b/tests/robotests/src/com/android/settings/datetime/ZonePickerComparatorTest.java
new file mode 100644
index 0000000..4c1794c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/datetime/ZonePickerComparatorTest.java
@@ -0,0 +1,123 @@
+package com.android.settings.datetime;
+
+import com.android.settings.datetime.ZonePicker;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settingslib.datetime.ZoneGetter;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ZonePickerComparatorTest {
+
+ // Strings in Chinese are sorted by alphabet order of their Pinyin.
+ // "伦敦" -> "lundun"; "纽约" -> "niuyue"; "悉尼" -> "xini"
+ // "开罗" -> "kailuo"; "雅典" -> "yadian"; "上海" -> "shanghai"
+ private static final String[] TEST_CHINESE_NAME =
+ new String[]{"伦敦", "纽约", "悉尼", "开罗", "雅典", "上海"};
+ private static final String[] ORDERED_CHINESE_NAME =
+ new String[]{"开罗", "伦敦", "纽约", "上海", "悉尼", "雅典"};
+
+ private static final String[] TEST_ENGLISH_NAME =
+ new String[]{"London", "New York", "Sydney", "Cairo", "Athens", "Shanghai"};
+ private static final String[] ORDERED_ENGLISH_NAME =
+ new String[]{"Athens", "Cairo", "London", "New York", "Shanghai", "Sydney"};
+
+ private static final Locale INIT_LOCALE = Locale.getDefault();
+
+ private Map<String, List> mTestDataMap;
+ private List<Map<String, Object>> mTestList;
+
+ @Before
+ public void setUp() {
+ mTestDataMap = new HashMap<>();
+ mTestDataMap.put("zh_CN", Arrays.asList(TEST_CHINESE_NAME));
+ mTestDataMap.put("en_US", Arrays.asList(TEST_ENGLISH_NAME));
+ }
+
+ @After
+ public void tearDown() {
+ Locale.setDefault(INIT_LOCALE);
+ }
+
+ @Test
+ public void testComparator_sortChineseString() {
+ String sortKey = ZoneGetter.KEY_DISPLAY_LABEL;
+ mTestList = getMockZonesList("zh_CN");
+ Locale.setDefault(new Locale("zh"));
+ final ZonePicker.MyComparator comparator = new ZonePicker.MyComparator(sortKey);
+ assertThat(comparator).isNotNull();
+ Collections.sort(mTestList, comparator);
+ for (int i = 0; i < mTestList.size(); i++) {
+ assertThat(mTestList.get(i).get(sortKey).toString())
+ .isEqualTo(ORDERED_CHINESE_NAME[i]);
+ }
+ }
+
+ @Test
+ public void testComparator_sortEnglishString() {
+ String sortKey = ZoneGetter.KEY_DISPLAY_LABEL;
+ mTestList = getMockZonesList("en_US");
+ Locale.setDefault(new Locale("en"));
+ final ZonePicker.MyComparator comparator = new ZonePicker.MyComparator(sortKey);
+ assertThat(comparator).isNotNull();
+ Collections.sort(mTestList, comparator);
+ for (int i = 0; i < mTestList.size(); i++) {
+ assertThat(mTestList.get(i).get(sortKey).toString())
+ .isEqualTo(ORDERED_ENGLISH_NAME[i]);
+ }
+ }
+
+ @Test
+ public void testComparator_sortInteger() {
+ String sortKey = ZoneGetter.KEY_OFFSET;
+ // TestList of any locale can be selected to test integer sorting.
+ mTestList = getMockZonesList("en_US");
+ final ZonePicker.MyComparator comparator = new ZonePicker.MyComparator(sortKey);
+ assertThat(comparator).isNotNull();
+ Collections.sort(mTestList, comparator);
+ for (int i = 0; i < mTestList.size(); i++) {
+ assertThat(mTestList.get(i).get(sortKey)).isEqualTo(i);
+ }
+ }
+
+ private List<Map<String, Object>> getMockZonesList(String locale) {
+ List<Map<String, Object>> zones = new ArrayList<>();
+ List<String> testData = mTestDataMap.get(locale);
+ TimeZone tz = TimeZone.getDefault();
+ int testSize = testData.size();
+ for (int i = 0; i < testSize; i++) {
+ zones.add(createMockDisplayEntry(tz, "GMT+08:00",
+ testData.get(i), testSize - i - 1));
+ }
+ return zones;
+ }
+
+ private Map<String, Object> createMockDisplayEntry(
+ TimeZone tz, CharSequence gmtOffsetText, CharSequence displayName, int offsetMillis) {
+ Map<String, Object> map = new HashMap<>();
+ map.put(ZoneGetter.KEY_ID, tz.getID());
+ map.put(ZoneGetter.KEY_DISPLAYNAME, displayName.toString());
+ map.put(ZoneGetter.KEY_DISPLAY_LABEL, displayName);
+ map.put(ZoneGetter.KEY_GMT, gmtOffsetText.toString());
+ map.put(ZoneGetter.KEY_OFFSET_LABEL, gmtOffsetText);
+ map.put(ZoneGetter.KEY_OFFSET, offsetMillis);
+ return map;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java
index dd29627..582400d 100644
--- a/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java
@@ -19,11 +19,7 @@
import static com.android.settings.development.AbstractBluetoothA2dpPreferenceController
.STREAMING_LABEL_ID;
-import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
@@ -72,7 +68,7 @@
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController = spy(new AbstractBluetoothA2dpPreferenceControllerImpl(mContext, mLifecycle,
mBluetoothA2dpConfigStore));
doReturn(mBluetoothCodecConfig).when(mController).getCodecConfig();
diff --git a/tests/robotests/src/com/android/settings/development/BluetoothAudioBitsPerSamplePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothAudioBitsPerSamplePreferenceControllerTest.java
index 2438b21..fe0a41a 100644
--- a/tests/robotests/src/com/android/settings/development/BluetoothAudioBitsPerSamplePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BluetoothAudioBitsPerSamplePreferenceControllerTest.java
@@ -61,13 +61,15 @@
private String[] mListValues;
private Context mContext;
private BluetoothAudioBitsPerSamplePreferenceController mController;
+ private Lifecycle mLifecycle;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController = spy(new BluetoothAudioBitsPerSamplePreferenceController(mContext,
- new Lifecycle(), mBluetoothA2dpConfigStore));
+ mLifecycle, mBluetoothA2dpConfigStore));
mListValues = mController.getListValues();
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
diff --git a/tests/robotests/src/com/android/settings/development/BluetoothAudioChannelModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothAudioChannelModePreferenceControllerTest.java
index efcd240..c4dcc19 100644
--- a/tests/robotests/src/com/android/settings/development/BluetoothAudioChannelModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BluetoothAudioChannelModePreferenceControllerTest.java
@@ -60,13 +60,15 @@
private String[] mListValues;
private Context mContext;
private BluetoothAudioChannelModePreferenceController mController;
+ private Lifecycle mLifecycle;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController = spy(new BluetoothAudioChannelModePreferenceController(mContext,
- new Lifecycle(), mBluetoothA2dpConfigStore));
+ mLifecycle, mBluetoothA2dpConfigStore));
mListValues = mController.getListValues();
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
diff --git a/tests/robotests/src/com/android/settings/development/BluetoothAudioCodecPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothAudioCodecPreferenceControllerTest.java
index 560a9c3..29d8047 100644
--- a/tests/robotests/src/com/android/settings/development/BluetoothAudioCodecPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BluetoothAudioCodecPreferenceControllerTest.java
@@ -65,12 +65,14 @@
private String[] mListValues;
private Context mContext;
private BluetoothAudioCodecPreferenceController mController;
+ private Lifecycle mLifecycle;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mController = spy(new BluetoothAudioCodecPreferenceController(mContext, new Lifecycle(),
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ mController = spy(new BluetoothAudioCodecPreferenceController(mContext, mLifecycle,
mBluetoothA2dpConfigStore));
mListValues = mController.getListValues();
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
diff --git a/tests/robotests/src/com/android/settings/development/BluetoothAudioQualityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothAudioQualityPreferenceControllerTest.java
index e00ac00..e76f1d0 100644
--- a/tests/robotests/src/com/android/settings/development/BluetoothAudioQualityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BluetoothAudioQualityPreferenceControllerTest.java
@@ -60,13 +60,15 @@
private String[] mListValues;
private Context mContext;
private BluetoothAudioQualityPreferenceController mController;
+ private Lifecycle mLifecycle;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController = spy(new BluetoothAudioQualityPreferenceController(mContext,
- new Lifecycle(), mBluetoothA2dpConfigStore));
+ mLifecycle, mBluetoothA2dpConfigStore));
mListValues = mController.getListValues();
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
diff --git a/tests/robotests/src/com/android/settings/development/BluetoothAudioSampleRatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothAudioSampleRatePreferenceControllerTest.java
index f683d21..4c113b1 100644
--- a/tests/robotests/src/com/android/settings/development/BluetoothAudioSampleRatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BluetoothAudioSampleRatePreferenceControllerTest.java
@@ -68,7 +68,7 @@
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController = spy(new BluetoothAudioSampleRatePreferenceController(mContext, mLifecycle,
mBluetoothA2dpConfigStore));
mListValues = mController.getListValues();
diff --git a/tests/robotests/src/com/android/settings/development/BugReportInPowerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BugReportInPowerPreferenceControllerTest.java
index c61dfc6..2d75b8a 100644
--- a/tests/robotests/src/com/android/settings/development/BugReportInPowerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BugReportInPowerPreferenceControllerTest.java
@@ -16,17 +16,25 @@
package com.android.settings.development;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.provider.Settings;
import android.os.UserManager;
+import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-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;
@@ -36,23 +44,12 @@
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* deprecated in favor of {@link BugReportInPowerPreferenceControllerV2}
*/
@Deprecated
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class BugReportInPowerPreferenceControllerTest {
@Mock(answer = RETURNS_DEEP_STUBS)
@@ -82,12 +79,10 @@
@Test
public void displayPreference_hasDebugRestriction_shouldRemovePreference() {
when(mUserManager.hasUserRestriction(anyString())).thenReturn(true);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(mPreference);
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
@@ -96,7 +91,7 @@
mController.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isTrue();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/development/BugReportPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BugReportPreferenceControllerTest.java
index d705610..dffa461 100644
--- a/tests/robotests/src/com/android/settings/development/BugReportPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BugReportPreferenceControllerTest.java
@@ -16,66 +16,62 @@
package com.android.settings.development;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-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;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* deprecated in favor of {@link BugReportPreferenceControllerV2}
*/
@Deprecated
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class BugReportPreferenceControllerTest {
@Mock
private Context mContext;
- @Mock
- private Preference mPreference;
@Mock(answer = RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
@Mock
private UserManager mUserManager;
private BugReportPreferenceController mController;
+ private Preference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
- when(mScreen.findPreference(anyString())).thenReturn(mPreference);
mController = new BugReportPreferenceController(mContext);
+ mPreference = new Preference(RuntimeEnvironment.application);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
}
@Test
public void displayPreference_hasDebugRestriction_shouldRemovePreference() {
when(mUserManager.hasUserRestriction(anyString())).thenReturn(true);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(mPreference);
- when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
@@ -84,7 +80,7 @@
mController.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isTrue();
}
@Test
@@ -92,9 +88,10 @@
when(mUserManager.hasUserRestriction(anyString())).thenReturn(true);
mController.displayPreference(mScreen);
+ mPreference.setEnabled(false);
mController.enablePreference(true);
- verify(mPreference, never()).setEnabled(anyBoolean());
+ assertThat(mPreference.isEnabled()).isFalse();
}
@Test
@@ -102,9 +99,10 @@
when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
mController.displayPreference(mScreen);
+ mPreference.setEnabled(false);
mController.enablePreference(true);
- verify(mPreference).setEnabled(anyBoolean());
+ assertThat(mPreference.isEnabled()).isTrue();
}
}
diff --git a/tests/robotests/src/com/android/settings/development/CameraHalHdrplusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/CameraHalHdrplusPreferenceControllerTest.java
deleted file mode 100644
index 48833e4..0000000
--- a/tests/robotests/src/com/android/settings/development/CameraHalHdrplusPreferenceControllerTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.Context;
-import android.os.SystemProperties;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
-
-import org.junit.After;
-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.annotation.Config;
-import org.robolectric.RuntimeEnvironment;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-/**
- * deprecated in favor of {@link CameraHalHdrPlusPreferenceControllerV2}
- */
-@Deprecated
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = {SettingsShadowSystemProperties.class})
-public class CameraHalHdrplusPreferenceControllerTest {
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
- @Mock
- private PreferenceScreen mScreen;
- @Mock
- private SwitchPreference mPreference;
-
- static final String USERDEBUG_BUILD = "userdebug";
-
- private CameraHalHdrplusPreferenceController mController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mController = new CameraHalHdrplusPreferenceController(mContext);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
- when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
- }
-
- @After
- public void tearDown() {
- SettingsShadowSystemProperties.clear();
- }
-
- @Test
- public void isAvailable_withConfigNoShow_shouldReturnFalse() {
- when(mContext.getResources().getBoolean(R.bool.config_show_camera_hal_hdrplus))
- .thenReturn(false);
- assertThat(mController.isAvailable()).isFalse();
- }
-
- @Test
- public void displayPreference_cameraHalHdrplusEnabled_shouldCheckedPreference() {
- when(mContext.getResources().getBoolean(R.bool.config_show_camera_hal_hdrplus))
- .thenReturn(true);
-
- SettingsShadowSystemProperties.set(
- CameraHalHdrplusPreferenceController.PROPERTY_CAMERA_HAL_HDRPLUS,
- CameraHalHdrplusPreferenceController.ENABLED);
- SettingsShadowSystemProperties.set(
- CameraHalHdrplusPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
-
- mController.displayPreference(mScreen);
-
- verify(mPreference).setChecked(true);
- }
-
- @Test
- public void displayPreference_cameraHalHdrplusEnabled_shouldUncheckedPreference() {
- when(mContext.getResources().getBoolean(R.bool.config_show_camera_hal_hdrplus))
- .thenReturn(true);
-
- SettingsShadowSystemProperties.set(
- CameraHalHdrplusPreferenceController.PROPERTY_CAMERA_HAL_HDRPLUS,
- CameraHalHdrplusPreferenceController.DISABLED);
- SettingsShadowSystemProperties.set(
- CameraHalHdrplusPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
-
- mController.displayPreference(mScreen);
-
- verify(mPreference).setChecked(false);
- }
-
- @Test
- public void handlePreferenceTreeClick_preferenceChecked_shouldEnableCameraHalHdrplus() {
- when(mContext.getResources().getBoolean(R.bool.config_show_camera_hal_hdrplus))
- .thenReturn(true);
-
- when(mPreference.isChecked()).thenReturn(true);
-
- when(mContext.getResources().getString(R.string.camera_hal_hdrplus_toast)).thenReturn(
- RuntimeEnvironment.application.getString(R.string.camera_hal_hdrplus_toast));
-
- mController.handlePreferenceTreeClick(mPreference);
-
- assertThat(CameraHalHdrplusPreferenceController.ENABLED.equals(
- SystemProperties.get(
- CameraHalHdrplusPreferenceController.PROPERTY_CAMERA_HAL_HDRPLUS,
- CameraHalHdrplusPreferenceController.DISABLED))).isTrue();
- }
-
- @Test
- public void handlePreferenceTreeClick_preferenceUnchecked_shouldDisableCameraHalHdrplus() {
- when(mContext.getResources().getBoolean(R.bool.config_show_camera_hal_hdrplus))
- .thenReturn(true);
-
- when(mPreference.isChecked()).thenReturn(false);
-
- when(mContext.getResources().getString(R.string.camera_hal_hdrplus_toast)).thenReturn(
- RuntimeEnvironment.application.getString(R.string.camera_hal_hdrplus_toast));
-
- mController.handlePreferenceTreeClick(mPreference);
-
- assertThat(CameraHalHdrplusPreferenceController.DISABLED.equals(
- SystemProperties.get(
- CameraHalHdrplusPreferenceController.PROPERTY_CAMERA_HAL_HDRPLUS,
- CameraHalHdrplusPreferenceController.DISABLED))).isTrue();
- }
-}
diff --git a/tests/robotests/src/com/android/settings/development/CameraHalHdrplusPreferenceControllerV2Test.java b/tests/robotests/src/com/android/settings/development/CameraHalHdrplusPreferenceControllerV2Test.java
deleted file mode 100644
index e0e137c..0000000
--- a/tests/robotests/src/com/android/settings/development/CameraHalHdrplusPreferenceControllerV2Test.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.os.SystemProperties;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = {SettingsShadowSystemProperties.class})
-public class CameraHalHdrplusPreferenceControllerV2Test {
-
- @Mock
- private PreferenceScreen mScreen;
- @Mock
- private SwitchPreference mPreference;
-
- private Context mContext;
- private CameraHalHdrplusPreferenceControllerV2 mController;
-
- static final String USERDEBUG_BUILD = "userdebug";
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mController = new CameraHalHdrplusPreferenceControllerV2(mContext);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
- when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
- mController.displayPreference(mScreen);
- }
-
- @After
- public void tearDown() {
- SettingsShadowSystemProperties.clear();
- }
-
- @Test
- @Config(qualifiers = "mcc999")
- public void isAvailable_withConfigNoShowAndUserDebugBuild_shouldReturnFalse() {
- SettingsShadowSystemProperties.set(
- CameraHalHdrplusPreferenceControllerV2.BUILD_TYPE, USERDEBUG_BUILD);
-
- assertThat(mController.isAvailable()).isFalse();
- }
-
- @Test
- public void updateState_cameraHalHdrplusEnabled_shouldCheckedPreference() {
- SettingsShadowSystemProperties.set(
- CameraHalHdrplusPreferenceControllerV2.PROPERTY_CAMERA_HAL_HDRPLUS,
- CameraHalHdrplusPreferenceControllerV2.ENABLED);
- SettingsShadowSystemProperties.set(
- CameraHalHdrplusPreferenceControllerV2.BUILD_TYPE, USERDEBUG_BUILD);
-
- mController.updateState(mPreference);
-
- verify(mPreference).setChecked(true);
- }
-
- @Test
- public void updateState_cameraHalHdrplusEnabled_shouldUncheckedPreference() {
- SettingsShadowSystemProperties.set(
- CameraHalHdrplusPreferenceControllerV2.PROPERTY_CAMERA_HAL_HDRPLUS,
- CameraHalHdrplusPreferenceControllerV2.DISABLED);
- SettingsShadowSystemProperties.set(
- CameraHalHdrplusPreferenceControllerV2.BUILD_TYPE, USERDEBUG_BUILD);
-
- mController.updateState(mPreference);
-
- verify(mPreference).setChecked(false);
- }
-
- @Test
- public void onPreferenceChange_preferenceChecked_shouldEnableCameraHalHdrplus() {
- mController.onPreferenceChange(mPreference, true /* new value */);
-
- assertThat(CameraHalHdrplusPreferenceControllerV2.ENABLED).isEqualTo(
- SystemProperties.get(
- CameraHalHdrplusPreferenceControllerV2.PROPERTY_CAMERA_HAL_HDRPLUS,
- CameraHalHdrplusPreferenceControllerV2.DISABLED));
- }
-
- @Test
- public void handlePreferenceTreeClick_preferenceUnchecked_shouldDisableCameraHalHdrplus() {
- mController.onPreferenceChange(mPreference, false /* new value */);
-
- assertThat(CameraHalHdrplusPreferenceControllerV2.DISABLED).isEqualTo(
- SystemProperties.get(
- CameraHalHdrplusPreferenceControllerV2.PROPERTY_CAMERA_HAL_HDRPLUS,
- CameraHalHdrplusPreferenceControllerV2.DISABLED));
- }
-
- @Test
- public void onDeveloperOptionsSwitchEnabled_shouldEnablePreference() {
- mController.onDeveloperOptionsSwitchEnabled();
-
- verify(mPreference).setEnabled(true);
- }
-
- @Test
- public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
- mController.onDeveloperOptionsSwitchDisabled();
-
- verify(mPreference).setEnabled(false);
- verify(mPreference).setChecked(false);
- assertThat(CameraHalHdrplusPreferenceControllerV2.DISABLED).isEqualTo(
- SystemProperties.get(
- CameraHalHdrplusPreferenceControllerV2.PROPERTY_CAMERA_HAL_HDRPLUS,
- CameraHalHdrplusPreferenceControllerV2.DISABLED));
- }
-}
diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
index ac09418..5449353 100644
--- a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
@@ -93,7 +93,7 @@
.getXmlResourcesToIndex(RuntimeEnvironment.application, true);
assertThat(index.size()).isEqualTo(1);
- assertThat(index.get(0).xmlResId).isEqualTo(R.xml.development_prefs);
+ assertThat(index.get(0).xmlResId).isEqualTo(R.xml.development_settings);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsTest.java
index b1943a5..87dc5d0 100644
--- a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsTest.java
@@ -108,7 +108,7 @@
RuntimeEnvironment.application, true);
assertThat(index.size()).isEqualTo(1);
- assertThat(index.get(0).xmlResId).isEqualTo(R.xml.development_prefs);
+ assertThat(index.get(0).xmlResId).isEqualTo(R.xml.development_settings);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java
index 6f79faf..aced766 100644
--- a/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java
@@ -16,7 +16,11 @@
package com.android.settings.development;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.when;
import com.android.settings.TestConfig;
@@ -55,7 +59,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mSwitchBar = new SwitchBar(RuntimeEnvironment.application);
}
@@ -72,10 +76,10 @@
final ArrayList<SwitchBar.OnSwitchChangeListener> listeners =
ReflectionHelpers.getField(mSwitchBar, "mSwitchChangeListeners");
- mLifecycle.onStart();
+ mLifecycle.handleLifecycleEvent(ON_START);
assertThat(listeners).doesNotContain(mSettings);
- mLifecycle.onStop();
+ mLifecycle.handleLifecycleEvent(ON_STOP);
assertThat(listeners).doesNotContain(mSettings);
}
@@ -87,10 +91,10 @@
final ArrayList<SwitchBar.OnSwitchChangeListener> listeners =
ReflectionHelpers.getField(mSwitchBar, "mSwitchChangeListeners");
- mLifecycle.onStart();
+ mLifecycle.handleLifecycleEvent(ON_START);
assertThat(listeners).doesNotContain(mNewSettings);
- mLifecycle.onStop();
+ mLifecycle.handleLifecycleEvent(ON_STOP);
assertThat(listeners).doesNotContain(mNewSettings);
}
@@ -102,10 +106,10 @@
final ArrayList<SwitchBar.OnSwitchChangeListener> listeners =
ReflectionHelpers.getField(mSwitchBar, "mSwitchChangeListeners");
- mLifecycle.onStart();
+ mLifecycle.handleLifecycleEvent(ON_START);
assertThat(listeners).contains(mSettings);
- mLifecycle.onStop();
+ mLifecycle.handleLifecycleEvent(ON_STOP);
assertThat(listeners).doesNotContain(mSettings);
}
@@ -118,10 +122,10 @@
final ArrayList<SwitchBar.OnSwitchChangeListener> listeners =
ReflectionHelpers.getField(mSwitchBar, "mSwitchChangeListeners");
- mLifecycle.onStart();
+ mLifecycle.handleLifecycleEvent(ON_START);
assertThat(listeners).contains(mNewSettings);
- mLifecycle.onStop();
+ mLifecycle.handleLifecycleEvent(ON_STOP);
assertThat(listeners).doesNotContain(mNewSettings);
}
diff --git a/tests/robotests/src/com/android/settings/development/LogPersistPreferenceControllerV2Test.java b/tests/robotests/src/com/android/settings/development/LogPersistPreferenceControllerV2Test.java
index 3a7604a..ddc0da5 100644
--- a/tests/robotests/src/com/android/settings/development/LogPersistPreferenceControllerV2Test.java
+++ b/tests/robotests/src/com/android/settings/development/LogPersistPreferenceControllerV2Test.java
@@ -21,14 +21,12 @@
import android.content.Context;
import android.os.SystemProperties;
-import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
-import com.android.settingslib.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.After;
@@ -39,7 +37,6 @@
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,
@@ -56,12 +53,14 @@
private Context mContext;
private LogPersistPreferenceControllerV2 mController;
+ private Lifecycle mLifecycle;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mController = new LogPersistPreferenceControllerV2(mContext, mFragment, new Lifecycle());
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ mController = new LogPersistPreferenceControllerV2(mContext, mFragment, mLifecycle);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
SystemProperties.set("ro.debuggable", "1");
mController.displayPreference(mScreen);
diff --git a/tests/robotests/src/com/android/settings/development/LogpersistPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/LogpersistPreferenceControllerTest.java
index 379890e..bd1af34 100644
--- a/tests/robotests/src/com/android/settings/development/LogpersistPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/LogpersistPreferenceControllerTest.java
@@ -40,7 +40,7 @@
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class LogpersistPreferenceControllerTest {
- private Lifecycle mLifecycle = new Lifecycle();
+ private Lifecycle mLifecycle;
@Mock
private ListPreference mListPreference;
@@ -50,6 +50,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController
= new LogpersistPreferenceController(RuntimeEnvironment.application, mLifecycle);
}
diff --git a/tests/robotests/src/com/android/settings/development/PictureColorModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/PictureColorModePreferenceControllerTest.java
index 5cf4e10..fac74ac 100644
--- a/tests/robotests/src/com/android/settings/development/PictureColorModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/PictureColorModePreferenceControllerTest.java
@@ -16,6 +16,9 @@
package com.android.settings.development;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
@@ -58,7 +61,7 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController = new PictureColorModePreferenceController(mContext, mLifecycle);
when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
mPreference);
@@ -123,14 +126,15 @@
@Test
public void onResume_shouldStartListening() {
- mLifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
verify(mPreference).startListening();
}
@Test
public void onPause_shouldStopListening() {
- mLifecycle.onPause();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
+ mLifecycle.handleLifecycleEvent(ON_PAUSE);
verify(mPreference).stopListening();
}
diff --git a/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java
index 8b96af0..71260f3 100644
--- a/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java
@@ -16,6 +16,9 @@
package com.android.settings.development;
+import static android.arch.lifecycle.Lifecycle.Event.ON_CREATE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_DESTROY;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
@@ -74,7 +77,7 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mContext = spy(RuntimeEnvironment.application);
doReturn(mUsbManager).when(mContext).getSystemService(Context.USB_SERVICE);
mValues = mContext.getResources().getStringArray(R.array.usb_configuration_values);
@@ -148,6 +151,7 @@
@Test
public void onCreate_shouldRegisterReceiver() {
mLifecycle.onCreate(null /* bundle */);
+ mLifecycle.handleLifecycleEvent(ON_CREATE);
verify(mContext).registerReceiver(any(), any());
}
@@ -155,7 +159,8 @@
@Test
public void onDestroy_shouldUnregisterReceiver() {
doNothing().when(mContext).unregisterReceiver(any());
- mLifecycle.onDestroy();
+ mLifecycle.handleLifecycleEvent(ON_CREATE);
+ mLifecycle.handleLifecycleEvent(ON_DESTROY);
verify(mContext).unregisterReceiver(any());
}
diff --git a/tests/robotests/src/com/android/settings/development/VerifyAppsOverUsbPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/VerifyAppsOverUsbPreferenceControllerTest.java
index cea3d89..3208810 100644
--- a/tests/robotests/src/com/android/settings/development/VerifyAppsOverUsbPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/VerifyAppsOverUsbPreferenceControllerTest.java
@@ -30,8 +30,8 @@
import android.provider.Settings.Global;
import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedSwitchPreference;
@@ -76,6 +76,7 @@
return this;
}
}
+
private final GlobalSetter mGlobals = new GlobalSetter();
@Before
@@ -175,7 +176,9 @@
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
when(mScreen.getPreferenceCount()).thenReturn(1);
when(mScreen.getPreference(anyInt())).thenReturn(mPreference);
+
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(mPreference);
+
+ verify(mPreference).setVisible(false);
}
}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceControllerTest.java
index 3d95cf4..fabf3b6 100644
--- a/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceControllerTest.java
@@ -16,7 +16,10 @@
package com.android.settings.development.featureflags;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -37,7 +40,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class FeatureFlagPreferenceControllerTest {
@Mock
@@ -50,7 +53,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController = new FeatureFlagsPreferenceController(mContext, mLifecycle);
when(mScreen.getContext()).thenReturn(mContext);
mController.displayPreference(mScreen);
@@ -64,7 +67,7 @@
@Test
public void onStart_shouldRefreshFeatureFlags() {
- mLifecycle.onStart();
+ mLifecycle.handleLifecycleEvent(ON_START);
verify(mScreen).removeAll();
verify(mScreen).addPreference(any(FeatureFlagPreference.class));
diff --git a/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceTest.java b/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceTest.java
index 11099b1..35ad7e1 100644
--- a/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceTest.java
@@ -30,7 +30,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class FeatureFlagPreferenceTest {
private static final String KEY = "feature_key";
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/BatteryInfoPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/BatteryInfoPreferenceControllerTest.java
index 362e813..0ccc139 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/BatteryInfoPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/BatteryInfoPreferenceControllerTest.java
@@ -16,11 +16,16 @@
package com.android.settings.deviceinfo;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+
import static com.android.settings.deviceinfo.BatteryInfoPreferenceController
.BATTERY_INFO_RECEIVER_INTENT_FILTER;
import static com.android.settings.deviceinfo.BatteryInfoPreferenceController.KEY_BATTERY_LEVEL;
import static com.android.settings.deviceinfo.BatteryInfoPreferenceController.KEY_BATTERY_STATUS;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -62,7 +67,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController = new BatteryInfoPreferenceController(mContext, mLifecycle);
mBatteryLevel = new Preference(mContext);
mBatteryStatus = new Preference(mContext);
@@ -80,8 +85,8 @@
public void runThroughLifecycle_shouldRegisterUnregisterBatteryInfoReceiver() {
final Context context = mock(Context.class);
mController = new BatteryInfoPreferenceController(context, mLifecycle);
- mLifecycle.onStart();
- mLifecycle.onStop();
+ mLifecycle.handleLifecycleEvent(ON_START);
+ mLifecycle.handleLifecycleEvent(ON_STOP);
verify(context).registerReceiver(mController.mBatteryInfoReceiver,
BATTERY_INFO_RECEIVER_INTENT_FILTER);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
index 8d5554c..16de8ea 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
@@ -84,7 +84,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mFactory = FakeFeatureFactory.setupForTest(mContext);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
mController = new BuildNumberPreferenceController(
mContext, mActivity, mFragment, mLifecycle);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java
index 108d342..aa86fd9 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java
@@ -16,13 +16,20 @@
package com.android.settings.deviceinfo;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.app.Fragment;
import android.content.Context;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-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;
@@ -32,15 +39,8 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class DeviceModelPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/FirmwareVersionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/FirmwareVersionPreferenceControllerTest.java
index 5a4d988..207d58e 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/FirmwareVersionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/FirmwareVersionPreferenceControllerTest.java
@@ -15,13 +15,17 @@
*/
package com.android.settings.deviceinfo;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -32,9 +36,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
-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 FirmwareVersionPreferenceControllerTest {
@@ -53,7 +54,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(null);
mController = new FirmwareVersionPreferenceController(mContext, mLifecycle);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/HardwareInfoDialogFragmentTest.java b/tests/robotests/src/com/android/settings/deviceinfo/HardwareInfoDialogFragmentTest.java
index 15461cc2..e56a2b2 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/HardwareInfoDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/HardwareInfoDialogFragmentTest.java
@@ -38,7 +38,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class HardwareInfoDialogFragmentTest {
private Activity mActivity;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/SystemUpdatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/SystemUpdatePreferenceControllerTest.java
index 5c62220..32bcd60 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/SystemUpdatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/SystemUpdatePreferenceControllerTest.java
@@ -15,6 +15,10 @@
*/
package com.android.settings.deviceinfo;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
@@ -22,8 +26,8 @@
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.R;
-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;
@@ -36,30 +40,27 @@
import java.util.ArrayList;
import java.util.List;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class SystemUpdatePreferenceControllerTest {
@Mock(answer = RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private UserManager mUserManager;
- @Mock(answer = RETURNS_DEEP_STUBS)
+ @Mock
private PreferenceScreen mScreen;
private SystemUpdatePreferenceController mController;
+ private Preference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new SystemUpdatePreferenceController(mContext, mUserManager);
+ mPreference = new Preference(RuntimeEnvironment.application);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
}
@Test
@@ -86,41 +87,30 @@
@Test
public void displayPrefs_nothingAvailable_shouldNotDisplay() {
- final Preference preference = mock(Preference.class);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(preference);
- when(preference.getKey()).thenReturn(mController.getPreferenceKey());
-
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
public void updateState_shouldSetToAndroidVersion() {
- final Preference preference = new Preference(RuntimeEnvironment.application);
mController = new SystemUpdatePreferenceController(
RuntimeEnvironment.application, mUserManager);
- mController.updateState(preference);
+ mController.updateState(mPreference);
- assertThat(preference.getSummary())
+ assertThat(mPreference.getSummary())
.isEqualTo(RuntimeEnvironment.application.getString(R.string.about_summary,
Build.VERSION.RELEASE));
}
@Test
public void displayPrefs_oneAvailable_shouldDisplayOne() {
- final Preference preference = mock(Preference.class);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(preference);
- when(preference.getKey()).thenReturn(mController.getPreferenceKey());
-
when(mContext.getResources().getBoolean(
R.bool.config_additional_system_update_setting_enable))
.thenReturn(true);
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionDialogControllerTest.java
new file mode 100644
index 0000000..0584a53
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionDialogControllerTest.java
@@ -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.deviceinfo.firmwareversion;
+
+import static com.android.settings.deviceinfo.firmwareversion.BasebandVersionDialogController
+ .BASEBAND_PROPERTY;
+import static com.android.settings.deviceinfo.firmwareversion.BasebandVersionDialogController
+ .BASEBAND_VERSION_LABEL_ID;
+import static com.android.settings.deviceinfo.firmwareversion.BasebandVersionDialogController
+ .BASEBAND_VERSION_VALUE_ID;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.robolectric.shadow.api.Shadow.extract;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.os.SystemProperties;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
+import com.android.settings.testutils.shadow.ShadowConnectivityManager;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH,
+ sdk = TestConfig.SDK_VERSION_O,
+ shadows = {ShadowConnectivityManager.class, SettingsShadowSystemProperties.class})
+public class BasebandVersionDialogControllerTest {
+
+ @Mock
+ private FirmwareVersionDialogFragment mDialog;
+
+ private Context mContext;
+ private BasebandVersionDialogController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ when(mDialog.getContext()).thenReturn(mContext);
+ mController = new BasebandVersionDialogController(mDialog);
+ }
+
+ @After
+ public void teardown() {
+ SettingsShadowSystemProperties.clear();
+ }
+
+ @Test
+ public void initialize_wifiOnly_shouldRemoveSettingFromDialog() {
+ ShadowConnectivityManager connectivityManager =
+ extract(mContext.getSystemService(ConnectivityManager.class));
+ connectivityManager.setNetworkSupported(ConnectivityManager.TYPE_MOBILE, false);
+
+ mController.initialize();
+
+ verify(mDialog).removeSettingFromScreen(BASEBAND_VERSION_LABEL_ID);
+ verify(mDialog).removeSettingFromScreen(BASEBAND_VERSION_VALUE_ID);
+ }
+
+ @Test
+ public void initialize_hasMobile_shouldSetDialogTextToBasebandVersion() {
+ final String text = "test";
+ SystemProperties.set(BASEBAND_PROPERTY, text);
+ ShadowConnectivityManager connectivityManager =
+ extract(mContext.getSystemService(ConnectivityManager.class));
+ connectivityManager.setNetworkSupported(ConnectivityManager.TYPE_MOBILE, true);
+
+ mController.initialize();
+
+ verify(mDialog).setText(BASEBAND_VERSION_VALUE_ID, text);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/BuildNumberDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/BuildNumberDialogControllerTest.java
new file mode 100644
index 0000000..8bdf84c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/BuildNumberDialogControllerTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.firmwareversion;
+
+import static com.android.settings.deviceinfo.firmwareversion.BuildNumberDialogController
+ .BUILD_NUMBER_VALUE_ID;
+
+import static org.mockito.Mockito.verify;
+
+import android.os.Build;
+import android.text.BidiFormatter;
+
+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.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class BuildNumberDialogControllerTest {
+
+ @Mock
+ private FirmwareVersionDialogFragment mDialog;
+
+ private BuildNumberDialogController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mController = new BuildNumberDialogController(mDialog);
+ }
+
+ @Test
+ public void initialize_shouldUpdateBuildNumberToDialog() {
+ mController.initialize();
+
+ verify(mDialog).setText(BUILD_NUMBER_VALUE_ID,
+ BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogControllerTest.java
new file mode 100644
index 0000000..00d1386
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogControllerTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.firmwareversion;
+
+import static com.android.settings.deviceinfo.firmwareversion.FirmwareVersionDialogController
+ .FIRMWARE_VERSION_LABEL_ID;
+import static com.android.settings.deviceinfo.firmwareversion.FirmwareVersionDialogController
+ .FIRMWARE_VERSION_VALUE_ID;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Build;
+import android.os.UserManager;
+import android.view.View;
+
+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_O)
+public class FirmwareVersionDialogControllerTest {
+
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private FirmwareVersionDialogFragment mDialog;
+ @Mock
+ private View mView;
+
+ private Context mContext;
+ private FirmwareVersionDialogController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ when(mDialog.getContext()).thenReturn(mContext);
+ mController = spy(new FirmwareVersionDialogController(mDialog));
+ ReflectionHelpers.setField(mController, "mUserManager", mUserManager);
+ doNothing().when(mController).arrayCopy();
+ doNothing().when(mController).initializeAdminPermissions();
+ }
+
+ @Test
+ public void initialize_shouldRegisterListenersAndSetBuildVersion() {
+ mController.initialize();
+
+ verify(mDialog).registerClickListener(eq(FIRMWARE_VERSION_VALUE_ID), any());
+ verify(mDialog).registerClickListener(eq(FIRMWARE_VERSION_LABEL_ID), any());
+ verify(mDialog).setText(FIRMWARE_VERSION_VALUE_ID, Build.VERSION.RELEASE);
+ }
+
+ @Test
+ public void handleSettingClicked_userRestricted_shouldDoNothing() {
+ final long[] hits = ReflectionHelpers.getField(mController, "mHits");
+ hits[0] = Long.MAX_VALUE;
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_FUN)).thenReturn(true);
+
+ mController.onClick(mView);
+
+ verify(mContext, never()).startActivity(any());
+ }
+
+ @Test
+ public void handleSettingClicked_userNotRestricted_shouldStartActivity() {
+ final long[] hits = ReflectionHelpers.getField(mController, "mHits");
+ hits[0] = Long.MAX_VALUE;
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_FUN)).thenReturn(false);
+
+ mController.onClick(mView);
+
+ verify(mContext).startActivity(any());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionDialogControllerTest.java
new file mode 100644
index 0000000..0dfedf4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionDialogControllerTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.android.settings.deviceinfo.firmwareversion.KernelVersionDialogController
+ .KERNEL_VERSION_VALUE_ID;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.DeviceInfoUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class KernelVersionDialogControllerTest {
+
+ @Mock
+ private FirmwareVersionDialogFragment mDialog;
+
+ private Context mContext;
+ private KernelVersionDialogController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ when(mDialog.getContext()).thenReturn(mContext);
+ mController = new KernelVersionDialogController(mDialog);
+ }
+
+ @Test
+ public void initialize_shouldUpdateKernelVersionToDialog() {
+ mController.initialize();
+
+ verify(mDialog).setText(KERNEL_VERSION_VALUE_ID,
+ DeviceInfoUtils.getFormattedKernelVersion(mContext));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelDialogControllerTest.java
new file mode 100644
index 0000000..ea37c2e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelDialogControllerTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.android.settings.deviceinfo.firmwareversion.SecurityPatchLevelDialogController
+ .SECURITY_PATCH_LABEL_ID;
+import static com.android.settings.deviceinfo.firmwareversion.SecurityPatchLevelDialogController
+ .SECURITY_PATCH_VALUE_ID;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Build;
+import android.view.View;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.wrapper.PackageManagerWrapper;
+
+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;
+
+import java.util.Collections;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class SecurityPatchLevelDialogControllerTest {
+
+ @Mock
+ private PackageManagerWrapper mPackageManager;
+ @Mock
+ private FirmwareVersionDialogFragment mDialog;
+ @Mock
+ private View mView;
+
+ private Context mContext;
+ private SecurityPatchLevelDialogController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ when(mDialog.getContext()).thenReturn(mContext);
+ }
+
+ @Test
+ public void initialize_noPatchInfo_shouldRemoveSettingFromDialog() {
+ ReflectionHelpers.setStaticField(Build.VERSION.class, "SECURITY_PATCH", "");
+ mController = new SecurityPatchLevelDialogController(mDialog);
+
+ mController.initialize();
+
+ verify(mDialog).removeSettingFromScreen(SECURITY_PATCH_VALUE_ID);
+ verify(mDialog).removeSettingFromScreen(SECURITY_PATCH_LABEL_ID);
+ }
+
+ @Test
+ public void initialize_patchInfoAvailable_shouldRegisterListeners() {
+ ReflectionHelpers.setStaticField(Build.VERSION.class, "SECURITY_PATCH", "foobar");
+ mController = new SecurityPatchLevelDialogController(mDialog);
+
+ mController.initialize();
+
+ verify(mDialog).registerClickListener(eq(SECURITY_PATCH_LABEL_ID), any());
+ verify(mDialog).registerClickListener(eq(SECURITY_PATCH_VALUE_ID), any());
+ }
+
+ @Test
+ public void onClick_noActivityIntent_shouldDoNothing() {
+ when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(
+ Collections.emptyList());
+ mController = new SecurityPatchLevelDialogController(mDialog);
+ ReflectionHelpers.setField(mController, "mPackageManager", mPackageManager);
+
+ mController.onClick(mView);
+
+ verify(mContext, never()).startActivity(any());
+ }
+
+ @Test
+ public void onClick_activityIntentFound_shouldStartActivity() {
+ when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(
+ Collections.singletonList(null));
+ mController = new SecurityPatchLevelDialogController(mDialog);
+ ReflectionHelpers.setField(mController, "mPackageManager", mPackageManager);
+
+ mController.onClick(mView);
+
+ verify(mContext).startActivity(any());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
index d2ee543..fd48162 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
@@ -91,14 +91,16 @@
private SimStatusDialogController mController;
private Context mContext;
+ private Lifecycle mLifecycle;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
when(mDialog.getContext()).thenReturn(mContext);
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController = spy(
- new SimStatusDialogController(mDialog, new Lifecycle(), 0 /* phone id */));
+ new SimStatusDialogController(mDialog, mLifecycle, 0 /* phone id */));
doReturn(mServiceState).when(mController).getCurrentServiceState();
doReturn(0).when(mController).getDbm(any());
doReturn(0).when(mController).getAsuLevel(any());
diff --git a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
index 06fd297..091ae1a 100644
--- a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
@@ -16,6 +16,12 @@
package com.android.settings.display;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.when;
+
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -23,9 +29,9 @@
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowSystemSettings;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -39,11 +45,6 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(
manifest = TestConfig.MANIFEST_PATH,
@@ -66,7 +67,7 @@
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
mContentResolver = RuntimeEnvironment.application.getContentResolver();
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mPreference = new SwitchPreference(RuntimeEnvironment.application);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
diff --git a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
index fb9bb9f..dc3d27a 100644
--- a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
@@ -25,7 +25,7 @@
import android.os.Bundle;
-import com.android.internal.app.NightDisplayController;
+import com.android.internal.app.ColorDisplayController;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.TestConfig;
@@ -52,7 +52,7 @@
private ColorModePreferenceFragment mFragment;
@Mock
- private NightDisplayController mController;
+ private ColorDisplayController mController;
@Before
public void setup() {
@@ -88,7 +88,7 @@
@Test
public void getKey_natural() {
Mockito.when(mController.getColorMode()).thenReturn(
- NightDisplayController.COLOR_MODE_NATURAL);
+ ColorDisplayController.COLOR_MODE_NATURAL);
assertThat(mFragment.getDefaultKey())
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_NATURAL);
@@ -98,7 +98,7 @@
@Test
public void getKey_boosted() {
Mockito.when(mController.getColorMode()).thenReturn(
- NightDisplayController.COLOR_MODE_BOOSTED);
+ ColorDisplayController.COLOR_MODE_BOOSTED);
assertThat(mFragment.getDefaultKey())
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_BOOSTED);
@@ -108,7 +108,7 @@
@Test
public void getKey_saturated() {
Mockito.when(mController.getColorMode()).thenReturn(
- NightDisplayController.COLOR_MODE_SATURATED);
+ ColorDisplayController.COLOR_MODE_SATURATED);
assertThat(mFragment.getDefaultKey())
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_SATURATED);
@@ -118,21 +118,21 @@
@Test
public void setKey_natural() {
mFragment.setDefaultKey(ColorModePreferenceFragment.KEY_COLOR_MODE_NATURAL);
- verify(mController).setColorMode(NightDisplayController.COLOR_MODE_NATURAL);
+ verify(mController).setColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
}
@Config(shadows = {SettingsShadowSystemProperties.class})
@Test
public void setKey_boosted() {
mFragment.setDefaultKey(ColorModePreferenceFragment.KEY_COLOR_MODE_BOOSTED);
- verify(mController).setColorMode(NightDisplayController.COLOR_MODE_BOOSTED);
+ verify(mController).setColorMode(ColorDisplayController.COLOR_MODE_BOOSTED);
}
@Config(shadows = {SettingsShadowSystemProperties.class})
@Test
public void setKey_saturated() {
mFragment.setDefaultKey(ColorModePreferenceFragment.KEY_COLOR_MODE_SATURATED);
- verify(mController).setColorMode(NightDisplayController.COLOR_MODE_SATURATED);
+ verify(mController).setColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceControllerTest.java
index 491fcdb..1154aa7 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceControllerTest.java
@@ -34,13 +34,11 @@
public AdminGrantedCameraPermissionPreferenceControllerTest() {
super("enterprise_privacy_number_camera_access_packages",
- new String[] {Manifest.permission.CAMERA},
- Manifest.permission_group.CAMERA);
+ new String[] {Manifest.permission.CAMERA});
}
@Override
protected AdminGrantedPermissionsPreferenceControllerBase createController(boolean async) {
- return new AdminGrantedCameraPermissionPreferenceController(mContext,null /* lifecycle */,
- async);
+ return new AdminGrantedCameraPermissionPreferenceController(mContext, async);
}
}
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceControllerTest.java
index 01a13d2..1c30da1 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceControllerTest.java
@@ -18,8 +18,8 @@
import android.Manifest;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
@@ -35,13 +35,11 @@
public AdminGrantedLocationPermissionsPreferenceControllerTest() {
super("enterprise_privacy_number_location_access_packages",
new String[] {Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION},
- Manifest.permission_group.LOCATION);
+ Manifest.permission.ACCESS_FINE_LOCATION});
}
@Override
protected AdminGrantedPermissionsPreferenceControllerBase createController(boolean async) {
- return new AdminGrantedLocationPermissionsPreferenceController(mContext,
- null /* lifecycle */, async);
+ return new AdminGrantedLocationPermissionsPreferenceController(mContext, async);
}
}
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceControllerTest.java
index fed1631..624022b 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceControllerTest.java
@@ -18,8 +18,8 @@
import android.Manifest;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
@@ -34,13 +34,11 @@
public AdminGrantedMicrophonePermissionPreferenceControllerTest() {
super("enterprise_privacy_number_microphone_access_packages",
- new String[] {Manifest.permission.RECORD_AUDIO},
- Manifest.permission_group.MICROPHONE);
+ new String[] {Manifest.permission.RECORD_AUDIO});
}
@Override
protected AdminGrantedPermissionsPreferenceControllerBase createController(boolean async) {
- return new AdminGrantedMicrophonePermissionPreferenceController(mContext,
- null /* lifecycle */, async);
+ return new AdminGrantedMicrophonePermissionPreferenceController(mContext, async);
}
}
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBaseTest.java
index a209a46..a5d1d1a 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBaseTest.java
@@ -16,8 +16,8 @@
package com.android.settings.enterprise;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
@@ -31,7 +31,7 @@
AdminGrantedPermissionsPreferenceControllerTestBase {
public AdminGrantedPermissionsPreferenceControllerBaseTest() {
- super("some.key", new String[] {"some.permission"}, "some.permission");
+ super("some.key", new String[] {"some.permission"});
}
@Override
@@ -44,7 +44,7 @@
AdminGrantedPermissionsPreferenceControllerBaseTestable(boolean async) {
super(AdminGrantedPermissionsPreferenceControllerBaseTest.this.mContext,
- null /* lifecycle */, async, mPermissions, mPermissionGroup);
+ async, mPermissions);
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerTestBase.java b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerTestBase.java
index c1a3143..421fb0f 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerTestBase.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerTestBase.java
@@ -16,12 +16,17 @@
package com.android.settings.enterprise;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.support.v7.preference.Preference;
import com.android.settings.R;
import com.android.settings.applications.ApplicationFeatureProvider;
-import com.android.settings.core.PreferenceAvailabilityObserver;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
@@ -32,35 +37,22 @@
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* Common base for testing subclasses of {@link AdminGrantedPermissionsPreferenceControllerBase}.
*/
public abstract class AdminGrantedPermissionsPreferenceControllerTestBase {
protected final String mKey;
protected final String[] mPermissions;
- protected final String mPermissionGroup;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
protected Context mContext;
private FakeFeatureFactory mFeatureFactory;
- @Mock private PreferenceAvailabilityObserver mObserver;
protected AdminGrantedPermissionsPreferenceControllerBase mController;
- public AdminGrantedPermissionsPreferenceControllerTestBase(String key, String[] permissions,
- String permissionGroup) {
+ public AdminGrantedPermissionsPreferenceControllerTestBase(String key, String[] permissions) {
mKey = key;
mPermissions = permissions;
- mPermissionGroup = permissionGroup;
}
@Before
@@ -69,12 +61,6 @@
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
mController = createController(true /* async */);
- mController.setAvailabilityObserver(mObserver);
- }
-
- @Test
- public void testGetAvailabilityObserver() {
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
}
private void setNumberOfPackagesWithAdminGrantedPermissions(int number, boolean async) {
@@ -96,7 +82,6 @@
setNumberOfPackagesWithAdminGrantedPermissions(0, true /* async */);
mController.updateState(preference);
assertThat(preference.isVisible()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(mKey, false);
setNumberOfPackagesWithAdminGrantedPermissions(20, true /* async */);
when(mContext.getResources().getQuantityString(
@@ -105,33 +90,27 @@
mController.updateState(preference);
assertThat(preference.getSummary()).isEqualTo("minimum 20 apps");
assertThat(preference.isVisible()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(mKey, true);
}
@Test
public void testIsAvailableSync() {
final AdminGrantedPermissionsPreferenceControllerBase controller
= createController(false /* async */);
- controller.setAvailabilityObserver(mObserver);
setNumberOfPackagesWithAdminGrantedPermissions(0, false /* async */);
assertThat(controller.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(mKey, false);
setNumberOfPackagesWithAdminGrantedPermissions(20, false /* async */);
assertThat(controller.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(mKey, true);
}
@Test
public void testIsAvailableAsync() {
setNumberOfPackagesWithAdminGrantedPermissions(0, true /* async */);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(eq(mKey), anyBoolean());
setNumberOfPackagesWithAdminGrantedPermissions(20, true /* async */);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(eq(mKey), anyBoolean());
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceControllerTest.java
index 045acf2..365b9be 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceControllerTest.java
@@ -16,14 +16,16 @@
package com.android.settings.enterprise;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
-import com.android.settings.R;
import android.support.v7.preference.Preference;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.R;
import com.android.settings.TestConfig;
-import com.android.settings.core.PreferenceAvailabilityObserver;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
@@ -33,10 +35,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* Tests for {@link AlwaysOnVpnCurrentUserPreferenceController}.
*/
@@ -51,7 +49,6 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
- @Mock private PreferenceAvailabilityObserver mObserver;
private AlwaysOnVpnCurrentUserPreferenceController mController;
@@ -60,18 +57,11 @@
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
- mController = new AlwaysOnVpnCurrentUserPreferenceController(mContext,
- null /* lifecycle */);
+ mController = new AlwaysOnVpnCurrentUserPreferenceController(mContext);
when(mContext.getString(R.string.enterprise_privacy_always_on_vpn_device))
.thenReturn(VPN_SET_DEVICE);
when(mContext.getString(R.string.enterprise_privacy_always_on_vpn_personal))
.thenReturn(VPN_SET_PERSONAL);
- mController.setAvailabilityObserver(mObserver);
- }
-
- @Test
- public void testGetAvailabilityObserver() {
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
}
@Test
@@ -95,12 +85,10 @@
when(mFeatureFactory.enterprisePrivacyFeatureProvider.isAlwaysOnVpnSetInCurrentUser())
.thenReturn(false);
assertThat(mController.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_ALWAYS_ON_VPN_PRIMARY_USER, false);
when(mFeatureFactory.enterprisePrivacyFeatureProvider.isAlwaysOnVpnSetInCurrentUser())
.thenReturn(true);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_ALWAYS_ON_VPN_PRIMARY_USER, true);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnManagedProfilePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnManagedProfilePreferenceControllerTest.java
index b321652..5f921cd 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnManagedProfilePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnManagedProfilePreferenceControllerTest.java
@@ -16,13 +16,15 @@
package com.android.settings.enterprise;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.support.v7.preference.Preference;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
-import com.android.settings.core.PreferenceAvailabilityObserver;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
@@ -32,10 +34,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* Tests for {@link AlwaysOnVpnManagedProfilePreferenceController}.
*/
@@ -48,7 +46,6 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
- @Mock private PreferenceAvailabilityObserver mObserver;
private AlwaysOnVpnManagedProfilePreferenceController mController;
@@ -57,14 +54,7 @@
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
- mController = new AlwaysOnVpnManagedProfilePreferenceController(mContext,
- null /* lifecycle */);
- mController.setAvailabilityObserver(mObserver);
- }
-
- @Test
- public void testGetAvailabilityObserver() {
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
+ mController = new AlwaysOnVpnManagedProfilePreferenceController(mContext);
}
@Test
@@ -72,12 +62,10 @@
when(mFeatureFactory.enterprisePrivacyFeatureProvider.isAlwaysOnVpnSetInManagedProfile())
.thenReturn(false);
assertThat(mController.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_ALWAYS_ON_VPN_MANAGED_PROFILE, false);
when(mFeatureFactory.enterprisePrivacyFeatureProvider.isAlwaysOnVpnSetInManagedProfile())
.thenReturn(true);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_ALWAYS_ON_VPN_MANAGED_PROFILE, true);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/ApplicationListFragmentTest.java b/tests/robotests/src/com/android/settings/enterprise/ApplicationListFragmentTest.java
index a6f95aa..80d4aaf 100644
--- a/tests/robotests/src/com/android/settings/enterprise/ApplicationListFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/ApplicationListFragmentTest.java
@@ -17,9 +17,7 @@
package com.android.settings.enterprise;
import static com.android.settings.testutils.ApplicationTestUtils.buildInfo;
-
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.when;
@@ -30,10 +28,10 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.applications.UserAppInfo;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.AbstractPreferenceController;
import org.junit.Before;
@@ -86,7 +84,8 @@
@Test
public void getPreferenceControllers() {
- final List<AbstractPreferenceController> controllers = mFragment.getPreferenceControllers(mContext);
+ final List<AbstractPreferenceController> controllers = mFragment.getPreferenceControllers(
+ mContext);
assertThat(controllers).isNotNull();
assertThat(controllers.size()).isEqualTo(1);
int position = 0;
@@ -94,7 +93,8 @@
ApplicationListPreferenceController.class);
}
- @Test public void getCategories() {
+ @Test
+ public void getCategories() {
assertThat(new ApplicationListFragment.AdminGrantedPermissionCamera().getMetricsCategory())
.isEqualTo(MetricsEvent.ENTERPRISE_PRIVACY_PERMISSIONS);
assertThat(new ApplicationListFragment.AdminGrantedPermissionLocation().
diff --git a/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java
index 35d78a5..5ee1145 100644
--- a/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java
@@ -73,7 +73,7 @@
@Override
CaCertsPreferenceControllerBase createController() {
- return new CaCertsCurrentUserPreferenceController(mContext, null /* lifecycle */);
+ return new CaCertsCurrentUserPreferenceController(mContext);
}
private void assertUpdateState(boolean isCompMode, String expectedTitle) {
diff --git a/tests/robotests/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceControllerTest.java
index 41b7f45..2aa5306 100644
--- a/tests/robotests/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceControllerTest.java
@@ -45,6 +45,6 @@
@Override
CaCertsPreferenceControllerBase createController() {
- return new CaCertsManagedProfilePreferenceController(mContext, null /* lifecycle */);
+ return new CaCertsManagedProfilePreferenceController(mContext);
}
}
diff --git a/tests/robotests/src/com/android/settings/enterprise/CaCertsPreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/enterprise/CaCertsPreferenceControllerBaseTest.java
index 37b903a..ec76b2b 100644
--- a/tests/robotests/src/com/android/settings/enterprise/CaCertsPreferenceControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/CaCertsPreferenceControllerBaseTest.java
@@ -50,7 +50,7 @@
CaCertsPreferenceControllerBase {
public CaCertsPreferenceControllerBaseTestable(Context context) {
- super(context, null);
+ super(context);
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/CaCertsPreferenceControllerTestBase.java b/tests/robotests/src/com/android/settings/enterprise/CaCertsPreferenceControllerTestBase.java
index c171fba..c2fb4da 100644
--- a/tests/robotests/src/com/android/settings/enterprise/CaCertsPreferenceControllerTestBase.java
+++ b/tests/robotests/src/com/android/settings/enterprise/CaCertsPreferenceControllerTestBase.java
@@ -17,15 +17,12 @@
package com.android.settings.enterprise;
import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.support.v7.preference.Preference;
import com.android.settings.R;
-import com.android.settings.core.PreferenceAvailabilityObserver;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
@@ -43,8 +40,6 @@
protected Context mContext;
protected FakeFeatureFactory mFeatureFactory;
protected CaCertsPreferenceControllerBase mController;
- @Mock
- private PreferenceAvailabilityObserver mObserver;
@Before
public void setUp() {
@@ -52,12 +47,6 @@
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
mController = createController();
- mController.setAvailabilityObserver(mObserver);
- }
-
- @Test
- public void testGetAvailabilityObserver() {
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
}
@Test
@@ -75,11 +64,9 @@
public void testIsAvailable() {
mockGetNumberOfCaCerts(0);
assertThat(mController.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(getPreferenceKey(), false);
mockGetNumberOfCaCerts(10);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(getPreferenceKey(), true);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java
index cc6335f..b4f7827 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java
@@ -16,15 +16,20 @@
package com.android.settings.enterprise;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.anyObject;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.support.v7.preference.Preference;
import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.applications.ApplicationFeatureProvider;
-import com.android.settings.core.PreferenceAvailabilityObserver;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
@@ -36,15 +41,6 @@
import org.mockito.stubbing.Answer;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyObject;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* Tests for {@link EnterpriseInstalledPackagesPreferenceController}.
*/
@@ -58,7 +54,6 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
- @Mock private PreferenceAvailabilityObserver mObserver;
private EnterpriseInstalledPackagesPreferenceController mController;
@@ -68,13 +63,7 @@
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
mController = new EnterpriseInstalledPackagesPreferenceController(mContext,
- null /* lifecycle */, true /* async */);
- mController.setAvailabilityObserver(mObserver);
- }
-
- @Test
- public void testGetAvailabilityObserver() {
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
+ true /* async */);
}
private void setNumberOfEnterpriseInstalledPackages(int number, boolean async) {
@@ -83,8 +72,9 @@
((ApplicationFeatureProvider.NumberOfAppsCallback)
invocation.getArguments()[1]).onNumberOfAppsResult(number);
return null;
- }}).when(mFeatureFactory.applicationFeatureProvider)
- .calculateNumberOfPolicyInstalledApps(eq(async), anyObject());
+ }
+ }).when(mFeatureFactory.applicationFeatureProvider)
+ .calculateNumberOfPolicyInstalledApps(eq(async), anyObject());
}
@Test
@@ -95,8 +85,6 @@
setNumberOfEnterpriseInstalledPackages(0, true /* async */);
mController.updateState(preference);
assertThat(preference.isVisible()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_NUMBER_ENTERPRISE_INSTALLED_PACKAGES,
- false);
setNumberOfEnterpriseInstalledPackages(20, true /* async */);
when(mContext.getResources().getQuantityString(
@@ -105,39 +93,27 @@
mController.updateState(preference);
assertThat(preference.getSummary()).isEqualTo("minimum 20 apps");
assertThat(preference.isVisible()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_NUMBER_ENTERPRISE_INSTALLED_PACKAGES,
- true);
}
@Test
public void testIsAvailableSync() {
final EnterpriseInstalledPackagesPreferenceController controller
- = new EnterpriseInstalledPackagesPreferenceController(mContext,
- null /* lifecycle */, false /* async */);
- controller.setAvailabilityObserver(mObserver);
+ = new EnterpriseInstalledPackagesPreferenceController(mContext, false /* async */);
setNumberOfEnterpriseInstalledPackages(0, false /* async */);
assertThat(controller.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(
- KEY_NUMBER_ENTERPRISE_INSTALLED_PACKAGES, false);
setNumberOfEnterpriseInstalledPackages(20, false /* async */);
assertThat(controller.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(
- KEY_NUMBER_ENTERPRISE_INSTALLED_PACKAGES, true);
}
@Test
public void testIsAvailableAsync() {
setNumberOfEnterpriseInstalledPackages(0, true /* async */);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(
- eq(KEY_NUMBER_ENTERPRISE_INSTALLED_PACKAGES), anyBoolean());
setNumberOfEnterpriseInstalledPackages(20, true /* async */);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(
- eq(KEY_NUMBER_ENTERPRISE_INSTALLED_PACKAGES), anyBoolean());
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyPreferenceControllerTest.java
index 7077ad5..18f16f4 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyPreferenceControllerTest.java
@@ -16,14 +16,16 @@
package com.android.settings.enterprise;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.support.v7.preference.Preference;
import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
-import com.android.settings.core.PreferenceAvailabilityObserver;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
@@ -33,10 +35,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* Tests for {@link EnterprisePrivacyPreferenceController}.
*/
@@ -52,7 +50,6 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
- @Mock private PreferenceAvailabilityObserver mObserver;
private EnterprisePrivacyPreferenceController mController;
@@ -61,13 +58,7 @@
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
- mController = new EnterprisePrivacyPreferenceController(mContext, null /* lifecycle */);
- mController.setAvailabilityObserver(mObserver);
- }
-
- @Test
- public void testGetAvailabilityObserver() {
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
+ mController = new EnterprisePrivacyPreferenceController(mContext);
}
@Test
@@ -88,17 +79,15 @@
.thenReturn(MANAGING_ORGANIZATION);
mController.updateState(preference);
assertThat(preference.getSummary()).isEqualTo(MANAGED_WITH_NAME);
- }
+ }
@Test
public void testIsAvailable() {
when(mFeatureFactory.enterprisePrivacyFeatureProvider.hasDeviceOwner()).thenReturn(false);
assertThat(mController.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_ENTERPRISE_PRIVACY, false);
when(mFeatureFactory.enterprisePrivacyFeatureProvider.hasDeviceOwner()).thenReturn(true);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_ENTERPRISE_PRIVACY, true);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
index 4da3289..a2b539d 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
@@ -17,18 +17,16 @@
package com.android.settings.enterprise;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.content.res.XmlResourceParser;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.TestConfig;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
import org.junit.Before;
@@ -37,14 +35,10 @@
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
-import org.xmlpull.v1.XmlPullParser;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
/**
* Tests for {@link EnterprisePrivacySettings}.
@@ -53,9 +47,6 @@
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public final class EnterprisePrivacySettingsTest {
- private final static String RESOURCES_NAMESPACE = "http://schemas.android.com/apk/res/android";
- private final static String ATTR_KEY = "key";
-
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
@@ -71,23 +62,11 @@
}
@Test
- public void testGetMetricsCategory() {
+ public void verifyConstants() {
assertThat(mSettings.getMetricsCategory())
.isEqualTo(MetricsEvent.ENTERPRISE_PRIVACY_SETTINGS);
- }
-
- @Test
- public void testGetCategoryKey() {
- assertThat(mSettings.getCategoryKey()).isNull();
- }
-
- @Test
- public void testGetLogTag() {
assertThat(mSettings.getLogTag()).isEqualTo("EnterprisePrivacySettings");
- }
-
- @Test
- public void testGetPreferenceScreenResId() {
+ assertThat(mSettings.getCategoryKey()).isNull();
assertThat(mSettings.getPreferenceScreenResId())
.isEqualTo(R.xml.enterprise_privacy_settings);
}
@@ -121,7 +100,7 @@
public void getSearchIndexProviderPreferenceControllers() throws Exception {
final List<AbstractPreferenceController> controllers
= EnterprisePrivacySettings.SEARCH_INDEX_DATA_PROVIDER.getPreferenceControllers(
- ShadowApplication.getInstance().getApplicationContext());
+ ShadowApplication.getInstance().getApplicationContext());
verifyPreferenceControllers(controllers);
}
@@ -155,67 +134,11 @@
CaCertsCurrentUserPreferenceController.class);
assertThat(controllers.get(position++)).isInstanceOf(
CaCertsManagedProfilePreferenceController.class);
- final AbstractPreferenceController exposureChangesCategoryController =
- controllers.get(position);
- final int exposureChangesCategoryControllerIndex = position;
assertThat(controllers.get(position++)).isInstanceOf(
- ExposureChangesCategoryPreferenceController.class);
+ PreferenceCategoryController.class);
assertThat(controllers.get(position++)).isInstanceOf(
FailedPasswordWipeCurrentUserPreferenceController.class);
assertThat(controllers.get(position++)).isInstanceOf(
FailedPasswordWipeManagedProfilePreferenceController.class);
-
- // The "Changes made by your organization's admin" category is hidden when all Preferences
- // inside it become unavailable. To do this correctly, the category's controller must:
- // a) Observe the availability of all Preferences in the category and
- // b) Be listed after those Preferences' controllers, so that availability is updated in
- // the correct order
-
- // Find all Preferences in the category.
- final XmlResourceParser parser = RuntimeEnvironment.application.getResources().getXml(
- R.xml.enterprise_privacy_settings);
- boolean done = false;
- int type;
- final Set<String> expectedObserved = new HashSet<>();
- while (!done && (type = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (type != XmlPullParser.START_TAG || !"exposure_changes_category".equals(
- parser.getAttributeValue(RESOURCES_NAMESPACE, ATTR_KEY))) {
- continue;
- }
- int depth = 1;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (type == XmlPullParser.START_TAG) {
- final String key = parser.getAttributeValue(RESOURCES_NAMESPACE, ATTR_KEY);
- if (key != null) {
- expectedObserved.add(key);
- }
- depth++;
- } else if (type == XmlPullParser.END_TAG) {
- depth--;
- if (depth == 0) {
- done = true;
- break;
- }
- }
- }
- }
-
- // Find all Preferences the category's controller is observing.
- final Set<String> actualObserved = new HashSet<>();
- int maxObservedIndex = -1;
- for (int i = 0; i < controllers.size(); i++) {
- final AbstractPreferenceController controller = controllers.get(i);
- if (controller instanceof DynamicAvailabilityPreferenceController &&
- ((DynamicAvailabilityPreferenceController) controller).getAvailabilityObserver()
- == exposureChangesCategoryController) {
- actualObserved.add(controller.getPreferenceKey());
- maxObservedIndex = i;
- }
- }
-
- // Verify that the category's controller is observing the Preferences inside it.
- assertThat(actualObserved).isEqualTo(expectedObserved);
- // Verify that the category's controller is listed after the Preferences' controllers.
- assertThat(maxObservedIndex).isLessThan(exposureChangesCategoryControllerIndex);
}
}
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceControllerTest.java
index bb21bf7..9eb6d66 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceControllerTest.java
@@ -17,7 +17,6 @@
package com.android.settings.enterprise;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.argThat;
@@ -29,16 +28,14 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.UserInfo;
import android.os.UserHandle;
-import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.applications.EnterpriseDefaultApps;
import com.android.settings.applications.UserAppInfo;
-import com.android.settings.core.PreferenceAvailabilityObserver;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
@@ -51,8 +48,6 @@
import java.util.ArrayList;
import java.util.List;
-
-import static org.mockito.Mockito.verify;
/**
* Tests for {@link EnterpriseSetDefaultAppsPreferenceController}.
*/
@@ -65,9 +60,7 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private UserManager mUm;
private FakeFeatureFactory mFeatureFactory;
- @Mock private PreferenceAvailabilityObserver mObserver;
private EnterpriseSetDefaultAppsPreferenceController mController;
@@ -76,14 +69,7 @@
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
- mController = new EnterpriseSetDefaultAppsPreferenceController(mContext,
- null /* lifecycle */);
- mController.setAvailabilityObserver(mObserver);
- }
-
- @Test
- public void testGetAvailabilityObserver() {
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
+ mController = new EnterpriseSetDefaultAppsPreferenceController(mContext);
}
private void setEnterpriseSetDefaultApps(Intent[] intents, int number) {
@@ -130,12 +116,10 @@
when(mFeatureFactory.applicationFeatureProvider.findPersistentPreferredActivities(anyInt(),
any(Intent[].class))).thenReturn(new ArrayList<>());
assertThat(mController.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_DEFAULT_APPS, false);
setEnterpriseSetDefaultApps(EnterpriseDefaultApps.BROWSER.getIntents(), 1);
configureUsers(1);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_DEFAULT_APPS, true);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/ExposureChangesCategoryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/ExposureChangesCategoryPreferenceControllerTest.java
deleted file mode 100644
index f77aef8..0000000
--- a/tests/robotests/src/com/android/settings/enterprise/ExposureChangesCategoryPreferenceControllerTest.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.enterprise;
-
-import android.content.Context;
-import android.support.v7.preference.Preference;
-
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import com.android.settings.core.DynamicAvailabilityPreferenceController;
-import com.android.settings.core.PreferenceAvailabilityObserver;
-
-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.annotation.Config;
-
-import java.util.Arrays;
-import java.util.List;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-
-/**
- * Tests for {@link ExposureChangesCategoryPreferenceController}.
- */
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public final class ExposureChangesCategoryPreferenceControllerTest {
-
- private static final String KEY_1 = "key_1";
- private static final String KEY_2 = "key_2";
- private static final String KEY_EXPOSURE_CHANGES_CATEGORY = "exposure_changes_category";
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
- private List<DynamicAvailabilityPreferenceController> mControllers;
- private ExposureChangesCategoryPreferenceController mController;
- @Mock private PreferenceAvailabilityObserver mObserver;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mControllers = Arrays.asList(mock(DynamicAvailabilityPreferenceController.class),
- mock(DynamicAvailabilityPreferenceController.class));
- mController = new ExposureChangesCategoryPreferenceController(mContext,
- null /* lifecycle */, mControllers, true /* controllingUi */);
- mController.setAvailabilityObserver(mObserver);
- }
-
- @Test
- public void testInitialization() {
- verify(mControllers.get(0)).setAvailabilityObserver(mController);
- verify(mControllers.get(1)).setAvailabilityObserver(mController);
- }
-
- @Test
- public void testGetAvailabilityObserver() {
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
- }
-
- @Test
- public void testOnPreferenceAvailabilityUpdated() {
- final Preference preference = new Preference(mContext, null, 0, 0);
- preference.setVisible(true);
-
- mController.updateState(preference);
- assertThat(preference.isVisible()).isFalse();
-
- mController.onPreferenceAvailabilityUpdated(KEY_1, true);
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_EXPOSURE_CHANGES_CATEGORY, true);
- assertThat(preference.isVisible()).isTrue();
- reset(mObserver);
-
- mController.onPreferenceAvailabilityUpdated(KEY_2, true);
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_EXPOSURE_CHANGES_CATEGORY, true);
- assertThat(preference.isVisible()).isTrue();
- reset(mObserver);
-
- mController.onPreferenceAvailabilityUpdated(KEY_1, false);
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_EXPOSURE_CHANGES_CATEGORY, true);
- assertThat(preference.isVisible()).isTrue();
- reset(mObserver);
-
- mController.onPreferenceAvailabilityUpdated(KEY_2, false);
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_EXPOSURE_CHANGES_CATEGORY, false);
- assertThat(preference.isVisible()).isFalse();
- }
-
- @Test
- public void testUpdateState() {
- final Preference preference = new Preference(mContext, null, 0, 0);
- preference.setVisible(false);
-
- mController.onPreferenceAvailabilityUpdated(KEY_1, true);
- mController.updateState(preference);
- assertThat(preference.isVisible()).isTrue();
- }
-
- @Test
- public void testIsAvailableForUi() {
- assertThat(mController.isAvailable()).isTrue();
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(
- eq(KEY_EXPOSURE_CHANGES_CATEGORY), anyBoolean());
-
- mController.onPreferenceAvailabilityUpdated(KEY_1, true);
- reset(mObserver);
- assertThat(mController.isAvailable()).isTrue();
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(
- eq(KEY_EXPOSURE_CHANGES_CATEGORY), anyBoolean());
-
- mController.onPreferenceAvailabilityUpdated(KEY_1, false);
- reset(mObserver);
- assertThat(mController.isAvailable()).isTrue();
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(
- eq(KEY_EXPOSURE_CHANGES_CATEGORY), anyBoolean());
- }
-
- @Test
- public void testIsAvailableForSearch() {
- final ExposureChangesCategoryPreferenceController controller
- = new ExposureChangesCategoryPreferenceController(mContext, null /* lifecycle */,
- mControllers, false /* controllingUi */);
- controller.setAvailabilityObserver(mObserver);
- verify(mControllers.get(0)).setAvailabilityObserver(controller);
- verify(mControllers.get(1)).setAvailabilityObserver(controller);
-
- assertThat(controller.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_EXPOSURE_CHANGES_CATEGORY, false);
- reset(mObserver);
-
- controller.onPreferenceAvailabilityUpdated(KEY_1, true);
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(
- eq(KEY_EXPOSURE_CHANGES_CATEGORY), anyBoolean());
- assertThat(controller.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_EXPOSURE_CHANGES_CATEGORY, true);
- reset(mObserver);
-
- controller.onPreferenceAvailabilityUpdated(KEY_2, true);
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(
- eq(KEY_EXPOSURE_CHANGES_CATEGORY), anyBoolean());
- assertThat(controller.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_EXPOSURE_CHANGES_CATEGORY, true);
- reset(mObserver);
-
- controller.onPreferenceAvailabilityUpdated(KEY_1, false);
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(
- eq(KEY_EXPOSURE_CHANGES_CATEGORY), anyBoolean());
- assertThat(controller.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_EXPOSURE_CHANGES_CATEGORY, true);
- reset(mObserver);
-
- controller.onPreferenceAvailabilityUpdated(KEY_2, false);
- verify(mObserver, never()).onPreferenceAvailabilityUpdated(
- eq(KEY_EXPOSURE_CHANGES_CATEGORY), anyBoolean());
- assertThat(controller.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_EXPOSURE_CHANGES_CATEGORY, false);
- }
-
- @Test
- public void testHandlePreferenceTreeClick() {
- assertThat(mController.handlePreferenceTreeClick(new Preference(mContext, null, 0, 0)))
- .isFalse();
- }
-
- @Test
- public void testGetPreferenceKey() {
- assertThat(mController.getPreferenceKey()).isEqualTo(KEY_EXPOSURE_CHANGES_CATEGORY);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeCurrentUserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeCurrentUserPreferenceControllerTest.java
index db9182b..8453d62 100644
--- a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeCurrentUserPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeCurrentUserPreferenceControllerTest.java
@@ -16,14 +16,14 @@
package com.android.settings.enterprise;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import static org.mockito.Mockito.when;
+
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
-import static org.mockito.Mockito.when;
-
/**
* Tests for {@link FailedPasswordWipeCurrentUserPreferenceController}.
*/
@@ -32,8 +32,6 @@
public final class FailedPasswordWipeCurrentUserPreferenceControllerTest extends
FailedPasswordWipePreferenceControllerTestBase {
- private int mMaximumFailedPasswordsBeforeWipe = 0;
-
public FailedPasswordWipeCurrentUserPreferenceControllerTest() {
super("failed_password_wipe_current_user");
}
@@ -41,8 +39,7 @@
@Override
public void setUp() {
super.setUp();
- mController = new FailedPasswordWipeCurrentUserPreferenceController(mContext,
- null /* lifecycle */);
+ mController = new FailedPasswordWipeCurrentUserPreferenceController(mContext);
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceControllerTest.java
index 329c526..a001a9c 100644
--- a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceControllerTest.java
@@ -16,14 +16,14 @@
package com.android.settings.enterprise;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import static org.mockito.Mockito.when;
+
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
-import static org.mockito.Mockito.when;
-
/**
* Tests for {@link FailedPasswordWipeManagedProfilePreferenceController}.
*/
@@ -32,8 +32,6 @@
public final class FailedPasswordWipeManagedProfilePreferenceControllerTest extends
FailedPasswordWipePreferenceControllerTestBase {
- private int mMaximumFailedPasswordsBeforeWipe = 0;
-
public FailedPasswordWipeManagedProfilePreferenceControllerTest() {
super("failed_password_wipe_managed_profile");
}
@@ -41,8 +39,7 @@
@Override
public void setUp() {
super.setUp();
- mController = new FailedPasswordWipeManagedProfilePreferenceController(mContext,
- null /* lifecycle */);
+ mController = new FailedPasswordWipeManagedProfilePreferenceController(mContext);
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBaseTest.java
index 5d1b28a..f80667c 100644
--- a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBaseTest.java
@@ -16,8 +16,8 @@
package com.android.settings.enterprise;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
@@ -50,8 +50,7 @@
private class FailedPasswordWipePreferenceControllerBaseTestable extends
FailedPasswordWipePreferenceControllerBase {
FailedPasswordWipePreferenceControllerBaseTestable() {
- super(FailedPasswordWipePreferenceControllerBaseTest.this.mContext,
- null /* lifecycle */);
+ super(FailedPasswordWipePreferenceControllerBaseTest.this.mContext);
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerTestBase.java b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerTestBase.java
index cbc220f..fe4fb6b 100644
--- a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerTestBase.java
+++ b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerTestBase.java
@@ -16,12 +16,13 @@
package com.android.settings.enterprise;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
-import android.content.res.Resources;
import android.support.v7.preference.Preference;
import com.android.settings.R;
-import com.android.settings.core.PreferenceAvailabilityObserver;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
@@ -30,10 +31,6 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* Common base for testing subclasses of {@link FailedPasswordWipePreferenceControllerBase}.
*/
@@ -44,7 +41,6 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
protected Context mContext;
protected FakeFeatureFactory mFeatureFactory;
- @Mock private PreferenceAvailabilityObserver mObserver;
protected FailedPasswordWipePreferenceControllerBase mController;
@@ -59,12 +55,6 @@
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
}
- @Test
- public void testGetAvailabilityObserver() {
- mController.setAvailabilityObserver(mObserver);
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
- }
-
public abstract void setMaximumFailedPasswordsBeforeWipe(int maximum);
@Test
@@ -81,15 +71,11 @@
@Test
public void testIsAvailable() {
- mController.setAvailabilityObserver(mObserver);
-
setMaximumFailedPasswordsBeforeWipe(0);
assertThat(mController.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(mKey, false);
setMaximumFailedPasswordsBeforeWipe(10);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(mKey, true);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceControllerTest.java
index d5ce102..b9c24bf 100644
--- a/tests/robotests/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceControllerTest.java
@@ -16,13 +16,15 @@
package com.android.settings.enterprise;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.support.v7.preference.Preference;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
-import com.android.settings.core.PreferenceAvailabilityObserver;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
@@ -32,10 +34,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* Tests for {@link GlobalHttpProxyPreferenceController}.
*/
@@ -48,7 +46,6 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
- @Mock private PreferenceAvailabilityObserver mObserver;
private GlobalHttpProxyPreferenceController mController;
@@ -57,13 +54,7 @@
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
- mController = new GlobalHttpProxyPreferenceController(mContext, null /* lifecycle */);
- mController.setAvailabilityObserver(mObserver);
- }
-
- @Test
- public void testGetAvailabilityObserver() {
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
+ mController = new GlobalHttpProxyPreferenceController(mContext);
}
@Test
@@ -71,12 +62,10 @@
when(mFeatureFactory.enterprisePrivacyFeatureProvider.isGlobalHttpProxySet())
.thenReturn(false);
assertThat(mController.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_GLOBAL_HTTP_PROXY, false);
when(mFeatureFactory.enterprisePrivacyFeatureProvider.isGlobalHttpProxySet())
.thenReturn(true);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_GLOBAL_HTTP_PROXY, true);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java
index 22d2a7d..1e05383 100644
--- a/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java
@@ -16,15 +16,16 @@
package com.android.settings.enterprise;
-import android.content.Context;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
-import com.android.settings.R;
+import android.content.Context;
import android.support.v7.preference.Preference;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.R;
import com.android.settings.TestConfig;
-import com.android.settings.core.PreferenceAvailabilityObserver;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
@@ -34,10 +35,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* Tests for {@link ImePreferenceController}.
*/
@@ -52,7 +49,6 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
- @Mock private PreferenceAvailabilityObserver mObserver;
private ImePreferenceController mController;
@@ -61,15 +57,9 @@
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
- mController = new ImePreferenceController(mContext, null /* lifecycle */);
+ mController = new ImePreferenceController(mContext);
when(mContext.getResources().getString(R.string.enterprise_privacy_input_method_name,
DEFAULT_IME_LABEL)).thenReturn(DEFAULT_IME_TEXT);
- mController.setAvailabilityObserver(mObserver);
- }
-
- @Test
- public void testGetAvailabilityObserver() {
- assertThat(mController.getAvailabilityObserver()).isEqualTo(mObserver);
}
@Test
@@ -77,7 +67,7 @@
final Preference preference = new Preference(mContext, null, 0, 0);
when(mFeatureFactory.enterprisePrivacyFeatureProvider.getImeLabelIfOwnerSet())
- .thenReturn(DEFAULT_IME_LABEL);
+ .thenReturn(DEFAULT_IME_LABEL);
mController.updateState(preference);
assertThat(preference.getSummary()).isEqualTo(DEFAULT_IME_TEXT);
}
@@ -85,14 +75,12 @@
@Test
public void testIsAvailable() {
when(mFeatureFactory.enterprisePrivacyFeatureProvider.getImeLabelIfOwnerSet())
- .thenReturn(null);
+ .thenReturn(null);
assertThat(mController.isAvailable()).isFalse();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_INPUT_METHOD, false);
when(mFeatureFactory.enterprisePrivacyFeatureProvider.getImeLabelIfOwnerSet())
- .thenReturn(DEFAULT_IME_LABEL);
+ .thenReturn(DEFAULT_IME_LABEL);
assertThat(mController.isAvailable()).isTrue();
- verify(mObserver).onPreferenceAvailabilityUpdated(KEY_INPUT_METHOD, true);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
index e434bb3..719cc33 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
@@ -17,7 +17,10 @@
package com.android.settings.fuelgauge;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
@@ -90,7 +93,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mContext = spy(RuntimeEnvironment.application);
mBatteryMeterView = new BatteryMeterView(mContext);
mBatteryPercentText = new TextView(mContext);
@@ -170,7 +173,7 @@
.thenReturn(mEntityHeaderController);
mController.displayPreference(mPreferenceScreen);
- mLifecycle.onStart();
+ mLifecycle.handleLifecycleEvent(ON_START);
verify(mEntityHeaderController).styleActionBar(mActivity);
}
diff --git a/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java
index 61b6909..df438c1 100644
--- a/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java
@@ -16,14 +16,21 @@
package com.android.settings.gestures;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.TwoStatePreference;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.widget.VideoPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -33,19 +40,11 @@
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class GesturePreferenceControllerTest {
@@ -55,12 +54,17 @@
private PreferenceScreen mScreen;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Lifecycle mLifecycle;
+
private TestPrefController mController;
+ private Preference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new TestPrefController(mContext, mLifecycle);
+ mPreference = new Preference(RuntimeEnvironment.application);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
}
@Test
@@ -70,20 +74,16 @@
mController.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isTrue();
}
@Test
public void display_configIsFalse_shouldNotDisplay() {
mController.mIsPrefAvailable = false;
- final Preference preference = mock(Preference.class);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(preference);
- when(preference.getKey()).thenReturn(mController.getPreferenceKey());
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java b/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java
index 9cc20d6..141d59d 100644
--- a/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java
@@ -59,7 +59,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
@@ -210,7 +209,7 @@
}
@Override
- protected Lifecycle getLifecycle() {
+ public Lifecycle getLifecycle() {
if (mLifecycle == null) {
return super.getLifecycle();
}
diff --git a/tests/robotests/src/com/android/settings/language/TtsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/language/TtsPreferenceControllerTest.java
index e4b3cf2..88a3bcb 100644
--- a/tests/robotests/src/com/android/settings/language/TtsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/language/TtsPreferenceControllerTest.java
@@ -16,14 +16,18 @@
package com.android.settings.language;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TtsEngines;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-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;
@@ -31,19 +35,14 @@
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class TtsPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -54,21 +53,28 @@
private PreferenceScreen mScreen;
private TtsPreferenceController mController;
+ private Preference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new TtsPreferenceController(mContext, mTtsEngines);
+ mPreference = new Preference(RuntimeEnvironment.application);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
}
@Test
public void testIsAvailable_ttsEngineEmpty_shouldReturnFalse() {
-
// Not available when there is no engine.
when(mTtsEngines.getEngines()).thenReturn(new ArrayList<>());
assertThat(mController.isAvailable()).isFalse();
+
+ mController.displayPreference(mScreen);
+
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
@@ -78,21 +84,9 @@
when(mTtsEngines.getEngines()).thenReturn(infolist);
assertThat(mController.isAvailable()).isTrue();
- }
-
- @Test
- public void displayPreference_notAvailable_shouldRemoveCategory() {
- final Preference preference = mock(Preference.class);
- final Preference category = mock(Preference.class);
- when(mScreen.getPreferenceCount()).thenReturn(2);
- when(mScreen.getPreference(0)).thenReturn(preference);
- when(mScreen.getPreference(1)).thenReturn(category);
- when(preference.getKey()).thenReturn(mController.getPreferenceKey());
- when(category.getKey()).thenReturn("voice_category");
mController.displayPreference(mScreen);
- // Remove preference.
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isTrue();
}
}
diff --git a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java
new file mode 100644
index 0000000..1ee52ca
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.localepicker;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowSettingsPreferenceFragment;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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,
+ shadows = { ShadowSettingsPreferenceFragment.class })
+public class LocaleListEditorTest {
+
+ private LocaleListEditor mLocaleListEditor;
+
+ @Before
+ public void setUp() {
+ mLocaleListEditor = new LocaleListEditor();
+ ReflectionHelpers.setField(mLocaleListEditor, "mEmptyTextView",
+ new TextView(RuntimeEnvironment.application));
+ ReflectionHelpers.setField(mLocaleListEditor, "mRestrictionsManager",
+ RuntimeEnvironment.application.getSystemService(Context.RESTRICTIONS_SERVICE));
+ ReflectionHelpers.setField(mLocaleListEditor, "mUserManager",
+ RuntimeEnvironment.application.getSystemService(Context.USER_SERVICE));
+ }
+
+ @Test
+ public void testDisallowConfigLocale_unrestrict() {
+ ReflectionHelpers.setField(mLocaleListEditor, "mIsUiRestricted", true);
+ mLocaleListEditor.onResume();
+ Assert.assertEquals(View.GONE, mLocaleListEditor.getEmptyTextView().getVisibility());
+ }
+
+ @Test
+ public void testDisallowConfigLocale_restrict() {
+ ReflectionHelpers.setField(mLocaleListEditor, "mIsUiRestricted", false);
+ mLocaleListEditor.onResume();
+ Assert.assertEquals(View.VISIBLE, mLocaleListEditor.getEmptyTextView().getVisibility());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java
index 602bbd1..61a9038 100644
--- a/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java
@@ -1,70 +1,52 @@
package com.android.settings.location;
+import static com.google.common.truth.Truth.assertThat;
+
import android.content.Context;
import android.provider.Settings;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-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;
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 static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class AppLocationPermissionPreferenceControllerTest {
- @Mock
- private Preference mPreference;
- @Mock(answer = RETURNS_DEEP_STUBS)
- private PreferenceScreen mScreen;
private AppLocationPermissionPreferenceController mController;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ @Mock
private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(mScreen.findPreference(anyString())).thenReturn(mPreference);
+ mContext = RuntimeEnvironment.application;
mController = new AppLocationPermissionPreferenceController(mContext);
}
@Test
- public void displayPreference_shouldRemovePreference() {
+ public void isAvailable_noLocationLinkPermission_shouldReturnFalse() {
Settings.System.putInt(mContext.getContentResolver(),
android.provider.Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED,
0);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(mPreference);
- when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
- mController.displayPreference(mScreen);
-
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mController.isAvailable()).isFalse();
}
@Test
- public void displayPreference_shouldNotRemovePreference() {
+ public void displayPreference_hasLocationLinkPermission_shouldReturnTrue() {
Settings.System.putInt(mContext.getContentResolver(),
android.provider.Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED,
1);
- mController.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(any(Preference.class));
+ assertThat(mController.isAvailable()).isTrue();
}
-
}
diff --git a/tests/robotests/src/com/android/settings/location/BluetoothScanningPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/BluetoothScanningPreferenceControllerTest.java
new file mode 100644
index 0000000..ffbf530
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/BluetoothScanningPreferenceControllerTest.java
@@ -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.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class BluetoothScanningPreferenceControllerTest {
+
+ @Mock
+ private SwitchPreference mPreference;
+
+ private Context mContext;
+ private BluetoothScanningPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mController = new BluetoothScanningPreferenceController(mContext);
+ when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+ }
+
+ @Test
+ public void updateState_bluetoothScanningEnabled_shouldCheckedPreference() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 1);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setChecked(true);
+ }
+
+ @Test
+ public void updateState_bluetoothScanningDisabled_shouldUncheckedPreference() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setChecked(false);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_checked_shouldEnableBluetoothScanning() {
+ when(mPreference.isChecked()).thenReturn(true);
+
+ mController.handlePreferenceTreeClick(mPreference);
+
+ assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0)).isEqualTo(1);
+
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_unchecked_shouldDisableBluetoothScanning() {
+ when(mPreference.isChecked()).thenReturn(false);
+
+ mController.handlePreferenceTreeClick(mPreference);
+
+ assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 1)).isEqualTo(0);
+
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java b/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
new file mode 100644
index 0000000..01aadc2
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
@@ -0,0 +1,220 @@
+/*
+ * 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.location;
+
+import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+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.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class LocationEnablerTest {
+
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private LocationEnabler.LocationModeChangeListener mListener;
+
+ private Context mContext;
+ private LocationEnabler mEnabler;
+ private Lifecycle mLifecycle;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ mEnabler = spy(new LocationEnabler(mContext, mListener, mLifecycle));
+ }
+
+ @Test
+ public void onResume_shouldSetActiveAndRegisterListener() {
+ mEnabler.onResume();
+
+ verify(mContext).registerReceiver(eq(mEnabler.mReceiver),
+ eq(mEnabler.INTENT_FILTER_LOCATION_MODE_CHANGED));
+ }
+
+ @Test
+ public void onResume_shouldRefreshLocationMode() {
+ mEnabler.onResume();
+
+ verify(mEnabler).refreshLocationMode();
+ }
+
+ @Test
+ public void onPause_shouldUnregisterListener() {
+ mEnabler.onPause();
+
+ verify(mContext).unregisterReceiver(mEnabler.mReceiver);
+ }
+
+ @Test
+ public void onReceive_shouldRefreshLocationMode() {
+ mEnabler.onResume();
+ reset(mListener);
+ mEnabler.mReceiver.onReceive(mContext, new Intent());
+
+ verify(mListener).onLocationModeChanged(anyInt(), anyBoolean());
+ }
+
+ @Test
+ public void isEnabled_locationOff_shouldReturnFalse() {
+ assertThat(mEnabler.isEnabled(Settings.Secure.LOCATION_MODE_OFF)).isFalse();
+ }
+
+ @Test
+ public void isEnabled_restricted_shouldReturnFalse() {
+ when(mUserManager.hasUserRestriction(anyString())).thenReturn(true);
+
+ assertThat(mEnabler.isEnabled(Settings.Secure.LOCATION_MODE_OFF)).isFalse();
+ }
+
+ @Test
+ public void isEnabled_locationONotRestricted_shouldReturnTrue() {
+ when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
+
+ assertThat(mEnabler.isEnabled(Settings.Secure.LOCATION_MODE_BATTERY_SAVING)).isTrue();
+ }
+
+ @Test
+ public void refreshLocationMode_shouldCallOnLocationModeChanged() {
+ mEnabler.refreshLocationMode();
+
+ verify(mListener).onLocationModeChanged(anyInt(), anyBoolean());
+ }
+
+ @Test
+ public void setLocationMode_restricted_shouldSetCurrentMode() {
+ when(mUserManager.hasUserRestriction(anyString())).thenReturn(true);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
+
+ mEnabler.setLocationMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
+
+ verify(mListener)
+ .onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, true);
+ }
+
+ @Test
+ public void setLocationMode_notRestricted_shouldUpdateSecureSettings() {
+ when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
+
+ mEnabler.setLocationMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
+
+ assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING))
+ .isEqualTo(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
+ }
+
+ @Test
+ public void setLocationMode_notRestricted_shouldRefreshLocation() {
+ when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
+
+ mEnabler.setLocationMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
+
+ verify(mEnabler).refreshLocationMode();
+ }
+
+ @Test
+ public void setLocationMode_notRestricted_shouldBroadcastUpdate() {
+ when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
+
+ mEnabler.setLocationMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
+
+ verify(mContext).sendBroadcast(argThat(actionMatches(mEnabler.MODE_CHANGING_ACTION)),
+ eq(WRITE_SECURE_SETTINGS));
+ }
+
+ @Test
+ public void isManagedProfileRestrictedByBase_notManagedProfile_shouldReturnFalse() {
+ assertThat(mEnabler.isManagedProfileRestrictedByBase()).isFalse();
+ }
+
+ @Test
+ public void isManagedProfileRestrictedByBase_notRestricted_shouldReturnFalse() {
+ mockManagedProfile();
+ doReturn(false).when(mEnabler).hasShareLocationRestriction(anyInt());
+
+ assertThat(mEnabler.isManagedProfileRestrictedByBase()).isFalse();
+ }
+
+ @Test
+ public void isManagedProfileRestrictedByBase_hasManagedProfile_shouldReturnFalse() {
+ mockManagedProfile();
+ doReturn(true).when(mEnabler).hasShareLocationRestriction(anyInt());
+
+ assertThat(mEnabler.isManagedProfileRestrictedByBase()).isTrue();
+ }
+
+ private void mockManagedProfile() {
+ final List<UserHandle> userProfiles = new ArrayList<>();
+ final UserHandle userHandle = mock(UserHandle.class);
+ when(userHandle.getIdentifier()).thenReturn(5);
+ userProfiles.add(userHandle);
+ when(mUserManager.getUserProfiles()).thenReturn(userProfiles);
+ when(mUserManager.getUserHandle()).thenReturn(1);
+ when(mUserManager.getUserInfo(5))
+ .thenReturn(new UserInfo(5, "user 5", UserInfo.FLAG_MANAGED_PROFILE));
+ }
+
+ private static ArgumentMatcher<Intent> actionMatches(String expected) {
+ return intent -> TextUtils.equals(expected, intent.getAction());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/location/LocationForWorkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationForWorkPreferenceControllerTest.java
new file mode 100644
index 0000000..86b9356
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/LocationForWorkPreferenceControllerTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+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.content.Context;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedSwitchPreference;
+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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class LocationForWorkPreferenceControllerTest {
+
+ @Mock
+ private RestrictedSwitchPreference mPreference;
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private LocationEnabler mEnabler;
+ @Mock
+ private UserHandle mUserHandle;
+
+ private Context mContext;
+ private LocationForWorkPreferenceController mController;
+ private Lifecycle mLifecycle;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ mController = spy(new LocationForWorkPreferenceController(mContext, mLifecycle));
+ mockManagedProfile();
+ ReflectionHelpers.setField(mController, "mLocationEnabler", mEnabler);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ final String key = mController.getPreferenceKey();
+ when(mPreference.getKey()).thenReturn(key);
+ when(mPreference.isVisible()).thenReturn(true);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_preferenceChecked_shouldSetRestrictionAndOnSummary() {
+ mController.displayPreference(mScreen);
+ when(mPreference.isChecked()).thenReturn(true);
+
+ mController.handlePreferenceTreeClick(mPreference);
+
+ verify(mUserManager).setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, false,
+ mUserHandle);
+ verify(mPreference).setSummary(R.string.switch_on_text);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_preferenceUnchecked_shouldSetRestritionAndOffSummary() {
+ mController.displayPreference(mScreen);
+ when(mPreference.isChecked()).thenReturn(false);
+
+ mController.handlePreferenceTreeClick(mPreference);
+
+ verify(mUserManager).setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true,
+ mUserHandle);
+ verify(mPreference).setSummary(R.string.switch_off_text);
+ }
+
+ @Test
+ public void isAvailable_noManagedProfile_shouldReturnFalse() {
+ when(mUserManager.getUserProfiles()).thenReturn(new ArrayList<UserHandle>());
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_hasManagedProfile_shouldReturnTrue() {
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void onLocationModeChanged_disabledByAdmin_shouldDisablePreference() {
+ mController.displayPreference(mScreen);
+ final EnforcedAdmin admin = mock(EnforcedAdmin.class);
+ doReturn(admin).when(mEnabler).getShareLocationEnforcedAdmin(anyInt());
+ doReturn(false).when(mEnabler).isManagedProfileRestrictedByBase();
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mPreference).setDisabledByAdmin(any());
+ verify(mPreference).setChecked(false);
+ }
+
+ @Test
+ public void onLocationModeChanged_locationOff_shouldDisablePreference() {
+ mController.displayPreference(mScreen);
+ doReturn(null).when(mEnabler).getShareLocationEnforcedAdmin(anyInt());
+ doReturn(false).when(mEnabler).isManagedProfileRestrictedByBase();
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_OFF, false);
+
+ verify(mPreference).setEnabled(false);
+ verify(mPreference).setChecked(false);
+ verify(mPreference).setSummary(R.string.switch_off_text);
+ }
+
+ @Test
+ public void onLocationModeChanged_locationOn_shouldEnablePreference() {
+ mController.displayPreference(mScreen);
+ doReturn(null).when(mEnabler).getShareLocationEnforcedAdmin(anyInt());
+ doReturn(false).when(mEnabler).isManagedProfileRestrictedByBase();
+ doReturn(true).when(mEnabler).isEnabled(anyInt());
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mPreference).setEnabled(true);
+ verify(mPreference).setSummary(R.string.switch_on_text);
+ }
+
+ @Test
+ public void onLocationModeChanged_noRestriction_shouldCheckedPreference() {
+ mController.displayPreference(mScreen);
+ doReturn(null).when(mEnabler).getShareLocationEnforcedAdmin(anyInt());
+ doReturn(false).when(mEnabler).isManagedProfileRestrictedByBase();
+ doReturn(true).when(mEnabler).isEnabled(anyInt());
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mPreference).setChecked(true);
+ }
+
+ @Test
+ public void onLocationModeChanged_hasRestriction_shouldCheckedPreference() {
+ mController.displayPreference(mScreen);
+ doReturn(null).when(mEnabler).getShareLocationEnforcedAdmin(anyInt());
+ doReturn(true).when(mEnabler).isManagedProfileRestrictedByBase();
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mPreference).setChecked(false);
+ }
+
+ private void mockManagedProfile() {
+ final List<UserHandle> userProfiles = new ArrayList<>();
+ when(mUserHandle.getIdentifier()).thenReturn(5);
+ userProfiles.add(mUserHandle);
+ when(mUserManager.getUserProfiles()).thenReturn(userProfiles);
+ when(mUserManager.getUserHandle()).thenReturn(1);
+ when(mUserManager.getUserInfo(5))
+ .thenReturn(new UserInfo(5, "user 5", UserInfo.FLAG_MANAGED_PROFILE));
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/location/LocationModeBatterySavingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationModeBatterySavingPreferenceControllerTest.java
new file mode 100644
index 0000000..3529a7c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/LocationModeBatterySavingPreferenceControllerTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.provider.Settings;
+
+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.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class LocationModeBatterySavingPreferenceControllerTest {
+
+ private Lifecycle mLifecycle;
+
+ @Before
+ public void setUp() {
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ }
+
+ @Test
+ public void getLocationMode_shouldReturnModeBatterySaving() {
+ final LocationModeBatterySavingPreferenceController controller =
+ new LocationModeBatterySavingPreferenceController(mock(Context.class), mLifecycle);
+
+ assertThat(controller.getLocationMode())
+ .isEqualTo(Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/location/LocationModeHighAccuracyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationModeHighAccuracyPreferenceControllerTest.java
new file mode 100644
index 0000000..0608a68
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/LocationModeHighAccuracyPreferenceControllerTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.provider.Settings;
+
+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.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class LocationModeHighAccuracyPreferenceControllerTest {
+
+ private Lifecycle mLifecycle;
+
+ @Before
+ public void setUp() {
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ }
+
+ @Test
+ public void getLocationMode_shouldReturnModeHighAccuracy() {
+ final LocationModeHighAccuracyPreferenceController controller =
+ new LocationModeHighAccuracyPreferenceController(mock(Context.class), mLifecycle);
+
+ assertThat(controller.getLocationMode())
+ .isEqualTo(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/location/LocationModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationModePreferenceControllerTest.java
new file mode 100644
index 0000000..b870d39
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/LocationModePreferenceControllerTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.location;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.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.os.UserManager;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+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;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class LocationModePreferenceControllerTest {
+
+ @Mock
+ private LocationSettings mFragment;
+ @Mock
+ private SettingsActivity mActivity;
+ @Mock
+ private Preference mPreference;
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private UserManager mUserManager;
+
+ private Context mContext;
+ private LocationModePreferenceController mController;
+ private Lifecycle mLifecycle;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ mController = new LocationModePreferenceController(mContext, mFragment, mLifecycle);
+ when(mFragment.getActivity()).thenReturn(mActivity);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ }
+
+ @Test
+ public void onLocationModeChanged_locationOff_shouldDisablePreference() {
+ when(mUserManager.hasUserRestriction(any())).thenReturn(false);
+ mController.displayPreference(mScreen);
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_OFF, false);
+
+ verify(mPreference).setEnabled(false);
+ }
+
+ @Test
+ public void onLocationModeChanged_restricted_shouldDisablePreference() {
+ when(mUserManager.hasUserRestriction(any())).thenReturn(true);
+ mController.displayPreference(mScreen);
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mPreference).setEnabled(false);
+ }
+
+ @Test
+ public void onLocationModeChanged_locationOnNotRestricted_shouldEnablePreference() {
+ when(mUserManager.hasUserRestriction(any())).thenReturn(false);
+ mController.displayPreference(mScreen);
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mPreference).setEnabled(true);
+ }
+
+ @Test
+ public void onLocationModeChanged_shouldUpdateSummary() {
+ mController.displayPreference(mScreen);
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mPreference).setSummary(anyInt());
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_shouldStartLocationModeFragment() {
+ final Preference preference = new Preference(mContext);
+ preference.setKey(mController.getPreferenceKey());
+
+ mController.handlePreferenceTreeClick(preference);
+
+ verify(mActivity).startPreferencePanel(any(), eq(LocationMode.class.getName()), any(),
+ eq(R.string.location_mode_screen_title), any(), any(), anyInt());
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/location/LocationModeRadioButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationModeRadioButtonPreferenceControllerTest.java
new file mode 100644
index 0000000..69297dad
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/LocationModeRadioButtonPreferenceControllerTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.widget.RadioButtonPreference;
+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.annotation.Config;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class LocationModeRadioButtonPreferenceControllerTest {
+
+ @Mock
+ private RadioButtonPreference mPreference;
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private Context mContext;
+ private LocationModeRadioButtonPreferenceController mController;
+ private Lifecycle mLifecycle;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ mController = new LocationModeRadioButtonPreferenceControllerTestable(mContext, mLifecycle);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ }
+
+ @Test
+ public void displayPreference_shouldAddClickListener() {
+ mController.displayPreference(mScreen);
+
+ verify(mPreference).setOnClickListener(mController);
+ }
+
+ @Test
+ public void onRadioButtonClicked_shouldSetLocationModeToOwnMode() {
+ mController.displayPreference(mScreen);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
+
+ mController.onRadioButtonClicked(mPreference);
+
+ assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF))
+ .isEqualTo(mController.getLocationMode());
+ }
+
+ @Test
+ public void onLocationModeChanged_otherModeSelected_shouldUncheckPreference() {
+ mController.displayPreference(mScreen);
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mPreference).setChecked(false);
+ }
+
+ @Test
+ public void onLocationModeChanged_ownModeSelected_shouldCheckPreference() {
+ mController.displayPreference(mScreen);
+
+ mController.onLocationModeChanged(mController.getLocationMode(), false);
+
+ verify(mPreference).setChecked(true);
+ }
+
+ @Test
+ public void onLocationModeChanged_locationOff_shouldDisablePreference() {
+ mController.displayPreference(mScreen);
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_OFF, false);
+
+ verify(mPreference).setEnabled(false);
+ }
+
+ @Test
+ public void onLocationModeChanged_locationOn_shouldDisablePreference() {
+ mController.displayPreference(mScreen);
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mPreference).setEnabled(true);
+ }
+
+ private class LocationModeRadioButtonPreferenceControllerTestable
+ extends LocationModeRadioButtonPreferenceController {
+
+ public LocationModeRadioButtonPreferenceControllerTestable(Context context,
+ Lifecycle lifecycle) {
+ super(context, lifecycle);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return "test";
+ }
+
+ @Override
+ protected int getLocationMode() {
+ return Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceControllerTest.java
new file mode 100644
index 0000000..374e118
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceControllerTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.provider.Settings;
+
+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.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class LocationModeSensorsOnlyPreferenceControllerTest {
+
+ private Lifecycle mLifecycle;
+
+ @Before
+ public void setUp() {
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ }
+
+ @Test
+ public void getLocationMode_shouldReturnModeSensorsOnly() {
+ final LocationModeSensorsOnlyPreferenceController controller =
+ new LocationModeSensorsOnlyPreferenceController(mock(Context.class), mLifecycle);
+
+ assertThat(controller.getLocationMode())
+ .isEqualTo(Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java
index 355d6d0..fe45a93 100644
--- a/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java
@@ -15,7 +15,11 @@
*/
package com.android.settings.location;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify;
@@ -67,7 +71,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mController = new LocationPreferenceController(mContext, mLifecycle);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
}
@@ -145,13 +149,14 @@
@Test
public void onResume_shouldRegisterObserver() {
- mLifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
}
@Test
public void onPause_shouldUnregisterObserver() {
- mLifecycle.onPause();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
+ mLifecycle.handleLifecycleEvent(ON_PAUSE);
verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
}
diff --git a/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java
new file mode 100644
index 0000000..46fba95
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+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.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceScreen;
+
+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.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class LocationServicePreferenceControllerTest {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private LocationSettings mFragment;
+ @Mock
+ private PreferenceCategory mCategory;
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private SettingsInjector mSettingsInjector;
+
+ private Context mContext;
+ private LocationServicePreferenceController mController;
+ private Lifecycle mLifecycle;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ mController = spy(new LocationServicePreferenceController(
+ mContext, mFragment, mLifecycle, mSettingsInjector));
+ final String key = mController.getPreferenceKey();
+ when(mScreen.findPreference(key)).thenReturn(mCategory);
+ when(mCategory.getKey()).thenReturn(key);
+ }
+
+ @Test
+ public void isAvailable_noInjectedSettings_shouldReturnFalse() {
+ doReturn(false).when(mSettingsInjector).hasInjectedSettings(anyInt());
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_hasInjectedSettings_shouldReturnFalse() {
+ doReturn(true).when(mSettingsInjector).hasInjectedSettings(anyInt());
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void onResume_shouldRegisterListener() {
+ mController.onResume();
+
+ verify(mContext).registerReceiver(eq(mController.mInjectedSettingsReceiver),
+ eq(mController.INTENT_FILTER_INJECTED_SETTING_CHANGED));
+ }
+
+ @Test
+ public void onPause_shouldUnregisterListener() {
+ mController.onResume();
+ mController.onPause();
+
+ verify(mContext).unregisterReceiver(mController.mInjectedSettingsReceiver);
+ }
+
+ @Test
+ public void updateState_shouldRemoveAllAndAddInjectedSettings() {
+ final List<Preference> preferences = new ArrayList<>();
+ final Preference pref1 = new Preference(mContext);
+ pref1.setTitle("Title1");
+ final Preference pref2 = new Preference(mContext);
+ pref2.setTitle("Title2");
+ preferences.add(pref1);
+ preferences.add(pref2);
+ doReturn(preferences).when(mSettingsInjector)
+ .getInjectedSettings(any(Context.class), anyInt());
+ when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
+ mController.displayPreference(mScreen);
+
+ mController.updateState(mCategory);
+
+ verify(mCategory).removeAll();
+ verify(mCategory).addPreference(pref1);
+ verify(mCategory).addPreference(pref2);
+ }
+
+ @Test
+ public void onLocationModeChanged_shouldRequestReloadInjectedSettigns() {
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mSettingsInjector).reloadStatusMessages();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/location/LocationSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationSwitchBarControllerTest.java
new file mode 100644
index 0000000..9eb69a4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/LocationSwitchBarControllerTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.location;
+
+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.content.Context;
+import android.provider.Settings;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.widget.SwitchBar;
+import com.android.settings.widget.ToggleSwitch;
+import com.android.settingslib.RestrictedLockUtils;
+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_O)
+public class LocationSwitchBarControllerTest {
+
+ @Mock
+ private SwitchBar mSwitchBar;
+ @Mock
+ private ToggleSwitch mSwitch;
+ @Mock
+ private LocationEnabler mEnabler;
+
+ private Context mContext;
+ private LocationSwitchBarController mController;
+ private Lifecycle mLifecycle;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ ReflectionHelpers.setField(mSwitchBar, "mSwitch", mSwitch);
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ mController = spy(new LocationSwitchBarController(
+ mContext, mSwitchBar, mLifecycle));
+ ReflectionHelpers.setField(mController, "mLocationEnabler", mEnabler);
+ }
+
+ @Test
+ public void onStart_shouldShowSwitchBarAndAddOnSwitchChangeListener() {
+ mController.onStart();
+
+ verify(mSwitchBar).show();
+ verify(mSwitchBar).addOnSwitchChangeListener(mController);
+ }
+
+ @Test
+ public void onStop_shouldHideSwitchBarAndRemoveOnSwitchChangeListener() {
+ mController.onStart();
+ mController.onStop();
+
+ verify(mSwitchBar).hide();
+ verify(mSwitchBar).removeOnSwitchChangeListener(mController);
+ }
+
+ @Test
+ public void onSwitchChanged_switchChecked_shouldSetPreviousLocationMode() {
+ mController.onSwitchChanged(mSwitch, true);
+
+ verify(mEnabler).setLocationMode(
+ android.provider.Settings.Secure.LOCATION_MODE_PREVIOUS);
+ }
+
+ @Test
+ public void onSwitchChanged_switchUnchecked_shouldSetLocationModeOff() {
+ mController.onSwitchChanged(mSwitch, false);
+
+ verify(mEnabler).setLocationMode(android.provider.Settings.Secure.LOCATION_MODE_OFF);
+ }
+
+ @Test
+ public void onLocationModeChanged_hasEnforcedAdmin_shouldDisableSwitchByAdmin() {
+ final RestrictedLockUtils.EnforcedAdmin admin =
+ mock(RestrictedLockUtils.EnforcedAdmin.class);
+ doReturn(admin).when(mEnabler).getShareLocationEnforcedAdmin(anyInt());
+ doReturn(false).when(mEnabler).hasShareLocationRestriction(anyInt());
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mSwitchBar).setDisabledByAdmin(admin);
+ }
+
+ @Test
+ public void onLocationModeChanged_Restricted_shouldDisableSwitch() {
+ doReturn(null).when(mEnabler).getShareLocationEnforcedAdmin(anyInt());
+ doReturn(true).when(mEnabler).hasShareLocationRestriction(anyInt());
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, true);
+
+ verify(mSwitchBar).setEnabled(false);
+ }
+
+ @Test
+ public void onLocationModeChanged_notRestricted_shouldEnableSwitch() {
+ doReturn(null).when(mEnabler).getShareLocationEnforcedAdmin(anyInt());
+ doReturn(false).when(mEnabler).hasShareLocationRestriction(anyInt());
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mSwitchBar).setEnabled(true);
+ }
+
+ @Test
+ public void onLocationModeChanged_locationOn_shouldCheckSwitch() {
+ doReturn(null).when(mEnabler).getShareLocationEnforcedAdmin(anyInt());
+ doReturn(false).when(mEnabler).hasShareLocationRestriction(anyInt());
+ when(mSwitch.isChecked()).thenReturn(false);
+ doReturn(true).when(mEnabler).isEnabled(anyInt());
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mSwitch).setChecked(true);
+ }
+
+ @Test
+ public void onLocationModeChanged_locationOff_shouldUncheckSwitch() {
+ doReturn(null).when(mEnabler).getShareLocationEnforcedAdmin(anyInt());
+ doReturn(false).when(mEnabler).hasShareLocationRestriction(anyInt());
+ when(mSwitch.isChecked()).thenReturn(true);
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_OFF, false);
+
+ verify(mSwitch).setChecked(false);
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java
new file mode 100644
index 0000000..4b3d051
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java
@@ -0,0 +1,178 @@
+/*
+ * 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.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.TestConfig;
+import com.android.settings.applications.InstalledAppDetails;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.widget.AppPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.location.RecentLocationApps;
+import com.android.settingslib.location.RecentLocationApps.Request;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class RecentLocationRequestPreferenceControllerTest {
+
+ @Mock
+ private LocationSettings mFragment;
+ @Mock
+ private PreferenceCategory mCategory;
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private RecentLocationApps mRecentLocationApps;
+
+ private Context mContext;
+ private RecentLocationRequestPreferenceController mController;
+ private Lifecycle mLifecycle;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ mController = spy(new RecentLocationRequestPreferenceController(
+ mContext, mFragment, mLifecycle, mRecentLocationApps));
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mCategory);
+ final String key = mController.getPreferenceKey();
+ when(mCategory.getKey()).thenReturn(key);
+ when(mCategory.getContext()).thenReturn(mContext);
+ }
+
+ @Test
+ public void onLocationModeChanged_LocationOn_shouldEnablePreference() {
+ mController.displayPreference(mScreen);
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
+
+ verify(mCategory).setEnabled(true);
+ }
+
+ @Test
+ public void onLocationModeChanged_LocationOff_shouldDisablePreference() {
+ mController.displayPreference(mScreen);
+
+ mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_OFF, false);
+
+ verify(mCategory).setEnabled(false);
+ }
+
+ @Test
+ public void updateState_noRecentRequest_shouldRemoveAllAndAddBanner() {
+ doReturn(new ArrayList<>()).when(mRecentLocationApps).getAppList();
+ mController.displayPreference(mScreen);
+
+ mController.updateState(mCategory);
+
+ verify(mCategory).removeAll();
+ verify(mCategory).addPreference(
+ argThat(titleMatches(mContext.getString(R.string.location_no_recent_apps))));
+ }
+
+ @Test
+ public void updateState_hasRecentRequest_shouldRemoveAllAndAddInjectedSettings() {
+ final List<RecentLocationApps.Request> requests = new ArrayList<>();
+ final Request req1 = mock(Request.class);
+ final Request req2 = mock(Request.class);
+ requests.add(req1);
+ requests.add(req2);
+ doReturn(requests).when(mRecentLocationApps).getAppList();
+ final String title = "testTitle";
+ final AppPreference preference = mock(AppPreference.class);
+ when(preference.getTitle()).thenReturn(title);
+ doReturn(preference).when(mController)
+ .createAppPreference(any(Context.class), any(Request.class));
+ mController.displayPreference(mScreen);
+
+ mController.updateState(mCategory);
+
+ verify(mCategory).removeAll();
+ verify(mCategory, times(2)).addPreference(argThat(titleMatches(title)));
+ }
+
+ @Test
+ public void createAppPreference_shouldAddClickListener() {
+ final Request request = mock(Request.class);
+ final AppPreference preference = mock(AppPreference.class);
+ doReturn(preference).when(mController)
+ .createAppPreference(any(Context.class));
+
+ mController.createAppPreference(mContext, request);
+
+ verify(preference).setOnPreferenceClickListener(
+ any(RecentLocationRequestPreferenceController.PackageEntryClickedListener.class));
+ }
+
+ @Test
+ public void onPreferenceClick_shouldLaunchAppDetails() {
+ final SettingsActivity activity = mock(SettingsActivity.class);
+ when(mFragment.getActivity()).thenReturn(activity);
+ final List<RecentLocationApps.Request> requests = new ArrayList<>();
+ final Request request = mock(Request.class);
+ requests.add(request);
+ doReturn(requests).when(mRecentLocationApps).getAppList();
+ final AppPreference preference = new AppPreference(mContext);
+ doReturn(preference).when(mController).createAppPreference(any(Context.class));
+ mController.displayPreference(mScreen);
+ mController.updateState(mCategory);
+
+ preference.performClick();
+
+ verify(activity).startPreferencePanelAsUser(any(), eq(InstalledAppDetails.class.getName()),
+ any(Bundle.class), anyInt(), any(), any());
+ }
+
+ private static ArgumentMatcher<Preference> titleMatches(String expected) {
+ return preference -> TextUtils.equals(expected, preference.getTitle());
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/location/ScanningSettingsTest.java b/tests/robotests/src/com/android/settings/location/ScanningSettingsTest.java
index 47b81bf..dff257b 100644
--- a/tests/robotests/src/com/android/settings/location/ScanningSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/location/ScanningSettingsTest.java
@@ -34,13 +34,12 @@
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class ScanningSettingsTest {
private Context mContext;
private ScanningSettings mSettings;
-
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
diff --git a/tests/robotests/src/com/android/settings/location/WifiScanningPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/WifiScanningPreferenceControllerTest.java
new file mode 100644
index 0000000..d8b6b75
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/WifiScanningPreferenceControllerTest.java
@@ -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.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class WifiScanningPreferenceControllerTest {
+
+ @Mock
+ private SwitchPreference mPreference;
+
+ private Context mContext;
+ private WifiScanningPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mController = new WifiScanningPreferenceController(mContext);
+ when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+ }
+
+ @Test
+ public void updateState_wifiScanningEnabled_shouldCheckedPreference() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 1);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setChecked(true);
+ }
+
+ @Test
+ public void updateState_wifiScanningDisabled_shouldUncheckedPreference() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setChecked(false);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_checked_shouldEnableWifiScanning() {
+ when(mPreference.isChecked()).thenReturn(true);
+
+ mController.handlePreferenceTreeClick(mPreference);
+
+ assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0)).isEqualTo(1);
+
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_unchecked_shouldDisableWifiScanning() {
+ when(mPreference.isChecked()).thenReturn(false);
+
+ mController.handlePreferenceTreeClick(mPreference);
+
+ assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 1)).isEqualTo(0);
+
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java
index 1a66dcc..d593b58 100644
--- a/tests/robotests/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java
@@ -15,6 +15,9 @@
*/
package com.android.settings.network;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
@@ -69,7 +72,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
when(mContext.getSystemService(Context.TELEPHONY_SERVICE))
.thenReturn(mTelephonyManager);
}
@@ -104,11 +107,11 @@
mLifecycle.addObserver(mController);
doReturn(true).when(mController).isAvailable();
- mLifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
verify(mTelephonyManager).listen(mController.mPhoneStateListener,
PhoneStateListener.LISTEN_SERVICE_STATE);
- mLifecycle.onPause();
+ mLifecycle.handleLifecycleEvent(ON_PAUSE);
verify(mTelephonyManager).listen(mController.mPhoneStateListener,
PhoneStateListener.LISTEN_NONE);
}
@@ -125,7 +128,7 @@
// Display pref and go through lifecycle to set up listener.
mController.displayPreference(mScreen);
- mLifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
verify(mController).onResume();
verify(mTelephonyManager).listen(mController.mPhoneStateListener,
PhoneStateListener.LISTEN_SERVICE_STATE);
diff --git a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
index fb3e75d..548d144 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
@@ -82,7 +82,9 @@
public void testPrepareActionBar_networkResetShouldBeCreated() {
final NetworkResetActionMenuController resetController =
mock(NetworkResetActionMenuController.class);
+ final PrivateDnsMenuController privateDnsController = mock(PrivateDnsMenuController.class);
ReflectionHelpers.setField(mFragment, "mNetworkResetController", resetController);
+ ReflectionHelpers.setField(mFragment, "mPrivateDnsMenuController", privateDnsController);
mFragment.onCreateOptionsMenu(null, null);
diff --git a/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java b/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java
index 0b2be3a..896e802 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java
@@ -43,6 +43,7 @@
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class NetworkResetActionMenuControllerTest {
+ private static final int MENU_ID = Menu.FIRST;
private Context mContext;
private NetworkResetActionMenuController mController;
@Mock
@@ -56,7 +57,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mController = new NetworkResetActionMenuController(mContext);
+ mController = new NetworkResetActionMenuController(mContext, MENU_ID);
ReflectionHelpers.setField(mController, "mRestrictionChecker", mRestrictionChecker);
when(mMenu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mMenuItem);
}
diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsMenuControllerTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsMenuControllerTest.java
new file mode 100644
index 0000000..0be66e0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/PrivateDnsMenuControllerTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.network;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.FragmentManager;
+import android.view.Menu;
+import android.view.MenuItem;
+
+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.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class PrivateDnsMenuControllerTest {
+ private static final int MENU_ID = 0;
+
+ private PrivateDnsMenuController mController;
+ @Mock
+ private Menu mMenu;
+ @Mock
+ private MenuItem mMenuItem;
+ @Mock
+ private FragmentManager mFragmentManager;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mController = new PrivateDnsMenuController(mFragmentManager, MENU_ID);
+ when(mMenu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mMenuItem);
+ }
+
+ @Test
+ public void buildMenuItem_available_shouldAddToMenu() {
+ mController.buildMenuItem(mMenu);
+
+ verify(mMenu).add(0 /* groupId */, MENU_ID, 0 /* order */,
+ R.string.select_private_dns_configuration_title);
+ verify(mMenuItem).setOnMenuItemClickListener(any(MenuItem.OnMenuItemClickListener.class));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java
new file mode 100644
index 0000000..3468702
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java
@@ -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.network;
+
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class PrivateDnsModeDialogFragmentTest {
+ private static final String HOST_NAME = "192.168.1.1";
+
+ private Context mContext;
+ private PrivateDnsModeDialogFragment mFragment;
+
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ mFragment = spy(new PrivateDnsModeDialogFragment());
+ doReturn(mContext).when(mFragment).getContext();
+ mFragment.onCreateDialog(null);
+ }
+
+ @Test
+ public void testOnCheckedChanged_dnsModeOff_disableEditText() {
+ mFragment.onCheckedChanged(null, R.id.private_dns_mode_off);
+
+ assertThat(mFragment.mMode).isEqualTo(PRIVATE_DNS_MODE_OFF);
+ assertThat(mFragment.mEditText.isEnabled()).isFalse();
+ }
+
+ @Test
+ public void testOnCheckedChanged_dnsModeOpportunistic_disableEditText() {
+ mFragment.onCheckedChanged(null, R.id.private_dns_mode_opportunistic);
+
+ assertThat(mFragment.mMode).isEqualTo(PRIVATE_DNS_MODE_OPPORTUNISTIC);
+ assertThat(mFragment.mEditText.isEnabled()).isFalse();
+ }
+
+ @Test
+ public void testOnCheckedChanged_dnsModeProvider_enableEditText() {
+ mFragment.onCheckedChanged(null, R.id.private_dns_mode_provider);
+
+ assertThat(mFragment.mMode).isEqualTo(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+ assertThat(mFragment.mEditText.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void testOnCreateDialog_containsCorrectData() {
+ Settings.Global.putString(mContext.getContentResolver(),
+ PrivateDnsModeDialogFragment.MODE_KEY, PRIVATE_DNS_MODE_OPPORTUNISTIC);
+ Settings.Global.putString(mContext.getContentResolver(),
+ PrivateDnsModeDialogFragment.HOSTNAME_KEY, HOST_NAME);
+
+ mFragment.onCreateDialog(null);
+
+ assertThat(mFragment.mEditText.getText().toString()).isEqualTo(HOST_NAME);
+ assertThat(mFragment.mRadioGroup.getCheckedRadioButtonId()).isEqualTo(
+ R.id.private_dns_mode_opportunistic);
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java
index b7c4848..c35f1cf 100644
--- a/tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java
@@ -17,6 +17,16 @@
package com.android.settings.network;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
@@ -25,8 +35,8 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -37,13 +47,6 @@
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowServiceManager;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class VpnPreferenceControllerTest {
@@ -74,7 +77,7 @@
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
mController = spy(new VpnPreferenceController(mContext));
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mLifecycle.addObserver(mController);
}
@@ -91,11 +94,11 @@
public void goThroughLifecycle_shouldRegisterUnregisterListener() {
doReturn(true).when(mController).isAvailable();
- mLifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
verify(mConnectivityManager).registerNetworkCallback(
any(NetworkRequest.class), any(ConnectivityManager.NetworkCallback.class));
- mLifecycle.onPause();
+ mLifecycle.handleLifecycleEvent(ON_PAUSE);
verify(mConnectivityManager).unregisterNetworkCallback(
any(ConnectivityManager.NetworkCallback.class));
}
diff --git a/tests/robotests/src/com/android/settings/notification/AllowSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/AllowSoundPreferenceControllerTest.java
new file mode 100644
index 0000000..9ba8706
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/AllowSoundPreferenceControllerTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+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 com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+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.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class AllowSoundPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+
+ @Mock
+ NotificationSettingsBase.ImportanceListener mImportanceListener;
+
+ private AllowSoundPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController =
+ spy(new AllowSoundPreferenceController(mContext, mImportanceListener, mBackend));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(RestrictedSwitchPreference.class));
+ mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
+ }
+
+ @Test
+ public void testIsAvailable_notIfNull() throws Exception {
+ mController.onResume(null, mock(NotificationChannel.class), null, null);
+ assertFalse(mController.isAvailable());
+
+ mController.onResume(mock(NotificationBackend.AppRow.class), null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfAppBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, mock(NotificationChannel.class), null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfAppCreatedChannel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something new");
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_notConfigurable() throws Exception {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_configurable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertTrue(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_checkedForHighImportanceChannel() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+ assertTrue(pref.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_checkedForUnspecifiedImportanceChannel() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_UNSPECIFIED);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+ assertTrue(pref.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_notCheckedForLowImportanceChannel() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+ assertFalse(pref.isChecked());
+ }
+
+ @Test
+ public void testOnPreferenceChange_on() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+ pref.setChecked(true);
+ mController.onPreferenceChange(pref, true);
+
+ assertEquals(IMPORTANCE_UNSPECIFIED, mController.mChannel.getImportance());
+ verify(mImportanceListener, times(1)).onImportanceChanged();
+ }
+
+ @Test
+ public void testOnPreferenceChange_off() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ pref.setChecked(false);
+ mController.onPreferenceChange(pref, false);
+
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ assertEquals(IMPORTANCE_LOW, mController.mChannel.getImportance());
+ verify(mImportanceListener, times(1)).onImportanceChanged();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/AppLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/AppLinkPreferenceControllerTest.java
new file mode 100644
index 0000000..b440704
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/AppLinkPreferenceControllerTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+
+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.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class AppLinkPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+
+ private AppLinkPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new AppLinkPreferenceController(mContext));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(Preference.class));
+ }
+
+ @Test
+ public void testIsAvailable_notIfNull() throws Exception {
+ mController.onResume(null, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfAppBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfChannelBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notNoIntent() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.settingsIntent = new Intent("test");
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ Intent intent = new Intent("action");
+ appRow.settingsIntent = intent;
+ mController.onResume(appRow, null, null, null);
+
+ Preference pref = new Preference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertEquals(intent, pref.getIntent());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/BadgePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BadgePreferenceControllerTest.java
new file mode 100644
index 0000000..6052478
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/BadgePreferenceControllerTest.java
@@ -0,0 +1,298 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.provider.Settings.Secure.NOTIFICATION_BADGING;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+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.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class BadgePreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+
+ private BadgePreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new BadgePreferenceController(mContext, mBackend));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(RestrictedSwitchPreference.class));
+ mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
+ }
+
+ @Test
+ public void testIsAvailable_notIfAppBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, mock(NotificationChannel.class), null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfChannelBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_channel_notIfAppOff() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.showBadge = false;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfOffGlobally() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+ Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, 0);
+
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_app() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ mController.onResume(appRow, null, null, null);
+ Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, 1);
+
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_channel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.showBadge = true;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+ Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, 1);
+
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_channelNotConfigurable() throws Exception {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_channel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = "a";
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.canShowBadge()).thenReturn(true);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertTrue(pref.isChecked());
+
+ when(channel.canShowBadge()).thenReturn(false);
+ mController.onResume(appRow, channel, null, null);
+ mController.updateState(pref);
+
+ assertFalse(pref.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_app() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.showBadge = true;
+ mController.onResume(appRow, null, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+ assertTrue(pref.isChecked());
+
+ appRow.showBadge = false;
+ mController.onResume(appRow, null, null, null);
+
+ mController.updateState(pref);
+ assertFalse(pref.isChecked());
+ }
+
+ @Test
+ public void testOnPreferenceChange_on_channel() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.showBadge = true;
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
+ channel.setShowBadge(false);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, true);
+ assertTrue(channel.canShowBadge());
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+
+ @Test
+ public void testOnPreferenceChange_off_channel() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.showBadge = true;
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
+ channel.setShowBadge(true);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, false);
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ assertFalse(channel.canShowBadge());
+ }
+
+ @Test
+ public void testOnPreferenceChange_on_app() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.showBadge = false;
+ mController.onResume(appRow, null, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, true);
+
+ assertTrue(appRow.showBadge);
+ verify(mBackend, times(1)).setShowBadge(any(), anyInt(), eq(true));
+ }
+
+ @Test
+ public void testOnPreferenceChange_off_app() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.showBadge = true;
+ mController.onResume(appRow, null, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, false);
+
+ assertFalse(appRow.showBadge);
+ verify(mBackend, times(1)).setShowBadge(any(), anyInt(), eq(false));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java
index ac158b6..d294122 100644
--- a/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java
@@ -18,9 +18,7 @@
import static android.provider.Settings.Secure.NOTIFICATION_BADGING;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -43,11 +41,12 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class BadgingNotificationPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -56,11 +55,15 @@
private PreferenceScreen mScreen;
private BadgingNotificationPreferenceController mController;
+ private Preference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new BadgingNotificationPreferenceController(mContext);
+ mPreference = new Preference(RuntimeEnvironment.application);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
}
@Test
@@ -70,7 +73,7 @@
.thenReturn(true);
mController.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isTrue();
}
@Test
@@ -78,14 +81,10 @@
when(mContext.getResources().
getBoolean(com.android.internal.R.bool.config_notificationBadging))
.thenReturn(false);
- final Preference preference = mock(Preference.class);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(preference);
- when(preference.getKey()).thenReturn(mController.getPreferenceKey());
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
new file mode 100644
index 0000000..9014f4e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
@@ -0,0 +1,272 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.UserManager;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.widget.SwitchBar;
+import com.android.settings.wrapper.NotificationChannelGroupWrapper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class BlockPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+
+ @Mock
+ NotificationSettingsBase.ImportanceListener mImportanceListener;
+
+ private BlockPreferenceController mController;
+ @Mock
+ private LayoutPreference mPreference;
+ private SwitchBar mSwitch;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new BlockPreferenceController(mContext, mImportanceListener, mBackend));
+ mSwitch = new SwitchBar(mContext);
+ when(mPreference.findViewById(R.id.switch_bar)).thenReturn(mSwitch);
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(LayoutPreference.class));
+ mController.onSwitchChanged(null, false);
+ }
+
+ @Test
+ public void testIsAvailable_notIfNull() throws Exception {
+ mController.onResume(null, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfChannelNotBlockable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = true;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfGroupNotBlockable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = true;
+ mController.onResume(appRow, null, mock(NotificationChannelGroupWrapper.class), null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfAppNotBlockable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = true;
+ mController.onResume(appRow, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_systemApp() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = true;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_nonSystemApp() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = false;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_app() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, null, null, null);
+ mController.updateState(mPreference);
+
+ assertNotNull(mPreference.findViewById(R.id.switch_bar));
+
+ assertFalse(mSwitch.isChecked());
+
+ appRow.banned = false;
+ mController.onResume(appRow, null, null, null);
+ mController.updateState(mPreference);
+
+ assertTrue(mSwitch.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_group() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.getGroup()).thenReturn(mock(NotificationChannelGroup.class));
+ when(group.isBlocked()).thenReturn(true);
+ mController.onResume(appRow, null, group, null);
+ mController.updateState(mPreference);
+
+ assertFalse(mSwitch.isChecked());
+
+ appRow.banned = true;
+ mController.onResume(appRow, null, group, null);
+ when(group.isBlocked()).thenReturn(true);
+ mController.updateState(mPreference);
+
+ assertFalse(mSwitch.isChecked());
+
+ appRow.banned = false;
+ mController.onResume(appRow, null, group, null);
+ when(group.isBlocked()).thenReturn(false);
+ mController.updateState(mPreference);
+
+ assertTrue(mSwitch.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_channelBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, null, null);
+ mController.updateState(mPreference);
+
+ assertFalse(mSwitch.isChecked());
+
+ appRow.banned = true;
+ channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+ mController.updateState(mPreference);
+
+ assertFalse(mSwitch.isChecked());
+
+ appRow.banned = false;
+ channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+ mController.updateState(mPreference);
+
+ assertTrue(mSwitch.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_noCrashIfCalledTwice() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+ mController.updateState(mPreference);
+ mController.updateState(mPreference);
+ }
+
+ @Test
+ public void testUpdateState_doesNotResetImportance() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+ mController.updateState(mPreference);
+
+ assertEquals(IMPORTANCE_LOW, channel.getImportance());
+ }
+
+ @Test
+ public void testOnSwitchChanged_channel_default() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_UNSPECIFIED);
+ mController.onResume(appRow, channel, null, null);
+ mController.updateState(mPreference);
+
+ mController.onSwitchChanged(null, false);
+ assertEquals(IMPORTANCE_NONE, channel.getImportance());
+
+ mController.onSwitchChanged(null, true);
+ assertEquals(IMPORTANCE_UNSPECIFIED, channel.getImportance());
+
+ verify(mBackend, times(2)).updateChannel(any(), anyInt(), any());
+
+ }
+
+ @Test
+ public void testOnSwitchChanged_channel_nonDefault() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+ mController.updateState(mPreference);
+
+ mController.onSwitchChanged(null, false);
+ assertEquals(IMPORTANCE_NONE, channel.getImportance());
+
+ mController.onSwitchChanged(null, true);
+ assertEquals(IMPORTANCE_DEFAULT, channel.getImportance());
+
+ verify(mBackend, times(2)).updateChannel(any(), anyInt(), any());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/DeletedChannelsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/DeletedChannelsPreferenceControllerTest.java
new file mode 100644
index 0000000..fd903f9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/DeletedChannelsPreferenceControllerTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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.notification;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.wrapper.NotificationChannelGroupWrapper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class DeletedChannelsPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+
+ private DeletedChannelsPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = new DeletedChannelsPreferenceController(mContext, mBackend);
+ }
+
+ @Test
+ public void noCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(Preference.class));
+ }
+
+ @Test
+ public void isAvailable_appScreen_notIfAppBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void isAvailable_groupScreen_never() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ mController.onResume(appRow, null, mock(NotificationChannelGroupWrapper.class), null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void isAvailable_channelScreen_never() throws Exception {
+ mController.onResume(
+ new NotificationBackend.AppRow(), mock(NotificationChannel.class), null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void isAvailable_appScreen_notIfNoDeletedChannels() throws Exception {
+ when(mBackend.getDeletedChannelCount(any(), anyInt())).thenReturn(0);
+ mController.onResume(new NotificationBackend.AppRow(), null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void isAvailable_appScreen() throws Exception {
+ when(mBackend.getDeletedChannelCount(any(), anyInt())).thenReturn(1);
+ mController.onResume(new NotificationBackend.AppRow(), null, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void updateState() throws Exception {
+ when(mBackend.getDeletedChannelCount(any(), anyInt())).thenReturn(1);
+ mController.onResume(new NotificationBackend.AppRow(), null, null, null);
+
+ Preference pref = mock(Preference.class);
+ mController.updateState(pref);
+
+ verify(pref, times(1)).setEnabled(false);
+ verify(pref, times(1)).setSelectable(false);
+ verify(mBackend, times(1)).getDeletedChannelCount(any(), anyInt());
+ ArgumentCaptor<CharSequence> argumentCaptor = ArgumentCaptor.forClass(CharSequence.class);
+ verify(pref, times(1)).setTitle(argumentCaptor.capture());
+ assertTrue(argumentCaptor.getValue().toString().contains("1"));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/DescriptionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/DescriptionPreferenceControllerTest.java
new file mode 100644
index 0000000..1776a9b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/DescriptionPreferenceControllerTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.wrapper.NotificationChannelGroupWrapper;
+
+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.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class DescriptionPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+
+ private DescriptionPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new DescriptionPreferenceController(mContext));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(Preference.class));
+ }
+
+ @Test
+ public void testIsAvailable_notIfNull() throws Exception {
+ mController.onResume(null, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfChannelGroupBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.isBlocked()).thenReturn(true);
+ mController.onResume(appRow, null, group, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfChannelBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfNoChannelDesc() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfNoChannelGroupDesc() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.getGroup()).thenReturn(mock(NotificationChannelGroup.class));
+ mController.onResume(appRow, null, group, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_channel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ when(channel.getDescription()).thenReturn("AAA");
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_channelGroup() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.getGroup()).thenReturn(mock(NotificationChannelGroup.class));
+ when(group.getDescription()).thenReturn("something");
+ when(group.isBlocked()).thenReturn(false);
+ mController.onResume(appRow, null, group, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_channel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ when(channel.getDescription()).thenReturn("AAA");
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new Preference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertEquals("AAA", pref.getTitle());
+ assertFalse(pref.isEnabled());
+ assertFalse(pref.isSelectable());
+ }
+
+ @Test
+ public void testUpdateState_channelGroup() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.getGroup()).thenReturn(mock(NotificationChannelGroup.class));
+ when(group.getDescription()).thenReturn("something");
+ mController.onResume(appRow, null, group, null);
+
+ Preference pref = new Preference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertEquals("something", pref.getTitle());
+ assertFalse(pref.isEnabled());
+ assertFalse(pref.isSelectable());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/DndPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/DndPreferenceControllerTest.java
new file mode 100644
index 0000000..241e279
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/DndPreferenceControllerTest.java
@@ -0,0 +1,240 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+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 com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+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.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class DndPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+ @Mock
+ private Lifecycle mLifecycle;
+
+ private DndPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new DndPreferenceController(mContext, mLifecycle, mBackend));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(RestrictedSwitchPreference.class));
+ mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
+ mController.onResume();
+ }
+
+ @Test
+ public void testIsAvailable_notIfNotImportant_noVisEffects() throws Exception {
+ when(mNm.getNotificationPolicy()).thenReturn(new NotificationManager.Policy(0, 0, 0, 0));
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
+ mController.onResume();
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfNotImportant_visEffects() throws Exception {
+ when(mNm.getNotificationPolicy()).thenReturn(new NotificationManager.Policy(0, 0, 0, 1));
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_MIN);
+ mController.onResume();
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_importance_noVisEffects() throws Exception {
+ when(mNm.getNotificationPolicy()).thenReturn(new NotificationManager.Policy(0, 0, 0, 0));
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume();
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_important_visEffects() throws Exception {
+ when(mNm.getNotificationPolicy()).thenReturn(new NotificationManager.Policy(0, 0, 0, 1));
+ assertTrue(mNm.getNotificationPolicy().suppressedVisualEffects != 0);
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
+ mController.onResume();
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_notConfigurable() throws Exception {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_configurable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertTrue(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_bypassDnd() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.canBypassDnd()).thenReturn(true);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+ assertTrue(pref.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_noBypassDnd() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.canBypassDnd()).thenReturn(false);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+ assertFalse(pref.isChecked());
+ }
+
+ @Test
+ public void testOnPreferenceChange_on() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, true);
+
+ assertTrue(channel.canBypassDnd());
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+
+ @Test
+ public void testOnPreferenceChange_off() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, false);
+
+ assertFalse(channel.canBypassDnd());
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java
new file mode 100644
index 0000000..385376f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.UserManager;
+import android.support.v14.preference.PreferenceFragment;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.wrapper.NotificationChannelGroupWrapper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class HeaderPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+
+ private HeaderPreferenceController mController;
+ @Mock
+ private LayoutPreference mPreference;
+ @Mock
+ private View mView;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ PreferenceFragment fragment = mock(PreferenceFragment.class);
+ when(fragment.getContext()).thenReturn(mContext);
+ Activity activity = mock(Activity.class);
+ when(activity.getApplicationContext()).thenReturn(mContext);
+ when(fragment.getActivity()).thenReturn(activity);
+ mController = spy(new HeaderPreferenceController(mContext, fragment));
+ when(mPreference.findViewById(anyInt())).thenReturn(mView);
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(LayoutPreference.class));
+ }
+
+ @Test
+ public void testIsAvailable_notIfNull() throws Exception {
+ mController.onResume(null, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, null, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testGetLabel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.label = "bananas";
+ mController.onResume(appRow, null, null, null);
+ assertEquals(appRow.label, mController.getLabel());
+
+ NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
+ NotificationChannelGroupWrapper gWrapper = new NotificationChannelGroupWrapper(group);
+ mController.onResume(appRow, null, gWrapper, null);
+ assertEquals(group.getName(), mController.getLabel());
+
+ NotificationChannel channel = new NotificationChannel("cid", "cname", IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, gWrapper, null);
+ assertEquals(channel.getName(), mController.getLabel());
+ }
+
+ @Test
+ public void testGetSummary() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.label = "bananas";
+ mController.onResume(appRow, null, null, null);
+ assertEquals("", mController.getSummary());
+
+ NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
+ NotificationChannelGroupWrapper gWrapper = new NotificationChannelGroupWrapper(group);
+ mController.onResume(appRow, null, gWrapper, null);
+ assertEquals(appRow.label, mController.getSummary());
+
+ NotificationChannel channel = new NotificationChannel("cid", "cname", IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, gWrapper, null);
+ assertTrue(mController.getSummary().toString().contains(group.getName()));
+ assertTrue(mController.getSummary().toString().contains(appRow.label));
+
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.getSummary().toString().contains(group.getName()));
+ assertTrue(mController.getSummary().toString().contains(appRow.label));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
new file mode 100644
index 0000000..aebd6c9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+import android.text.TextUtils;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.RestrictedLockUtils;
+
+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.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class ImportancePreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+
+ private ImportancePreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new ImportancePreferenceController(mContext));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(Preference.class));
+ }
+
+ @Test
+ public void testIsAvailable_notIfNull() throws Exception {
+ mController.onResume(null, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfAppBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, mock(NotificationChannel.class), null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfChannelBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notForDefaultChannel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new Preference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ assertNull(pref.getIntent());
+ }
+
+ @Test
+ public void testUpdateState_notConfigurable() throws Exception {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new Preference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ assertNull(pref.getIntent());
+ }
+
+ @Test
+ public void testUpdateState() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new Preference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertTrue(pref.isEnabled());
+ assertNotNull(pref.getIntent());
+ assertFalse(TextUtils.isEmpty(pref.getSummary()));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/LightsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/LightsPreferenceControllerTest.java
new file mode 100644
index 0000000..017cb88
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/LightsPreferenceControllerTest.java
@@ -0,0 +1,245 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.provider.Settings.System.NOTIFICATION_LIGHT_PULSE;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+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.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O, shadows = {
+ SettingsShadowResources.class,
+})
+public class LightsPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+
+ private LightsPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new LightsPreferenceController(mContext, mBackend));
+
+ // By default allow lights
+ SettingsShadowResources.overrideResource(
+ com.android.internal.R.bool.config_intrusiveNotificationLed, true);
+ Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_LIGHT_PULSE, 1);
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(RestrictedSwitchPreference.class));
+ mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
+ }
+
+ @Test
+ public void testIsAvailable_notIfConfigNotAllowed() throws Exception {
+ SettingsShadowResources.overrideResource(
+ com.android.internal.R.bool.config_intrusiveNotificationLed, false);
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfSettingNotAllowed() throws Exception {
+ Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_LIGHT_PULSE, 0);
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfNotImportant() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfDefaultChannel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_notConfigurable() throws Exception {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_configurable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertTrue(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_lightsOn() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.shouldShowLights()).thenReturn(true);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+ assertTrue(pref.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_lightsOff() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.shouldShowLights()).thenReturn(false);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+ assertFalse(pref.isChecked());
+ }
+
+ @Test
+ public void testOnPreferenceChange_on() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_DEFAULT);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, true);
+
+ assertTrue(channel.shouldShowLights());
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+
+ @Test
+ public void testOnPreferenceChange_off() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, false);
+
+ assertFalse(channel.shouldShowLights());
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
new file mode 100644
index 0000000..d685740
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
@@ -0,0 +1,316 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.wrapper.NotificationChannelGroupWrapper;
+import com.android.settingslib.RestrictedLockUtils;
+
+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.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class NotificationPreferenceControllerTest {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+
+ private TestPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = new TestPreferenceController(mContext, mBackend);
+ }
+
+ @Test
+ public void noCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(Preference.class));
+ assertFalse(mController.checkCanBeVisible(IMPORTANCE_UNSPECIFIED));
+ mController.saveChannel();
+ assertFalse(mController.isChannelConfigurable());
+ assertFalse(mController.isChannelBlockable());
+ assertFalse(mController.isChannelGroupBlockable());
+ }
+
+ @Test
+ public void isAvailable_notIfNull() throws Exception {
+ mController.onResume(null, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void isAvailable_notIfAppBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, mock(NotificationChannel.class),
+ mock(NotificationChannelGroupWrapper.class), null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void isAvailable_notIfChannelBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void isAvailable_notIfChannelGroupBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+
+ mController.onResume(appRow, channel, group, null);
+ when(group.isBlocked()).thenReturn(true);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void isAvailable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.isBlocked()).thenReturn(false);
+
+ mController.onResume(appRow, channel, group, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testOnResume() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ RestrictedLockUtils.EnforcedAdmin admin = mock(RestrictedLockUtils.EnforcedAdmin.class);
+
+ mController.onResume(appRow, channel, group, admin);
+
+ assertEquals(appRow, mController.mAppRow);
+ assertEquals(channel, mController.mChannel);
+ assertEquals(group, mController.mChannelGroup);
+ assertEquals(admin, mController.mAdmin);
+ }
+
+ @Test
+ public void testCanBeVisible_unspecified() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_UNSPECIFIED);
+
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.checkCanBeVisible(IMPORTANCE_MIN));
+ }
+
+ @Test
+ public void testCanBeVisible_sameImportance() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.checkCanBeVisible(IMPORTANCE_LOW));
+ }
+
+ @Test
+ public void testCanBeVisible_greaterImportance() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.checkCanBeVisible(IMPORTANCE_MIN));
+ }
+
+ @Test
+ public void testCanBeVisible_lesserImportance() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.checkCanBeVisible(IMPORTANCE_DEFAULT));
+ }
+
+ @Test
+ public void testSaveImportance() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
+
+ mController.onResume(appRow, channel, null, null);
+ mController.saveChannel();
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+
+ @Test
+ public void testIsConfigurable() {
+ String sameId = "bananas";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = sameId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(sameId);
+
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isChannelConfigurable());
+
+ when(channel.getId()).thenReturn("something new");
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isChannelConfigurable());
+ }
+
+ @Test
+ public void testIsChannelBlockable_nonSystemAppsBlockable() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = false;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.isBlockableSystem()).thenReturn(false);
+
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isChannelBlockable());
+ }
+
+ @Test
+ public void testIsChannelBlockable_mostSystemAppsNotBlockable() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = true;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.isBlockableSystem()).thenReturn(false);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isChannelBlockable());
+ }
+
+ @Test
+ public void testIsChannelBlockable_someSystemAppsAreBlockable() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = true;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.isBlockableSystem()).thenReturn(true);
+
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isChannelBlockable());
+ }
+
+ @Test
+ public void testIsChannelBlockable_canUndoSystemBlock() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = true;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.isBlockableSystem()).thenReturn(false);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isChannelBlockable());
+ }
+
+ @Test
+ public void testIsChannelGroupBlockable_nonSystemBlockable() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = false;
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.isBlocked()).thenReturn(false);
+
+ mController.onResume(appRow, null, group, null);
+ assertTrue(mController.isChannelGroupBlockable());
+ }
+
+ @Test
+ public void testIsChannelGroupBlockable_SystemNotBlockable() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = true;
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.isBlocked()).thenReturn(false);
+
+ mController.onResume(appRow, null, group, null);
+ assertFalse(mController.isChannelGroupBlockable());
+ }
+
+ @Test
+ public void testIsChannelGroupBlockable_canUndoSystemBlock() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = true;
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.isBlocked()).thenReturn(true);
+
+ mController.onResume(appRow, null, group, null);
+ assertTrue(mController.isChannelGroupBlockable());
+ }
+
+ private final class TestPreferenceController extends NotificationPreferenceController {
+
+ public TestPreferenceController(Context context,
+ NotificationBackend backend) {
+ super(context, backend);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return null;
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationsOffPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationsOffPreferenceControllerTest.java
new file mode 100644
index 0000000..e1f9eb7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/NotificationsOffPreferenceControllerTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.wrapper.NotificationChannelGroupWrapper;
+
+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.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class NotificationsOffPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+
+ private NotificationsOffPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new NotificationsOffPreferenceController(mContext));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(Preference.class));
+ }
+
+ @Test
+ public void testIsAvailable_yesIfAppBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, null, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_yesIfChannelGroupBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.isBlocked()).thenReturn(true);
+ mController.onResume(appRow, null, group, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_yesIfChannelBlocked() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_channel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new Preference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertTrue(pref.getTitle().toString().contains("category"));
+ assertFalse(pref.isEnabled());
+ assertFalse(pref.isSelectable());
+ }
+
+ @Test
+ public void testUpdateState_channelGroup() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
+ when(group.isBlocked()).thenReturn(true);
+ mController.onResume(appRow, null, group, null);
+
+ Preference pref = new Preference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertTrue(pref.getTitle().toString().contains("group"));
+ assertFalse(pref.isEnabled());
+ assertFalse(pref.isSelectable());
+ }
+
+ @Test
+ public void testUpdateState_app() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, null, null, null);
+
+ Preference pref = new Preference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertTrue(pref.getTitle().toString().contains("app"));
+ assertFalse(pref.isEnabled());
+ assertFalse(pref.isSelectable());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/PulseNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/PulseNotificationPreferenceControllerTest.java
index f6c6bf2..4ee5f5a 100644
--- a/tests/robotests/src/com/android/settings/notification/PulseNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/PulseNotificationPreferenceControllerTest.java
@@ -16,6 +16,12 @@
package com.android.settings.notification;
+import static android.provider.Settings.System.NOTIFICATION_LIGHT_PULSE;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.provider.Settings;
import android.support.v7.preference.Preference;
@@ -31,18 +37,12 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
-import static android.provider.Settings.System.NOTIFICATION_LIGHT_PULSE;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class PulseNotificationPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -51,11 +51,15 @@
private PreferenceScreen mScreen;
private PulseNotificationPreferenceController mController;
+ private Preference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new PulseNotificationPreferenceController(mContext);
+ mPreference = new Preference(RuntimeEnvironment.application);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
}
@Test
@@ -65,7 +69,7 @@
.thenReturn(true);
mController.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isTrue();
}
@Test
@@ -73,14 +77,10 @@
when(mContext.getResources().
getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed))
.thenReturn(false);
- final Preference preference = mock(Preference.class);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(preference);
- when(preference.getKey()).thenReturn(mController.getPreferenceKey());
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java
new file mode 100644
index 0000000..1d5a791
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java
@@ -0,0 +1,257 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.util.AttributeSet;
+
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.RestrictedLockUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class SoundPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+ @Mock
+ private SettingsPreferenceFragment mFragment;
+ @Mock
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+
+ private SoundPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new SoundPreferenceController(
+ mContext, mFragment, mImportanceListener, mBackend));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(NotificationSoundPreference.class));
+ mController.onPreferenceChange(mock(NotificationSoundPreference.class), Uri.EMPTY);
+ mController.handlePreferenceTreeClick(mock(NotificationSoundPreference.class));
+ mController.onActivityResult(1, 1, null);
+ mController.hasValidSound(null);
+ }
+
+ @Test
+ public void testIsAvailable_notIfChannelNull() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ mController.onResume(appRow, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfNotImportant() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfDefaultChannel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testDisplayPreference_savesPreference() throws Exception {
+ NotificationSoundPreference pref = mock(NotificationSoundPreference.class);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+
+ mController.onActivityResult(SoundPreferenceController.CODE, 1, new Intent());
+ verify(pref, times(1)).onActivityResult(anyInt(), anyInt(), any());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new NotificationSoundPreference(mContext, mock(AttributeSet.class));
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_notConfigurable() throws Exception {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new NotificationSoundPreference(mContext, mock(AttributeSet.class));
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_configurable() throws Exception {
+ Uri sound = Settings.System.DEFAULT_ALARM_ALERT_URI;
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ when(channel.getSound()).thenReturn(sound);
+ mController.onResume(appRow, channel, null, null);
+
+ NotificationSoundPreference pref =
+ new NotificationSoundPreference(mContext, mock(AttributeSet.class));
+ mController.updateState(pref);
+
+ assertEquals(sound, pref.onRestoreRingtone());
+ assertTrue(pref.isEnabled());
+ }
+
+ @Test
+ public void testOnPreferenceChange() throws Exception {
+ Uri sound = Settings.System.DEFAULT_ALARM_ALERT_URI;
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+ channel.setSound(sound, Notification.AUDIO_ATTRIBUTES_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+
+ NotificationSoundPreference pref =
+ new NotificationSoundPreference(mContext, mock(AttributeSet.class));
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, Uri.EMPTY);
+ assertEquals(Uri.EMPTY, channel.getSound());
+ assertEquals(Notification.AUDIO_ATTRIBUTES_DEFAULT, channel.getAudioAttributes());
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+
+ @Test
+ public void testOnPreferenceTreeClick_incorrectPref() throws Exception {
+ NotificationSoundPreference pref = mock(NotificationSoundPreference.class);
+ mController.handlePreferenceTreeClick(pref);
+
+ verify(pref, never()).onPrepareRingtonePickerIntent(any());
+ verify(mFragment, never()).startActivityForResult(any(), anyInt());
+ }
+
+
+ @Test
+ public void testOnPreferenceTreeClick_correctPref() throws Exception {
+ NotificationSoundPreference pref =
+ spy(new NotificationSoundPreference(mContext, mock(AttributeSet.class)));
+ pref.setKey(mController.getPreferenceKey());
+ mController.handlePreferenceTreeClick(pref);
+
+ verify(pref, times(1)).onPrepareRingtonePickerIntent(any());
+ verify(mFragment, times(1)).startActivityForResult(any(), anyInt());
+ }
+
+ @Test
+ public void testOnActivityResult() {
+ NotificationSoundPreference pref = mock(NotificationSoundPreference.class);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+
+ mController.onActivityResult(SoundPreferenceController.CODE, 1, new Intent("hi"));
+ verify(pref, times(1)).onActivityResult(anyInt(), anyInt(), any());
+ verify(mImportanceListener, times(1)).onImportanceChanged();
+ }
+
+ @Test
+ public void testHasValidSound() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
+ assertTrue(mController.hasValidSound(channel));
+
+ channel.setSound(Uri.EMPTY, Notification.AUDIO_ATTRIBUTES_DEFAULT);
+ assertFalse(mController.hasValidSound(channel));
+
+ channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
+ assertFalse(mController.hasValidSound(channel));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java
index 054309c..19cf649 100644
--- a/tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java
@@ -16,6 +16,12 @@
package com.android.settings.notification;
+import static android.provider.Settings.System.VIBRATE_WHEN_RINGING;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.provider.Settings;
import android.support.v7.preference.Preference;
@@ -23,26 +29,20 @@
import android.support.v7.preference.TwoStatePreference;
import android.telephony.TelephonyManager;
-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;
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.shadows.ShadowApplication;
-import static android.provider.Settings.System.VIBRATE_WHEN_RINGING;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class VibrateWhenRingPreferenceControllerTest {
@Mock
@@ -53,36 +53,34 @@
private TelephonyManager mTelephonyManager;
private VibrateWhenRingPreferenceController mController;
+ private Preference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
mController = new VibrateWhenRingPreferenceController(mContext);
+ mPreference = new Preference(RuntimeEnvironment.application);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
}
@Test
public void display_voiceCapable_shouldDisplay() {
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
- when(mScreen.findPreference(mController.getPreferenceKey()))
- .thenReturn(mock(Preference.class));
mController.displayPreference(mScreen);
- verify(mScreen, never()).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isTrue();
}
@Test
public void display_notVoiceCapable_shouldNotDisplay() {
when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
- final Preference preference = mock(Preference.class);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(preference);
- when(preference.getKey()).thenReturn(mController.getPreferenceKey());
mController.displayPreference(mScreen);
- verify(mScreen).removePreference(any(Preference.class));
+ assertThat(mPreference.isVisible()).isFalse();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/notification/VibrationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VibrationPreferenceControllerTest.java
new file mode 100644
index 0000000..4695590
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/VibrationPreferenceControllerTest.java
@@ -0,0 +1,230 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.UserManager;
+import android.os.Vibrator;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+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.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
+public class VibrationPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ Vibrator mVibrator;
+ @Mock
+ private UserManager mUm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+
+ private VibrationPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ shadowApplication.setSystemService(Context.VIBRATOR_SERVICE, mVibrator);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new VibrationPreferenceController(mContext, mBackend));
+
+ // by default allow vibration
+ when(mVibrator.hasVibrator()).thenReturn(true);
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(RestrictedSwitchPreference.class));
+ mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
+ }
+
+ @Test
+ public void testIsAvailable_notSystemDoesNotHave() throws Exception {
+ when(mVibrator.hasVibrator()).thenReturn(false);
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfNotImportant() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfDefaultChannel() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_notConfigurable() throws Exception {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_configurable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ assertTrue(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_vibrateOn() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.shouldVibrate()).thenReturn(true);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+ assertTrue(pref.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_vibrateOff() throws Exception {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.shouldVibrate()).thenReturn(false);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+ assertFalse(pref.isChecked());
+ }
+
+ @Test
+ public void testOnPreferenceChange_on() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_DEFAULT);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, true);
+
+ assertTrue(channel.shouldVibrate());
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+
+ @Test
+ public void testOnPreferenceChange_off() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref =
+ new RestrictedSwitchPreference(RuntimeEnvironment.application);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, false);
+
+ assertFalse(channel.shouldVibrate());
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/VisibilityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VisibilityPreferenceControllerTest.java
new file mode 100644
index 0000000..ed658fe
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/VisibilityPreferenceControllerTest.java
@@ -0,0 +1,326 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.NotificationManager.VISIBILITY_NO_OVERRIDE;
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.Build;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowRestrictionUtils;
+import com.android.settingslib.RestrictedLockUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O, shadows = {
+ ShadowRestrictionUtils.class,
+})
+public class VisibilityPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private LockPatternUtils mLockUtils;
+ @Mock
+ private UserManager mUm;
+ @Mock
+ private DevicePolicyManager mDm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+
+ private VisibilityPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ shadowApplication.setSystemService(Context.DEVICE_POLICY_SERVICE, mDm);
+ mContext = shadowApplication.getApplicationContext();
+ mController = spy(new VisibilityPreferenceController(mContext, mLockUtils, mBackend));
+
+ // by default the lockscreen is secure
+ when(mLockUtils.isSecure(anyInt())).thenReturn(true);
+ // and notifications are visible in redacted form
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1);
+ // and not restricted
+ ShadowRestrictionUtils.setRestricted(false);
+ // with no managed profile
+ UserInfo userInfo = new UserInfo();
+ when(mUm.getUserInfo(anyInt())).thenReturn(userInfo);
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() throws Exception {
+ mController.isAvailable();
+ mController.updateState(mock(RestrictedDropDownPreference.class));
+ mController.onPreferenceChange(mock(RestrictedDropDownPreference.class), true);
+ }
+
+ @Test
+ public void testIsAvailable_notSecure() throws Exception {
+ when(mLockUtils.isSecure(anyInt())).thenReturn(false);
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfNotImportant() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_MIN);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+
+ channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin_disableSecure() throws Exception {
+ ShadowRestrictionUtils.setRestricted(true);
+ UserInfo userInfo = new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE);
+ when(mUm.getUserInfo(anyInt())).thenReturn(userInfo);
+ List<ComponentName> components = new ArrayList<>();
+ components.add(new ComponentName("", ""));
+ when(mDm.getActiveAdminsAsUser(anyInt())).thenReturn(components);
+ when(mDm.getKeyguardDisabledFeatures(any(), anyInt()))
+ .thenReturn(KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+ mController.updateState(pref);
+
+ verify(pref, times(2)).addRestrictedItem(any());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin_disableUnredacted() throws Exception {
+ ShadowRestrictionUtils.setRestricted(true);
+ UserInfo userInfo = new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE);
+ when(mUm.getUserInfo(anyInt())).thenReturn(userInfo);
+ List<ComponentName> components = new ArrayList<>();
+ components.add(new ComponentName("", ""));
+ when(mDm.getActiveAdminsAsUser(anyInt())).thenReturn(components);
+ when(mDm.getKeyguardDisabledFeatures(any(), anyInt()))
+ .thenReturn(KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn("something");
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+ mController.updateState(pref);
+
+ verify(pref, times(1)).addRestrictedItem(any());
+ }
+
+ @Test
+ public void testUpdateState_noLockScreenNotificationsGlobally() throws Exception {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
+
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+ mController.updateState(pref);
+
+ ArgumentCaptor<String[]> argumentCaptor = ArgumentCaptor.forClass(String[].class);
+ verify(pref, times(1)).setEntryValues(argumentCaptor.capture());
+ assertFalse(Arrays.asList(argumentCaptor.getValue())
+ .contains(VISIBILITY_NO_OVERRIDE));
+ }
+
+ @Test
+ public void testUpdateState_noPrivateLockScreenNotificationsGlobally() throws Exception {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
+
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+ mController.updateState(pref);
+
+ ArgumentCaptor<String[]> argumentCaptor = ArgumentCaptor.forClass(String[].class);
+ verify(pref, times(1)).setEntryValues(argumentCaptor.capture());
+ assertFalse(Arrays.asList(argumentCaptor.getValue())
+ .contains(VISIBILITY_NO_OVERRIDE));
+ }
+
+ @Test
+ public void testUpdateState_noGlobalRestriction() throws Exception {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+ mController.updateState(pref);
+
+ ArgumentCaptor<String[]> argumentCaptor = ArgumentCaptor.forClass(String[].class);
+ verify(pref, times(1)).setEntryValues(argumentCaptor.capture());
+ List<String> values = Arrays.asList(argumentCaptor.getValue());
+ assertEquals(3, values.size());
+ assertTrue(values.contains(String.valueOf(VISIBILITY_NO_OVERRIDE)));
+ assertTrue(values.contains(String.valueOf(Notification.VISIBILITY_PRIVATE)));
+ assertTrue(values.contains(String.valueOf(Notification.VISIBILITY_SECRET)));
+ }
+
+ @Test
+ public void testUpdateState_noChannelOverride() throws Exception {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
+
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getLockscreenVisibility()).thenReturn(VISIBILITY_NO_OVERRIDE);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+ mController.updateState(pref);
+
+ ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
+ verify(pref, times(1)).setValue(argumentCaptor.capture());
+
+ assertEquals(String.valueOf(Notification.VISIBILITY_PRIVATE), argumentCaptor.getValue());
+ }
+
+ @Test
+ public void testUpdateState_channelOverride() throws Exception {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
+
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getLockscreenVisibility()).thenReturn(Notification.VISIBILITY_SECRET);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+ mController.updateState(pref);
+
+ ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
+ verify(pref, times(1)).setValue(argumentCaptor.capture());
+
+ assertEquals(String.valueOf(Notification.VISIBILITY_SECRET), argumentCaptor.getValue());
+ }
+
+ @Test
+ public void testOnPreferenceChange_noOverride() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
+
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", 4);
+ channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, String.valueOf(Notification.VISIBILITY_PRIVATE));
+
+ assertEquals(VISIBILITY_NO_OVERRIDE, channel.getLockscreenVisibility());
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+
+ @Test
+ public void testOnPreferenceChange_override() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
+
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", 4);
+ channel.setLockscreenVisibility(VISIBILITY_NO_OVERRIDE);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, String.valueOf(Notification.VISIBILITY_SECRET));
+
+ assertEquals(Notification.VISIBILITY_SECRET, channel.getLockscreenVisibility());
+ verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
index a529b0b..fae814f 100644
--- a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
@@ -18,13 +18,24 @@
package com.android.settings.search;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.content.ComponentName;
+import android.content.Intent;
+import android.util.FeatureFlagUtils;
+import android.widget.Toolbar;
+
import com.android.settings.TestConfig;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.dashboard.SiteMapManager;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,13 +43,12 @@
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O, shadows = {
+ SettingsShadowSystemProperties.class
+})
public class SearchFeatureProviderImplTest {
+
private SearchFeatureProviderImpl mProvider;
private Activity mActivity;
@@ -49,6 +59,11 @@
mProvider = spy(new SearchFeatureProviderImpl());
}
+ @After
+ public void tearDown() {
+ SettingsShadowSystemProperties.clear();
+ }
+
@Test
public void getSiteMapManager_shouldCacheInstance() {
final SiteMapManager manager1 = mProvider.getSiteMapManager();
@@ -75,24 +90,69 @@
verify(mProvider).cleanQuery(eq(query));
}
+ @Test
+ public void initSearchToolbar_searchV2_shouldInitWithOnClickListener() {
+ mProvider.initSearchToolbar(mActivity, null);
+ // Should not crash.
+
+ SettingsShadowSystemProperties.set(
+ FeatureFlagUtils.FFLAG_PREFIX + FeatureFlags.SEARCH_V2,
+ "true");
+ final Toolbar toolbar = new Toolbar(mActivity);
+ mProvider.initSearchToolbar(mActivity, toolbar);
+
+ toolbar.performClick();
+
+ final Intent launchIntent = shadowOf(mActivity).getNextStartedActivity();
+
+ assertThat(launchIntent.getAction())
+ .isEqualTo("com.android.settings.action.SETTINGS_SEARCH");
+ }
+
+ @Test
+ public void initSearchToolbar_searchV1_shouldInitWithOnClickListener() {
+ mProvider.initSearchToolbar(mActivity, null);
+ // Should not crash.
+
+ SettingsShadowSystemProperties.set(
+ FeatureFlagUtils.FFLAG_PREFIX + FeatureFlags.SEARCH_V2,
+ "false");
+ final Toolbar toolbar = new Toolbar(mActivity);
+ mProvider.initSearchToolbar(mActivity, toolbar);
+
+ toolbar.performClick();
+
+ final Intent launchIntent = shadowOf(mActivity).getNextStartedActivity();
+
+ assertThat(launchIntent.getComponent().getClassName())
+ .isEqualTo(SearchActivity.class.getName());
+ }
+
@Test(expected = IllegalArgumentException.class)
public void verifyLaunchSearchResultPageCaller_nullCaller_shouldCrash() {
mProvider.verifyLaunchSearchResultPageCaller(mActivity, null /* caller */);
}
@Test(expected = SecurityException.class)
- public void everifyLaunchSearchResultPageCaller_badCaller_shouldCrash() {
+ public void verifyLaunchSearchResultPageCaller_badCaller_shouldCrash() {
final ComponentName cn = new ComponentName("pkg", "class");
mProvider.verifyLaunchSearchResultPageCaller(mActivity, cn);
}
@Test
- public void verifyLaunchSearchResultPageCaller_goodCaller_shouldNotCrash() {
+ public void verifyLaunchSearchResultPageCaller_settingsCaller_shouldNotCrash() {
final ComponentName cn = new ComponentName(mActivity.getPackageName(), "class");
mProvider.verifyLaunchSearchResultPageCaller(mActivity, cn);
}
@Test
+ public void verifyLaunchSearchResultPageCaller_settingsIntelligenceCaller_shouldNotCrash() {
+ final ComponentName cn =
+ new ComponentName(mProvider.getSettingsIntelligencePkgName(), "class");
+ mProvider.verifyLaunchSearchResultPageCaller(mActivity, cn);
+ }
+
+ @Test
public void cleanQuery_trimsWhitespace() {
final String query = " space ";
final String cleanQuery = "space";
diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
index b4a91c5..3c51a90 100644
--- a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
+++ b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
@@ -114,11 +114,10 @@
continue;
}
// Must be in SearchProviderRegistry
- if (SearchIndexableResources.getResourceByName(className) == null) {
+ if (!SearchIndexableResources.providerValues().contains(clazz)) {
if (!notInSearchIndexableRegistryGrandfatherList.remove(className)) {
notInSearchProviderRegistry.add(className);
}
- continue;
}
}
diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java b/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
index 0e3ce50..eedb324 100644
--- a/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
+++ b/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
@@ -17,12 +17,13 @@
package com.android.settings.search;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE;
-import static com.android.settings.search.SearchIndexableResources.NO_RES_ID;
import static com.google.common.truth.Truth.assertThat;
+
+import static junit.framework.Assert.fail;
+
import static org.mockito.Mockito.spy;
import android.database.Cursor;
-import android.provider.SearchIndexableResource;
import android.text.TextUtils;
import com.android.settings.TestConfig;
@@ -35,60 +36,48 @@
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.HashSet;
+import java.util.Set;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SearchIndexableResourcesTest {
- Map<String, SearchIndexableResource> sResMapCopy;
+ Set<Class> sProviderClassCopy;
@Before
public void setUp() {
- sResMapCopy = new HashMap<>(SearchIndexableResources.sResMap);
+ sProviderClassCopy = new HashSet<>(SearchIndexableResources.sProviders);
}
@After
public void cleanUp() {
- SearchIndexableResources.sResMap.clear();
- for (String key : sResMapCopy.keySet()) {
- SearchIndexableResources.sResMap.put(key, sResMapCopy.get(key));
- }
+ SearchIndexableResources.sProviders.clear();
+ SearchIndexableResources.sProviders.addAll(sProviderClassCopy);
}
@Test
public void testAddIndex() {
+ final Class stringClass = java.lang.String.class;
// Confirms that String.class isn't contained in SearchIndexableResources.
- assertThat(SearchIndexableResources.getResourceByName("java.lang.String")).isNull();
- final int beforeCount = SearchIndexableResources.values().size();
+ assertThat(SearchIndexableResources.sProviders).doesNotContain(stringClass);
+ final int beforeCount = SearchIndexableResources.providerValues().size();
SearchIndexableResources.addIndex(java.lang.String.class);
- final SearchIndexableResource index = SearchIndexableResources
- .getResourceByName("java.lang.String");
- assertThat(index).isNotNull();
- assertThat(index.className).isEqualTo("java.lang.String");
- assertThat(index.xmlResId).isEqualTo(NO_RES_ID);
- assertThat(index.iconResId).isEqualTo(NO_RES_ID);
- final int afterCount = SearchIndexableResources.values().size();
+ assertThat(SearchIndexableResources.sProviders).contains(stringClass);
+ final int afterCount = SearchIndexableResources.providerValues().size();
assertThat(afterCount).isEqualTo(beforeCount + 1);
}
@Test
public void testIndexHasWifiSettings() {
- final SearchIndexableResource index = SearchIndexableResources
- .getResourceByName(WifiSettings.class.getName());
-
- assertThat(index).isNotNull();
- assertThat(index.className).isEqualTo(WifiSettings.class.getName());
- assertThat(index.xmlResId).isEqualTo(NO_RES_ID);
- assertThat(index.iconResId).isEqualTo(NO_RES_ID);
+ assertThat(sProviderClassCopy).contains(WifiSettings.class);
}
@Test
public void testNonIndexableKeys_GetsKeyFromProvider() {
- SearchIndexableResources.sResMap.clear();
+ SearchIndexableResources.sProviders.clear();
SearchIndexableResources.addIndex(FakeIndexProvider.class);
SettingsSearchIndexablesProvider provider = spy(new SettingsSearchIndexablesProvider());
@@ -105,4 +94,13 @@
assertThat(hasTestKey).isTrue();
}
+
+ @Test
+ public void testAllClassNamesHaveProviders() {
+ for (Class clazz: sProviderClassCopy) {
+ if(DatabaseIndexingUtils.getSearchIndexProvider(clazz) == null) {
+ fail(clazz.getName() + "is not an index provider");
+ }
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
new file mode 100644
index 0000000..efeaed7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
@@ -0,0 +1,119 @@
+package com.android.settings.search;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.ProviderInfo;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.SearchIndexablesContract;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.search.indexing.FakeSettingsFragment;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+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;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SettingsSearchIndexablesProviderTest {
+
+ private final String BASE_AUTHORITY = "com.android.settings";
+
+ private SettingsSearchIndexablesProvider mProvider;
+
+ Set<Class> sProviderClasses;
+ Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+
+ mProvider = spy(new SettingsSearchIndexablesProvider());
+ ProviderInfo info = new ProviderInfo();
+ info.exported = true;
+ info.grantUriPermissions = true;
+ info.authority = BASE_AUTHORITY;
+ info.readPermission = Manifest.permission.READ_SEARCH_INDEXABLES;
+ mProvider.attachInfo(mContext, info);
+
+ sProviderClasses = new HashSet<>(SearchIndexableResources.sProviders);
+ SearchIndexableResources.sProviders.clear();
+ SearchIndexableResources.sProviders.add(FakeSettingsFragment.class);
+ }
+
+ @After
+ public void cleanUp() {
+ SearchIndexableResources.sProviders.clear();
+ SearchIndexableResources.sProviders.addAll(sProviderClasses);
+ }
+
+ @Test
+ public void testRawColumnFetched() {
+ Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" +
+ SearchIndexablesContract.INDEXABLES_RAW_PATH);
+
+ final Cursor cursor = mProvider.query(rawUri,
+ SearchIndexablesContract.INDEXABLES_RAW_COLUMNS, null, null, null);
+
+ cursor.moveToFirst();
+ assertThat(cursor.getString(1)).isEqualTo(FakeSettingsFragment.TITLE);
+ assertThat(cursor.getString(2)).isEqualTo(FakeSettingsFragment.SUMMARY_ON);
+ assertThat(cursor.getString(3)).isEqualTo(FakeSettingsFragment.SUMMARY_OFF);
+ assertThat(cursor.getString(4)).isEqualTo(FakeSettingsFragment.ENTRIES);
+ assertThat(cursor.getString(5)).isEqualTo(FakeSettingsFragment.KEYWORDS);
+ assertThat(cursor.getString(6)).isEqualTo(FakeSettingsFragment.SCREEN_TITLE);
+ assertThat(cursor.getString(7)).isEqualTo(FakeSettingsFragment.CLASS_NAME);
+ assertThat(cursor.getInt(8)).isEqualTo(FakeSettingsFragment.ICON);
+ assertThat(cursor.getString(9)).isEqualTo(FakeSettingsFragment.INTENT_ACTION);
+ assertThat(cursor.getString(10)).isEqualTo(FakeSettingsFragment.TARGET_PACKAGE);
+ assertThat(cursor.getString(11)).isEqualTo(FakeSettingsFragment.TARGET_CLASS);
+ assertThat(cursor.getString(12)).isEqualTo(FakeSettingsFragment.KEY);
+ }
+
+ @Test
+ public void testResourcesColumnFetched() {
+ Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" +
+ SearchIndexablesContract.INDEXABLES_XML_RES_PATH);
+
+ final Cursor cursor = mProvider.query(rawUri,
+ SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS, null, null, null);
+
+ cursor.moveToFirst();
+ assertThat(cursor.getCount()).isEqualTo(1);
+ assertThat(cursor.getInt(1)).isEqualTo(R.xml.display_settings);
+ assertThat(cursor.getString(2)).isEqualTo(FakeSettingsFragment.CLASS_NAME);
+ assertThat(cursor.getInt(3)).isEqualTo(0);
+ assertThat(cursor.getString(4)).isNull();
+ assertThat(cursor.getString(5)).isNull();
+ assertThat(cursor.getString(6)).isNull();
+ }
+
+ @Test
+ public void testNonIndexablesColumnFetched() {
+ Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" +
+ SearchIndexablesContract.NON_INDEXABLES_KEYS_PATH);
+ //final ContentResolver resolver = mContext.getContentResolver();
+
+ final Cursor cursor = mProvider.query(rawUri,
+ SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS, null, null, null);
+
+ cursor.moveToFirst();
+ assertThat(cursor.getCount()).isEqualTo(2);
+ assertThat(cursor.getString(0)).isEqualTo("pref_key_1");
+ cursor.moveToNext();
+ assertThat(cursor.getString(0)).isEqualTo("pref_key_3");
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java b/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java
index b95bfe8..0f2ab56 100644
--- a/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java
+++ b/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java
@@ -266,55 +266,6 @@
assertThat(row.iconResId).isGreaterThan(0);
}
- // Tests for the flow: IndexOneResource -> IndexFromProvider -> IndexFromResource ->
- // UpdateOneRowWithFilteredData -> UpdateOneRow
-
- @Test
- public void testAddProviderWithResource_rowInserted() {
- final SearchIndexableResource resource = getFakeResource(0 /* xml */);
- resource.className = FAKE_CLASS_NAME;
- final PreIndexData preIndexData = new PreIndexData();
- preIndexData.dataToUpdate.add(resource);
-
- List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData);
-
- assertThat(indexData.size()).isEqualTo(NUM_FAKE_FRAGMENT_ENTRIES);
- assertThat(findIndexDataForTitle(indexData, PAGE_TITLE)).isNotNull();
- assertThat(findIndexDataForTitle(indexData, TITLE_ONE)).isNotNull();
- assertThat(findIndexDataForTitle(indexData, TITLE_TWO)).isNotNull();
- assertThat(findIndexDataForTitle(indexData, TITLE_THREE)).isNotNull();
- assertThat(findIndexDataForTitle(indexData, TITLE_FOUR)).isNotNull();
- assertThat(findIndexDataForTitle(indexData, TITLE_FIVE)).isNotNull();
- assertThat(findIndexDataForTitle(indexData, FakeSettingsFragment.TITLE)).isNotNull();
- }
-
- @Test
- public void testAddProviderWithRaw_rowInserted() {
- final SearchIndexableResource resource = getFakeResource(0 /* xml */);
- resource.className = FAKE_CLASS_NAME;
- final PreIndexData preIndexData = new PreIndexData();
- preIndexData.dataToUpdate.add(resource);
-
- List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData);
-
- final IndexData data = findIndexDataForTitle(indexData, FakeSettingsFragment.TITLE);
- assertFakeFragment(data);
- }
-
- @Test
- public void testAddProvider_disabledRows() {
- // Note that in FakeSettingsFragment, preferences 1 and 3 are disabled.
- final SearchIndexableResource resource = getFakeResource(0 /* xml */);
- resource.className = FAKE_CLASS_NAME;
-
- final PreIndexData preIndexData = new PreIndexData();
- preIndexData.dataToUpdate.add(resource);
-
- List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData);
-
- assertThat(getEnabledResultCount(indexData)).isEqualTo(NUM_ENABLED_FAKE_FRAGMENT_ENTRIES);
- }
-
@Test
public void testResource_sameTitleForSettingAndPage_titleNotInserted() {
final SearchIndexableResource resource = getFakeResource(R.xml.about_legal);
diff --git a/tests/robotests/src/com/android/settings/security/RestrictedEncryptionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/RestrictedEncryptionPreferenceControllerTest.java
index 8db6795..59b267f 100644
--- a/tests/robotests/src/com/android/settings/security/RestrictedEncryptionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/RestrictedEncryptionPreferenceControllerTest.java
@@ -46,16 +46,18 @@
private InstallCredentialsPreferenceController mInstallCredentialsPreferenceController;
private ResetCredentialsPreferenceController mResetCredentialsPreferenceController;
private UserCredentialsPreferenceController mUserCredentialsPreferenceController;
+ private Lifecycle mLifecycle;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
+ mLifecycle = new Lifecycle(() -> mLifecycle);
mCredentialStoragePreferenceController =
new CredentialStoragePreferenceController(mContext);
mInstallCredentialsPreferenceController =
new InstallCredentialsPreferenceController(mContext);
mResetCredentialsPreferenceController =
- new ResetCredentialsPreferenceController(mContext, new Lifecycle());
+ new ResetCredentialsPreferenceController(mContext, mLifecycle);
mUserCredentialsPreferenceController =
new UserCredentialsPreferenceController(mContext);
mUserManager = ShadowUserManager.getShadow();
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSettingsPreferenceFragment.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSettingsPreferenceFragment.java
new file mode 100644
index 0000000..586ff48
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSettingsPreferenceFragment.java
@@ -0,0 +1,38 @@
+/*
+ * 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.os.Bundle;
+
+import com.android.settings.SettingsPreferenceFragment;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Shadow of {@link SettingsPreferenceFragment}.
+ *
+ * Override the {@link #onCreate(Bundle)} to skip a null pointer exception in
+ * {@link android.content.res.Resources.Theme}, much the same as {@link ShadowDashboardFragment}.
+ */
+@Implements(SettingsPreferenceFragment.class)
+public class ShadowSettingsPreferenceFragment {
+
+ @Implementation
+ public void onCreate(Bundle savedInstanceState) {
+ // do nothing
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
index a578364..56f3949 100644
--- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
@@ -16,27 +16,28 @@
package com.android.settings.users;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.app.Activity;
import android.content.pm.UserInfo;
import android.os.UserManager;
import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.dashboard.SummaryLoader;
+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.annotation.Config;
import org.robolectric.Robolectric;
-
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -70,4 +71,9 @@
mActivity.getString(R.string.users_summary, name));
}
+ @Test
+ public void testAssignDefaultPhoto_ContextNull_ReturnFalseAndNotCrash() {
+ // Should not crash here
+ assertThat(UserSettings.assignDefaultPhoto(null, 0)).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wallpaper/WallpaperSuggestionActivityTest.java b/tests/robotests/src/com/android/settings/wallpaper/WallpaperSuggestionActivityTest.java
index 49a678f..b8fe81e 100644
--- a/tests/robotests/src/com/android/settings/wallpaper/WallpaperSuggestionActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wallpaper/WallpaperSuggestionActivityTest.java
@@ -42,7 +42,7 @@
import org.robolectric.shadows.ShadowActivity;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
shadows = {
WallpaperSuggestionActivityTest.ShadowWallpaperManagerWrapper.class
})
@@ -67,6 +67,8 @@
final Intent intent = activity.getNextStartedActivity();
assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName());
+ assertThat(intent.getFlags()).isEqualTo(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ assertThat(activity.isFinishing()).isTrue();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/wallpaper/WallpaperTypeSettingsTest.java b/tests/robotests/src/com/android/settings/wallpaper/WallpaperTypeSettingsTest.java
new file mode 100644
index 0000000..7e15f7a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wallpaper/WallpaperTypeSettingsTest.java
@@ -0,0 +1,67 @@
+package com.android.settings.wallpaper;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.robolectric.RuntimeEnvironment.application;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.support.v7.preference.Preference;
+
+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.ArgumentCaptor;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class WallpaperTypeSettingsTest {
+
+ private Preference mPreference;
+
+ private Intent mIntent;
+
+ @Before
+ public void setUp() {
+ mIntent = new Intent();
+ mPreference = new Preference(application);
+ }
+
+ @Test
+ public void testOnPreferenceTreeClick_intentNull_shouldDoNothing() {
+ Activity activity = Robolectric.setupActivity(Activity.class);
+ WallpaperTypeSettings fragment = spy(new WallpaperTypeSettings());
+ doReturn(activity).when(fragment).getActivity();
+
+ boolean handled = fragment.onPreferenceTreeClick(mPreference);
+
+ assertThat(handled).isFalse();
+ }
+
+ @Test
+ public void testOnPreferenceTreeClick_shouldLaunchIntentAndFinish() {
+ Activity activity = Robolectric.setupActivity(Activity.class);
+ WallpaperTypeSettings fragment = spy(new WallpaperTypeSettings());
+ doReturn(activity).when(fragment).getActivity();
+ mPreference.setIntent(mIntent);
+ doNothing().when(fragment).finish();
+ ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
+ doNothing().when(fragment).startActivity(intent.capture());
+
+ boolean handled = fragment.onPreferenceTreeClick(mPreference);
+
+ assertThat(handled).isTrue();
+ verify(fragment, times(1)).finish();
+ assertThat(intent.getValue()).isSameAs(mIntent);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/widget/ActionBarShadowControllerTest.java b/tests/robotests/src/com/android/settings/widget/ActionBarShadowControllerTest.java
index 41ba1e4..0f3eb31 100644
--- a/tests/robotests/src/com/android/settings/widget/ActionBarShadowControllerTest.java
+++ b/tests/robotests/src/com/android/settings/widget/ActionBarShadowControllerTest.java
@@ -17,7 +17,11 @@
package com.android.settings.widget;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -31,7 +35,6 @@
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
import org.junit.Before;
import org.junit.Test;
@@ -40,9 +43,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import org.robolectric.util.ReflectionHelpers;
-
-import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -62,7 +62,7 @@
MockitoAnnotations.initMocks(this);
when(mActivity.getActionBar()).thenReturn(mActionBar);
mView = new View(RuntimeEnvironment.application);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
}
@Test
@@ -93,14 +93,13 @@
public void attachToRecyclerView_lifecycleChange_shouldAttachDetach() {
ActionBarShadowController.attachToRecyclerView(mActivity, mLifecycle, mRecyclerView);
- List<LifecycleObserver> observers = ReflectionHelpers.getField(mLifecycle, "mObservers");
- assertThat(observers).hasSize(1);
verify(mRecyclerView).addOnScrollListener(any());
- mLifecycle.onStop();
+ mLifecycle.handleLifecycleEvent(ON_START);
+ mLifecycle.handleLifecycleEvent(ON_STOP);
verify(mRecyclerView).removeOnScrollListener(any());
- mLifecycle.onStart();
+ mLifecycle.handleLifecycleEvent(ON_START);
verify(mRecyclerView, times(2)).addOnScrollListener(any());
}
diff --git a/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
new file mode 100644
index 0000000..2eaa587
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.wifi.AccessPoint;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ConnectedAccessPointPreferenceTest {
+ @Mock
+ private AccessPoint mAccessPoint;
+ @Mock
+ private View mView;
+ @Mock
+ private ConnectedAccessPointPreference.OnGearClickListener mOnGearClickListener;
+ private Context mContext;
+ private ConnectedAccessPointPreference mConnectedAccessPointPreference;
+
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ mConnectedAccessPointPreference = new ConnectedAccessPointPreference(mAccessPoint, mContext,
+ null, 0 /* iconResId */, false /* forSavedNetworks */);
+ mConnectedAccessPointPreference.setOnGearClickListener(mOnGearClickListener);
+ }
+
+ @Test
+ public void testOnClick_gearClicked_listenerInvoked() {
+ doReturn(R.id.settings_button).when(mView).getId();
+
+ mConnectedAccessPointPreference.onClick(mView);
+
+ verify(mOnGearClickListener).onGearClick(mConnectedAccessPointPreference);
+ }
+
+ @Test
+ public void testOnClick_gearNotClicked_listenerNotInvoked() {
+ mConnectedAccessPointPreference.onClick(mView);
+
+ verify(mOnGearClickListener, never()).onGearClick(mConnectedAccessPointPreference);
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiInfoPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiInfoPreferenceControllerTest.java
index 1650816..cf3cca7 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiInfoPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiInfoPreferenceControllerTest.java
@@ -16,6 +16,16 @@
package com.android.settings.wifi;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
@@ -23,8 +33,8 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -35,12 +45,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class WifiInfoPreferenceControllerTest {
@@ -62,7 +66,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
when(mContext.getSystemService(WifiManager.class))
.thenReturn(mWifiManager);
when(mScreen.findPreference(anyString()))
@@ -83,10 +87,10 @@
@Test
public void runThroughLifecycle_shouldInstallListenerOnResume() {
- mLifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
- mLifecycle.onPause();
+ mLifecycle.handleLifecycleEvent(ON_PAUSE);
verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
}
diff --git a/tests/robotests/src/com/android/settings/wifi/WpsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WpsPreferenceControllerTest.java
index 94cc46b..7a734e5 100644
--- a/tests/robotests/src/com/android/settings/wifi/WpsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WpsPreferenceControllerTest.java
@@ -15,7 +15,11 @@
*/
package com.android.settings.wifi;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.times;
@@ -31,8 +35,8 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -66,7 +70,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
when(mContext.getSystemService(WifiManager.class))
.thenReturn(mWifiManager);
when(mScreen.findPreference(anyString()))
@@ -83,12 +87,13 @@
@Test
public void testOnResume_shouldRegisterListener() {
- mLifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
}
@Test
public void testOnPause_shouldUnregisterListener() {
- mLifecycle.onPause();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
+ mLifecycle.handleLifecycleEvent(ON_PAUSE);
verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
}
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index aa21a19..6e3fa32 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -16,6 +16,7 @@
package com.android.settings.wifi.details;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -203,7 +204,7 @@
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfig);
when(mockAccessPoint.getLevel()).thenReturn(LEVEL);
diff --git a/tests/robotests/src/com/android/settings/wifi/p2p/P2pCategoryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/p2p/P2pCategoryPreferenceControllerTest.java
index dd2ef52..e53fb87 100644
--- a/tests/robotests/src/com/android/settings/wifi/p2p/P2pCategoryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/p2p/P2pCategoryPreferenceControllerTest.java
@@ -16,12 +16,19 @@
package com.android.settings.wifi.p2p;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceScreen;
-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;
@@ -31,13 +38,8 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class P2pCategoryPreferenceControllerTest {
@Mock
@@ -81,7 +83,8 @@
mController.addChild(pref);
verify(mCategory).addPreference(pref);
- verify(mCategory).setVisible(true);
+ verify(mCategory, atLeastOnce()).setVisible(true);
+ verify(mCategory, never()).setVisible(false);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2PPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2PPreferenceControllerTest.java
index 8946a5e..e809431 100644
--- a/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2PPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2PPreferenceControllerTest.java
@@ -15,7 +15,11 @@
*/
package com.android.settings.wifi.p2p;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.times;
@@ -30,8 +34,8 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -61,7 +65,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
when(mContext.getSystemService(WifiManager.class))
.thenReturn(mWifiManager);
when(mScreen.findPreference(anyString()))
@@ -76,13 +80,14 @@
@Test
public void testOnResume_shouldRegisterListener() {
- mLifecycle.onResume();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
}
@Test
public void testOnPause_shouldUnregisterListener() {
- mLifecycle.onPause();
+ mLifecycle.handleLifecycleEvent(ON_RESUME);
+ mLifecycle.handleLifecycleEvent(ON_PAUSE);
verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
}
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java
index ff3f47e..9d24e78 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java
@@ -16,7 +16,11 @@
package com.android.settings.wifi.tether;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
@@ -84,7 +88,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mLifecycle = new Lifecycle();
+ mLifecycle = new Lifecycle(() -> mLifecycle);
FakeFeatureFactory.setupForTest(mFeatureFactoryContext);
mPreference = new MasterSwitchPreference(RuntimeEnvironment.application);
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
@@ -119,8 +123,8 @@
final BroadcastReceiver receiver = ReflectionHelpers.getField(mController, "mReceiver");
mController.displayPreference(mScreen);
- mLifecycle.onStart();
- mLifecycle.onStop();
+ mLifecycle.handleLifecycleEvent(ON_START);
+ mLifecycle.handleLifecycleEvent(ON_STOP);
assertThat(ShadowWifiTetherSwitchBarController.onStartCalled).isTrue();
assertThat(ShadowWifiTetherSwitchBarController.onStopCalled).isTrue();
@@ -136,7 +140,7 @@
when(mScreen.findPreference(anyString())).thenReturn(pref);
mController.displayPreference(mScreen);
- mLifecycle.onStart();
+ mLifecycle.handleLifecycleEvent(ON_START);
assertThat(ShadowWifiTetherSwitchBarController.onStartCalled).isTrue();
verify(mContext).registerReceiver(eq(receiver), any(IntentFilter.class));
@@ -151,7 +155,7 @@
when(mScreen.findPreference(anyString())).thenReturn(pref);
mController.displayPreference(mScreen);
- mLifecycle.onStart();
+ mLifecycle.handleLifecycleEvent(ON_START);
assertThat(ShadowWifiTetherSwitchBarController.onStartCalled).isTrue();
verify(mContext).registerReceiver(eq(receiver), any(IntentFilter.class));
diff --git a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
index c75ca13..bc82125 100644
--- a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
+++ b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
@@ -54,8 +54,7 @@
public void controllersInSearchShouldImplementPreferenceControllerMixin() {
final Set<String> errorClasses = new ArraySet<>();
- for (SearchIndexableResource page : SearchIndexableResources.values()) {
- final Class<?> clazz = DatabaseIndexingUtils.getIndexableClass(page.className);
+ for (Class clazz: SearchIndexableResources.providerValues()) {
final Indexable.SearchIndexProvider provider =
DatabaseIndexingUtils.getSearchIndexProvider(clazz);
diff --git a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
index 4c51772..5f3e512 100644
--- a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
+++ b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
@@ -90,8 +90,8 @@
final Set<String> uniqueKeys = new HashSet<>();
final Set<String> nullKeyClasses = new HashSet<>();
final Set<String> duplicatedKeys = new HashSet<>();
- for (SearchIndexableResource sir : SearchIndexableResources.values()) {
- verifyPreferenceIdInXml(uniqueKeys, duplicatedKeys, nullKeyClasses, sir);
+ for (Class<?> clazz : SearchIndexableResources.providerValues()) {
+ verifyPreferenceIdInXml(uniqueKeys, duplicatedKeys, nullKeyClasses, clazz);
}
if (!nullKeyClasses.isEmpty()) {
@@ -115,22 +115,24 @@
}
private void verifyPreferenceIdInXml(Set<String> uniqueKeys, Set<String> duplicatedKeys,
- Set<String> nullKeyClasses, SearchIndexableResource page)
+ Set<String> nullKeyClasses, Class<?> clazz)
throws IOException, XmlPullParserException, Resources.NotFoundException {
- final Class<?> clazz = DatabaseIndexingUtils.getIndexableClass(page.className);
-
+ if (clazz == null) {
+ return;
+ }
+ final String className = clazz.getName();
final Indexable.SearchIndexProvider provider =
DatabaseIndexingUtils.getSearchIndexProvider(clazz);
final List<SearchIndexableResource> resourcesToIndex =
provider.getXmlResourcesToIndex(mContext, true);
if (resourcesToIndex == null) {
- Log.d(TAG, page.className + "is not providing SearchIndexableResource, skipping");
+ Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
return;
}
for (SearchIndexableResource sir : resourcesToIndex) {
if (sir.xmlResId <= 0) {
- Log.d(TAG, page.className + " doesn't have a valid xml to index.");
+ Log.d(TAG, className + " doesn't have a valid xml to index.");
continue;
}
final XmlResourceParser parser = mContext.getResources().getXml(sir.xmlResId);
@@ -154,14 +156,14 @@
final String key = XmlParserUtils.getDataKey(mContext, attrs);
if (TextUtils.isEmpty(key)) {
Log.e(TAG, "Every preference must have an key; found null key"
- + " in " + page.className
+ + " in " + className
+ " at " + parser.getPositionDescription());
- nullKeyClasses.add(page.className);
+ nullKeyClasses.add(className);
continue;
}
if (uniqueKeys.contains(key) && !WHITELISTED_DUPLICATE_KEYS.contains(key)) {
Log.e(TAG, "Every preference key must unique; found " + nodeName
- + " in " + page.className
+ + " in " + className
+ " at " + parser.getPositionDescription());
duplicatedKeys.add(key);
}
diff --git a/tests/unit/src/com/android/settings/search/SearchIndexablesContractTest.java b/tests/unit/src/com/android/settings/search/SearchIndexablesContractTest.java
index 4de5fb7..2e779e8 100644
--- a/tests/unit/src/com/android/settings/search/SearchIndexablesContractTest.java
+++ b/tests/unit/src/com/android/settings/search/SearchIndexablesContractTest.java
@@ -17,105 +17,52 @@
package com.android.settings.search;
+import static com.google.common.truth.Truth.assertThat;
+
import android.provider.SearchIndexablesContract;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-public class SearchIndexablesContractTest extends AndroidTestCase {
- @SmallTest
- public void testRawColumns_IncludesRank() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_RANK,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[0]);
- }
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SearchIndexablesContractTest {
- @SmallTest
- public void testRawColumns_IncludesTitle() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_TITLE,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[1]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesSummaryOn() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_SUMMARY_ON,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[2]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesSummaryOff() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_SUMMARY_OFF,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[3]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesEntries() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_ENTRIES,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[4]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesKeywords() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_KEYWORDS,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[5]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesScreenTitle() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_SCREEN_TITLE,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[6]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesClassName() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_CLASS_NAME,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[7]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesIcon() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_ICON_RESID,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[8]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesIntentAction() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_INTENT_ACTION,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[9]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesIntentTargetPackage() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_INTENT_TARGET_PACKAGE,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[10]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesTargetClass() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_INTENT_TARGET_CLASS,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[11]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesKey() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_KEY,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[12]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesUserId() {
- assertEquals(SearchIndexablesContract.RawData.COLUMN_USER_ID,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[13]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesPayloadType() {
- assertEquals(SearchIndexablesContract.RawData.PAYLOAD_TYPE,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[14]);
- }
-
- @SmallTest
- public void testRawColumns_IncludesPayload() {
- assertEquals(SearchIndexablesContract.RawData.PAYLOAD,
- SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[15]);
- }
+ @Test
+ public void testRawColumns_matchContractIndexing() {
+ assertThat(SearchIndexablesContract.RawData.COLUMN_RANK)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[0]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_TITLE)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[1]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_SUMMARY_ON)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[2]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_SUMMARY_OFF)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[3]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_ENTRIES)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[4]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_KEYWORDS)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[5]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_SCREEN_TITLE)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[6]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_CLASS_NAME)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[7]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_ICON_RESID)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[8]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_INTENT_ACTION)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[9]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_INTENT_TARGET_PACKAGE)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[10]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_INTENT_TARGET_CLASS)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[11]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_KEY)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[12]);
+ assertThat(SearchIndexablesContract.RawData.COLUMN_USER_ID)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[13]);
+ assertThat(SearchIndexablesContract.RawData.PAYLOAD_TYPE)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[14]);
+ assertThat(SearchIndexablesContract.RawData.PAYLOAD)
+ .isEqualTo(SearchIndexablesContract.INDEXABLES_RAW_COLUMNS[15]);
+ }
}
diff --git a/tests/unit/src/com/android/settings/search/SearchResultTrampolineTest.java b/tests/unit/src/com/android/settings/search/SearchResultTrampolineTest.java
new file mode 100644
index 0000000..974518f
--- /dev/null
+++ b/tests/unit/src/com/android/settings/search/SearchResultTrampolineTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.search;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SearchResultTrampolineTest {
+
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = InstrumentationRegistry.getTargetContext();
+ }
+
+ @Test
+ public void canLaunchSettingsTrampolineWithIntentAction() {
+ final PackageManager pm = mContext.getPackageManager();
+ final ResolveInfo info =
+ pm.resolveActivity(new Intent("com.android.settings.SEARCH_RESULT_TRAMPOLINE"), 0);
+
+ assertThat(info.activityInfo.name)
+ .isEqualTo(SearchResultTrampoline.class.getName());
+
+ }
+}