Merge "Base implementation of WFC disclaimer UI"
diff --git a/res/drawable/ic_face_header.xml b/res/drawable/ic_face_header.xml
index 0bf2c07..15ea7ae 100644
--- a/res/drawable/ic_face_header.xml
+++ b/res/drawable/ic_face_header.xml
@@ -1,4 +1,4 @@
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2018 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,10 +15,17 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="32dp"
android:width="32dp"
+ android:height="32dp"
android:tint="?android:attr/colorPrimary"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path android:fillColor="#000" android:pathData="M9,11.75A1.25,1.25 0 0,0 7.75,13A1.25,1.25 0 0,0 9,14.25A1.25,1.25 0 0,0 10.25,13A1.25,1.25 0 0,0 9,11.75M15,11.75A1.25,1.25 0 0,0 13.75,13A1.25,1.25 0 0,0 15,14.25A1.25,1.25 0 0,0 16.25,13A1.25,1.25 0 0,0 15,11.75M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20C7.59,20 4,16.41 4,12C4,11.71 4,11.42 4.05,11.14C6.41,10.09 8.28,8.16 9.26,5.77C11.07,8.33 14.05,10 17.42,10C18.2,10 18.95,9.91 19.67,9.74C19.88,10.45 20,11.21 20,12C20,16.41 16.41,20 12,20Z" />
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 12 13 C 13.1045694997 13 14 13.8954305003 14 15 C 14 16.1045694997 13.1045694997 17 12 17 C 10.8954305003 17 10 16.1045694997 10 15 C 10 13.8954305003 10.8954305003 13 12 13 Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M18.5,1C16.01,1,14,3.01,14,5.5V8H6c-1.1,0-2,0.9-2,2v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10c0-1.1-0.9-2-2-2h-2V5.5 C16,4.12,17.12,3,18.5,3C19.88,3,21,4.12,21,5.5V6h2V5.5C23,3.01,20.99,1,18.5,1z M18,10v10H6V10H18z" />
+ <path android:pathData="M0,0h24v24H0V0z" />
</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_notification_alert.xml b/res/drawable/ic_notification_alert.xml
new file mode 100644
index 0000000..07e7b48
--- /dev/null
+++ b/res/drawable/ic_notification_alert.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2019 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/back">
+ <shape android:shape="oval">
+ <solid
+ android:color="@android:color/transparent" />
+ <size
+ android:height="48dp"
+ android:width="48dp"/>
+ <stroke android:width="1dp"
+ android:color="@color/notification_alert_color"/>
+ </shape>
+ </item>
+ <item
+ android:id="@+id/fore"
+ android:gravity="center">
+ <vector
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <path
+ android:fillColor="@color/notification_alert_color"
+ android:pathData="M7.58 4.08L6.15 2.65C3.75 4.48 2.17 7.3 2.03 10.5h2c.15-2.65 1.51-4.97 3.55-6.42zm12.39 6.42h2c-.15-3.2-1.73-6.02-4.12-7.85l-1.42 1.43c2.02 1.45 3.39 3.77 3.54 6.42zM18 11c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2v-5zm-6 11c.14 0 .27-.01.4-.04.65-.14 1.18-.58 1.44-1.18.1-.24.15-.5.15-.78h-4c.01 1.1.9 2 2.01 2z"/>
+ </vector>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/ic_notification_block.xml b/res/drawable/ic_notification_block.xml
new file mode 100644
index 0000000..d4f0a2a
--- /dev/null
+++ b/res/drawable/ic_notification_block.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2019 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/back">
+ <shape android:shape="oval">
+ <solid
+ android:color="@android:color/transparent" />
+ <size
+ android:height="48dp"
+ android:width="48dp"/>
+ <stroke android:width="1dp"
+ android:color="@color/notification_block_color"/>
+ </shape>
+ </item>
+ <item
+ android:id="@+id/fore"
+ android:gravity="center">
+ <vector
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <path
+ android:fillColor="@color/notification_block_color"
+ android:pathData="M12.0,2.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0zM4.0,12.0c0.0,-4.42 3.58,-8.0 8.0,-8.0 1.85,0.0 3.5,0.63 4.9,1.69L5.69,16.9C4.63,15.55 4.0,13.85 4.0,12.0zm8.0,8.0c-1.85,0.0 -3.55,-0.63 -4.9,-1.69L18.31,7.1C19.37,8.45 20.0,10.15 20.0,12.0c0.0,4.42 -3.58,8.0 -8.0,8.0z"/>
+ </vector>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/ic_notification_silence.xml b/res/drawable/ic_notification_silence.xml
new file mode 100644
index 0000000..673340f
--- /dev/null
+++ b/res/drawable/ic_notification_silence.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2019 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/back">
+ <shape android:shape="oval">
+ <solid
+ android:color="@android:color/transparent" />
+ <size
+ android:height="48dp"
+ android:width="48dp"/>
+ <stroke android:width="1dp"
+ android:color="@color/notification_silence_color"/>
+ </shape>
+ </item>
+ <item
+ android:id="@+id/fore"
+ android:gravity="center">
+ <vector
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <path
+ android:fillColor="@color/notification_silence_color"
+ android:pathData="M20 18.69L7.84 6.14 5.27 3.49 4 4.76l2.8 2.8v.01c-.52.99-.8 2.16-.8 3.42v5l-2 2v1h13.73l2 2L21 19.72l-1-1.03zM12 22c1.11 0 2-.89 2-2h-4c0 1.11.89 2 2 2zm6-7.32V11c0-3.08-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68c-.15.03-.29.08-.42.12-.1.03-.2.07-.3.11h-.01c-.01 0-.01 0-.02.01-.23.09-.46.2-.68.31 0 0-.01 0-.01.01L18 14.68z" />
+ </vector>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/layout/notif_importance_preference.xml b/res/layout/notif_importance_preference.xml
new file mode 100644
index 0000000..5d79ff3
--- /dev/null
+++ b/res/layout/notif_importance_preference.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/app_entities_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="horizontal">
+
+ <LinearLayout
+ android:id="@+id/block"
+ android:layout_width="0dp"
+ android:layout_weight="33.33"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp"
+ android:layout_marginTop="16dp"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <ImageButton
+ android:id="@+id/block_icon"
+ android:layout_width="@dimen/notification_importance_toggle_size"
+ android:layout_height="@dimen/notification_importance_toggle_size"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:src="@drawable/ic_notification_block"
+ android:contentDescription="@string/notification_block_title" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/notification_block_title"
+ android:layout_marginTop="@dimen/notification_importance_toggle_marginTop"
+ android:layout_marginBottom="@dimen/notification_importance_toggle_marginBottom"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/silence"
+ android:layout_width="0dp"
+ android:layout_weight="33.33"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp"
+ android:layout_marginTop="16dp"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <ImageButton
+ android:id="@+id/silence_icon"
+ android:layout_width="@dimen/notification_importance_toggle_size"
+ android:layout_height="@dimen/notification_importance_toggle_size"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:src="@drawable/ic_notification_silence"
+ android:contentDescription="@string/notification_silence_title" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/notification_silence_title"
+ android:layout_marginTop="@dimen/notification_importance_toggle_marginTop"
+ android:layout_marginBottom="@dimen/notification_importance_toggle_marginBottom"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/alert"
+ android:layout_width="0dp"
+ android:layout_weight="33.33"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp"
+ android:layout_marginTop="16dp"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <ImageButton
+ android:id="@+id/alert_icon"
+ android:layout_width="@dimen/notification_importance_toggle_size"
+ android:layout_height="@dimen/notification_importance_toggle_size"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:src="@drawable/ic_notification_alert"
+ android:contentDescription="@string/notification_alert_title" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/notification_alert_title"
+ android:layout_marginTop="@dimen/notification_importance_toggle_marginTop"
+ android:layout_marginBottom="@dimen/notification_importance_toggle_marginBottom"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" />
+ </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 7b55a2b..0afd288 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -56,7 +56,7 @@
<color name="material_blue_700">#3367D6</color>
<color name="material_grey_100">#f5f5f5</color>
<color name="material_grey_200">#ffffff</color>
- <color name="switch_bar_background">#ff80868B</color>
+ <color name="switch_bar_background">#757575</color>
<color name="message_text_incoming">#ffffffff</color>
<color name="message_text_outgoing">#ff323232</color>
@@ -124,6 +124,11 @@
<color name="face_anim_particle_color_4">#fffdd835</color> <!-- Material Yellow 600 -->
<color name="face_anim_particle_error">#ff9e9e9e</color> <!-- Material Gray 500 -->
+ <!-- notification settings -->
+ <color name="notification_block_color">#ffff0000</color>
+ <color name="notification_silence_color">#fbbc04</color>
+ <color name="notification_alert_color">#30a751</color>
+
<!-- launcher icon color -->
<color name="icon_launcher_setting_color">@*android:color/accent_device_default_light</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a36d8ab..f5b6e95 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -68,6 +68,9 @@
<dimen name="notification_app_icon_size">64dp</dimen>
<dimen name="notification_app_icon_badge_size">20dp</dimen>
<dimen name="notification_app_icon_badge_margin">4dp</dimen>
+ <dimen name="notification_importance_toggle_size">48dp</dimen>
+ <dimen name="notification_importance_toggle_marginTop">8dp</dimen>
+ <dimen name="notification_importance_toggle_marginBottom">16dp</dimen>
<dimen name="zen_schedule_rule_checkbox_padding">7dp</dimen>
<dimen name="zen_schedule_day_margin">17dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 01bc56e..aa43f12 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3022,14 +3022,14 @@
<string name="status_prl_version">PRL version</string>
<!-- About phone screen, title for MEID for multi-sim devices -->
<string name="meid_multi_sim">MEID (sim slot %1$d)</string>
- <!-- The status text when both Wi-Fi scanning and Bluetooth scanning are on. [CHAR LIMIT=120] -->
- <string name="scanning_status_text_wifi_on_ble_on">Both Wi\u2011Fi and Bluetooth are allowed to determine location</string>
- <!-- The status text when Wi-Fi scanning is on and Bluetooth scanning are off. [CHAR LIMIT=120] -->
- <string name="scanning_status_text_wifi_on_ble_off">Only Wi\u2011Fi is allowed to determine location</string>
- <!-- The status text when Wi-Fi scanning is off and Bluetooth scanning are on. [CHAR LIMIT=120] -->
- <string name="scanning_status_text_wifi_off_ble_on">Only Bluetooth is allowed to determine location</string>
- <!-- The status text when both Wi-Fi scanning and Bluetooth scanning are off. [CHAR LIMIT=120] -->
- <string name="scanning_status_text_wifi_off_ble_off">Neither Wi\u2011Fi nor Bluetooth is allowed to determine location</string>
+ <!-- The status text when both Wi-Fi scanning and Bluetooth scanning are on. [CHAR LIMIT=100] -->
+ <string name="scanning_status_text_wifi_on_ble_on">Both Wi\u2011Fi and Bluetooth scanning are on</string>
+ <!-- The status text when Wi-Fi scanning is on and Bluetooth scanning are off. [CHAR LIMIT=100] -->
+ <string name="scanning_status_text_wifi_on_ble_off">Wi\u2011Fi scanning is on, Bluetooth scanning is off</string>
+ <!-- The status text when Wi-Fi scanning is off and Bluetooth scanning are on. [CHAR LIMIT=100] -->
+ <string name="scanning_status_text_wifi_off_ble_on">Bluetooth scanning is on, Wi\u2011Fi scanning is off</string>
+ <!-- The status text when both Wi-Fi scanning and Bluetooth scanning are off. [CHAR LIMIT=100] -->
+ <string name="scanning_status_text_wifi_off_ble_off">Both Wi\u2011Fi and Bluetooth scanning are off</string>
<!-- About phone, status item title. The phone MEID number of the current LTE/CDMA device. [CHAR LIMIT=30] -->
<string name="status_meid_number">MEID</string>
<!-- About phone, status item title. The ICCID of the current LTE device. [CHAR LIMIT=30] -->
@@ -3754,13 +3754,25 @@
<string name="location_app_level_permissions">App permission</string>
<!-- Summary for app permission on Location settings page when location is off [CHAR LIMIT=NONE] -->
<string name="location_app_permission_summary_location_off">Location is off</string>
- <!-- Summary for Location settings when location is on, explaining how many apps have location permission [CHAR LIMIT=NONE]-->
+ <!--
+ Summary for Location settings when location is on, explaining how many apps have unlimited
+ location permission.
+
+ "Unlimited access" means the app can access the device location even when it's not being used
+ (on background), while "limited" means the app can only access the device location when the user
+ is using it (foreground only).
+
+ Please note that the distinction between singular and plural of this sentence only depends on
+ the quantity of "background_location_app_count" ("has" vs "have"). The quantity of
+ "total_location_app_count" is almost always greater than 1, so "apps" is always in plural form.
+
+ [CHAR LIMIT=NONE]-->
<plurals name="location_app_permission_summary_location_on">
<item quantity="one">
<xliff:g id="background_location_app_count">%1$d</xliff:g>
of
<xliff:g id="total_location_app_count">%2$d</xliff:g>
- app has unlimited access</item>
+ apps has unlimited access</item>
<item quantity="other">
<xliff:g id="background_location_app_count">%1$d</xliff:g>
of
@@ -3771,8 +3783,12 @@
<string name="location_category_recent_location_access">Recent location access</string>
<!-- [CHAR LIMIT=30] Location settings screen, button to bring the user to view the details of recent location access -->
<string name="location_recent_location_access_view_details">View details</string>
- <!-- Location settings screen, displayed when there's no recent app accessing location -->
+ <!-- Location settings screen, displayed when there's no recent app accessing location
+ (for TV) [CHAR LIMIT=100] -->
<string name="location_no_recent_apps">No apps have requested location recently</string>
+ <!-- Location settings screen, displayed when there's no recent app accessing location
+ (for phones and tablets) [CHAR LIMIT=100] -->
+ <string name="location_no_recent_accesses">No apps recently accessed location</string>
<!-- [CHAR LIMIT=30] Location settings screen, recent location requests high battery use-->
<string name="location_high_battery_use">High battery use</string>
<!-- [CHAR LIMIT=30] Location settings screen, recent location requests low battery use-->
@@ -7771,7 +7787,7 @@
summary on the channel page-->
<!-- [CHAR LIMIT=100] Notification Importance title: min importance level title -->
- <string name="notification_importance_min_title">Low</string>
+ <string name="notification_importance_min_title">Minimize</string>
<!-- [CHAR LIMIT=100] Notification Importance title: low importance level title -->
<string name="notification_importance_low_title">Medium</string>
@@ -7780,7 +7796,16 @@
<string name="notification_importance_default_title">High</string>
<!-- [CHAR LIMIT=100] Notification Importance title: high importance level title -->
- <string name="notification_importance_high_title">Urgent</string>
+ <string name="notification_importance_high_title">Pop on screen</string>
+
+ <!-- [CHAR LIMIT=100] Notification Importance title -->
+ <string name="notification_block_title">Block</string>
+
+ <!-- [CHAR LIMIT=100] Notification Importance title -->
+ <string name="notification_silence_title">Show silently</string>
+
+ <!-- [CHAR LIMIT=100] Notification Importance title -->
+ <string name="notification_alert_title">Alert</string>
<!-- [CHAR LIMIT=40] Notification importance title. This setting controls how notifications in older apps may alert the user (eg, sound, visual, vibrate). -->
<string name="allow_interruption">Allow interruptions</string>
diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml
index 94a2cdb..6015f7f 100644
--- a/res/xml/channel_notification_settings.xml
+++ b/res/xml/channel_notification_settings.xml
@@ -25,11 +25,6 @@
android:order="1"
android:layout="@layout/settings_entity_header" />
- <com.android.settingslib.widget.LayoutPreference
- android:key="block"
- android:order="2"
- android:layout="@layout/styled_switch_bar" />
-
<!-- Importance toggle -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="allow_sound"
@@ -38,10 +33,23 @@
android:summary="@string/allow_interruption_summary" />
<!-- Importance -->
- <com.android.settings.RestrictedListPreference
+ <com.android.settings.notification.ImportancePreference
android:key="importance"
- android:order="10"
- android:title="@string/notification_importance_title" />
+ android:order="4"
+ android:title="@string/notification_importance_title"
+ settings:allowDividerBelow="true"/>
+
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="min_importance"
+ android:order="5"
+ settings:allowDividerAbove="true"
+ android:title="@string/notification_importance_min_title"/>
+
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="high_importance"
+ android:order="6"
+ settings:allowDividerAbove="true"
+ android:title="@string/notification_importance_high_title"/>
<PreferenceCategory
android:key="channel_advanced"
@@ -113,6 +121,7 @@
<com.android.settings.notification.NotificationFooterPreference
android:key="block_desc"
- android:order="110"/>
+ android:order="110"
+ settings:allowDividerAbove="false"/>
</PreferenceScreen>
diff --git a/res/xml/mobile_network_list.xml b/res/xml/mobile_network_list.xml
index b72540f..c2baf46 100644
--- a/res/xml/mobile_network_list.xml
+++ b/res/xml/mobile_network_list.xml
@@ -16,11 +16,13 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="mobile_network_list_screen"
android:title="@string/network_settings_title">
<Preference
android:key="add_more"
+ settings:isPreferenceVisible="false"
android:title="@string/mobile_network_list_add_more"
android:icon="@drawable/ic_menu_add"
android:order="100" >
diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java
index 7c21b55..72e1919 100644
--- a/src/com/android/settings/ResetNetworkConfirm.java
+++ b/src/com/android/settings/ResetNetworkConfirm.java
@@ -157,20 +157,9 @@
SubscriptionManager.getPhoneId(mSubId)).factoryReset();
restoreDefaultApn(context);
esimFactoryReset(context, context.getPackageName());
- // There has been issues when Sms raw table somehow stores orphan
- // fragments. They lead to garbled message when new fragments come
- // in and combied with those stale ones. In case this happens again,
- // user can reset all network settings which will clean up this table.
- cleanUpSmsRawTable(context);
}
};
- private void cleanUpSmsRawTable(Context context) {
- ContentResolver resolver = context.getContentResolver();
- Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
- resolver.delete(uri, null, null);
- }
-
@VisibleForTesting
void esimFactoryReset(Context context, String packageName) {
if (mEraseEsim) {
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollAccessibilityToggle.java b/src/com/android/settings/biometrics/face/FaceEnrollAccessibilityToggle.java
index 49f4f7f..2db654b 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollAccessibilityToggle.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollAccessibilityToggle.java
@@ -58,9 +58,14 @@
a.recycle();
}
mSwitch = findViewById(R.id.toggle);
+ mSwitch.setChecked(false);
}
public boolean isChecked() {
return mSwitch.isChecked();
}
+
+ public void setChecked(boolean checked) {
+ mSwitch.setChecked(checked);
+ }
}
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index 5f2b675..c7966f2 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -53,6 +53,7 @@
final LinearLayout accessibilityLayout = findViewById(R.id.accessibility_layout);
final Button accessibilityButton = findViewById(R.id.accessibility_button);
accessibilityButton.setOnClickListener(view -> {
+ mSwitchDiversity.setChecked(true);
accessibilityButton.setVisibility(View.INVISIBLE);
accessibilityLayout.setVisibility(View.VISIBLE);
});
@@ -177,7 +178,7 @@
} else {
intent.setClass(this, FaceEnrollEnrolling.class);
}
- intent.putExtra(EXTRA_KEY_REQUIRE_DIVERSITY, mSwitchDiversity.isChecked());
+ intent.putExtra(EXTRA_KEY_REQUIRE_DIVERSITY, !mSwitchDiversity.isChecked());
WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
return intent;
}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
index 13564b5..ff2ee91 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
@@ -67,7 +67,8 @@
@VisibleForTesting
Uri mNotifyUri;
- private Context mContext;
+
+ private final Context mContext;
ContextualCardLoader(Context context) {
super(context);
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
index c829015..8f7e84a 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
@@ -109,13 +109,13 @@
}
}
- void loadContextualCards(ContextualCardsFragment fragment) {
+ void loadContextualCards(LoaderManager loaderManager) {
mStartTime = System.currentTimeMillis();
final CardContentLoaderCallbacks cardContentLoaderCallbacks =
new CardContentLoaderCallbacks(mContext);
cardContentLoaderCallbacks.setListener(this);
// Use the cached data when navigating back to the first page and upon screen rotation.
- LoaderManager.getInstance(fragment).initLoader(CARD_CONTENT_LOADER_ID, null /* bundle */,
+ loaderManager.initLoader(CARD_CONTENT_LOADER_ID, null /* bundle */,
cardContentLoaderCallbacks);
}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
index e598e4c..72ddb50 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
@@ -19,16 +19,19 @@
import static com.android.settings.homepage.contextualcards.ContextualCardsAdapter.SPAN_COUNT;
import android.app.settings.SettingsEnums;
+import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import androidx.loader.app.LoaderManager;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.overlay.FeatureFactory;
public class ContextualCardsFragment extends InstrumentedFragment {
@@ -42,14 +45,19 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mContextualCardManager = new ContextualCardManager(getContext(), getSettingsLifecycle(),
+ final Context context = getContext();
+ if (savedInstanceState == null) {
+ FeatureFactory.getFactory(context).getSlicesFeatureProvider().newUiSession();
+ }
+ mContextualCardManager = new ContextualCardManager(context, getSettingsLifecycle(),
savedInstanceState);
+
}
@Override
public void onStart() {
super.onStart();
- mContextualCardManager.loadContextualCards(this);
+ mContextualCardManager.loadContextualCards(LoaderManager.getInstance(this));
}
@Override
diff --git a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
index 44d600e..a76d381 100644
--- a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
+++ b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
@@ -74,6 +74,7 @@
mController = AppEntitiesHeaderController.newInstance(mContext, view)
.setHeaderTitleRes(R.string.location_category_recent_location_access)
.setHeaderDetailsRes(R.string.location_recent_location_access_view_details)
+ .setHeaderEmptyRes(R.string.location_no_recent_accesses)
.setHeaderDetailsClickListener((View v) -> {
final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE);
intent.putExtra(Intent.EXTRA_PERMISSION_NAME,
@@ -100,14 +101,20 @@
.setIcon(access.icon)
.setTitle(access.label)
.setSummary(access.contentDescription)
+ .setOnClickListener((v) -> {
+ final Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION);
+ intent.putExtra(Intent.EXTRA_PERMISSION_NAME,
+ Manifest.permission_group.LOCATION);
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME, access.packageName);
+ intent.putExtra(Intent.EXTRA_USER, access.userHandle);
+ mContext.startActivity(intent);
+ })
.build();
mController.setAppEntity(i, appEntityInfo);
}
for (; i < MAXIMUM_APP_COUNT; i++) {
mController.removeAppEntity(i);
}
- } else {
- // If there's no item to display, add a "No recent apps" item.
}
mController.apply();
}
diff --git a/src/com/android/settings/network/MobileNetworkListController.java b/src/com/android/settings/network/MobileNetworkListController.java
index 7de6cdd..79715e3 100644
--- a/src/com/android/settings/network/MobileNetworkListController.java
+++ b/src/com/android/settings/network/MobileNetworkListController.java
@@ -24,14 +24,10 @@
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.euicc.EuiccManager;
import android.util.ArrayMap;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleObserver;
-import androidx.lifecycle.OnLifecycleEvent;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.network.telephony.MobileNetworkActivity;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -39,6 +35,12 @@
import java.util.List;
import java.util.Map;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
/**
* This populates the entries on a page which lists all available mobile subscriptions. Each entry
* has the name of the subscription with some subtext giving additional detail, and clicking on the
@@ -48,6 +50,9 @@
LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
private static final String TAG = "MobileNetworkListCtlr";
+ @VisibleForTesting
+ static final String KEY_ADD_MORE = "add_more";
+
private SubscriptionManager mSubscriptionManager;
private SubscriptionsChangeListener mChangeListener;
private PreferenceScreen mPreferenceScreen;
@@ -76,6 +81,8 @@
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreferenceScreen = screen;
+ final EuiccManager euiccManager = mContext.getSystemService(EuiccManager.class);
+ mPreferenceScreen.findPreference(KEY_ADD_MORE).setVisible(euiccManager.isEnabled());
update();
}
@@ -93,7 +100,7 @@
final List<SubscriptionInfo> subscriptions = SubscriptionUtil.getAvailableSubscriptions(
mSubscriptionManager);
for (SubscriptionInfo info : subscriptions) {
- int subId = info.getSubscriptionId();
+ final int subId = info.getSubscriptionId();
Preference pref = existingPreferences.remove(subId);
if (pref == null) {
pref = new Preference(mPreferenceScreen.getContext());
diff --git a/src/com/android/settings/network/MobileNetworkSummaryController.java b/src/com/android/settings/network/MobileNetworkSummaryController.java
index a1fef4c..56735ab 100644
--- a/src/com/android/settings/network/MobileNetworkSummaryController.java
+++ b/src/com/android/settings/network/MobileNetworkSummaryController.java
@@ -16,8 +16,6 @@
package com.android.settings.network;
-import static android.telephony.TelephonyManager.MultiSimVariants.UNKNOWN;
-
import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
@@ -25,7 +23,6 @@
import android.content.Intent;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager;
import com.android.settings.R;
@@ -52,7 +49,6 @@
private SubscriptionManager mSubscriptionManager;
private SubscriptionsChangeListener mChangeListener;
- private TelephonyManager mTelephonyMgr;
private EuiccManager mEuiccManager;
private AddPreference mPreference;
@@ -74,7 +70,6 @@
public MobileNetworkSummaryController(Context context, Lifecycle lifecycle) {
super(context);
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
- mTelephonyMgr = mContext.getSystemService(TelephonyManager.class);
mEuiccManager = mContext.getSystemService(EuiccManager.class);
if (lifecycle != null) {
mChangeListener = new SubscriptionsChangeListener(context, this);
@@ -124,48 +119,43 @@
mContext.startActivity(intent);
}
- private boolean shouldShowAddButton() {
- // The add button should only show up if the device is in multi-sim mode and the eSIM
- // manager is enabled.
- return mTelephonyMgr.getMultiSimConfiguration() != UNKNOWN && mEuiccManager.isEnabled();
- }
-
private void update() {
if (mPreference == null) {
return;
}
- final boolean showAddButton = shouldShowAddButton();
refreshSummary(mPreference);
- if (!showAddButton) {
- mPreference.setOnAddClickListener(null);
- } else {
- mPreference.setAddWidgetEnabled(!mChangeListener.isAirplaneModeOn());
- mPreference.setOnAddClickListener(p -> {
- startAddSimFlow();
- });
- }
- final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(
- mSubscriptionManager);
mPreference.setOnPreferenceClickListener(null);
+ mPreference.setOnAddClickListener(null);
mPreference.setFragment(null);
mPreference.setEnabled(!mChangeListener.isAirplaneModeOn());
+
+ final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(
+ mSubscriptionManager);
+
if (subs.isEmpty()) {
- if (showAddButton) {
- mPreference.setEnabled(false);
- } else if (mEuiccManager.isEnabled()) {
+ if (mEuiccManager.isEnabled()) {
mPreference.setOnPreferenceClickListener((Preference pref) -> {
startAddSimFlow();
return true;
});
}
- } else if (subs.size() == 1) {
- mPreference.setOnPreferenceClickListener((Preference pref) -> {
- final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
- mContext.startActivity(intent);
- return true;
- });
} else {
- mPreference.setFragment(MobileNetworkListFragment.class.getCanonicalName());
+ // We have one or more existing subscriptions, so we want the plus button if eSIM is
+ // supported.
+ if (mEuiccManager.isEnabled()) {
+ mPreference.setAddWidgetEnabled(!mChangeListener.isAirplaneModeOn());
+ mPreference.setOnAddClickListener(p -> startAddSimFlow());
+ }
+
+ if (subs.size() == 1) {
+ mPreference.setOnPreferenceClickListener((Preference pref) -> {
+ final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
+ mContext.startActivity(intent);
+ return true;
+ });
+ } else {
+ mPreference.setFragment(MobileNetworkListFragment.class.getCanonicalName());
+ }
}
}
diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
index 088bfbf..d70bd62 100644
--- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java
+++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
@@ -318,7 +318,8 @@
// Try to get the network registration states
ServiceState ss = mTelephonyManager.getServiceState();
List<NetworkRegistrationState> networkList =
- ss.getNetworkRegistrationStates(AccessNetworkConstants.TransportType.WWAN);
+ ss.getNetworkRegistrationStatesForTransportType(
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
if (networkList == null || networkList.size() == 0) {
// Remove the connected network operators category
mConnectedPreferenceCategory.setVisible(false);
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 9f5ece2..5fd26a6 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -152,6 +152,10 @@
context, mImportanceListener, mBackend));
mControllers.add(new ImportancePreferenceController(
context, mImportanceListener, mBackend));
+ mControllers.add(new MinImportancePreferenceController(
+ context, mImportanceListener, mBackend));
+ mControllers.add(new HighImportancePreferenceController(
+ context, mImportanceListener, mBackend));
mControllers.add(new SoundPreferenceController(context, this,
mImportanceListener, mBackend));
mControllers.add(new LightsPreferenceController(context, mBackend));
diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java
index f92e529..850fde2 100644
--- a/src/com/android/settings/notification/ChannelNotificationSettings.java
+++ b/src/com/android/settings/notification/ChannelNotificationSettings.java
@@ -94,9 +94,12 @@
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new HeaderPreferenceController(context, this));
- mControllers.add(new BlockPreferenceController(context, mImportanceListener, mBackend));
mControllers.add(new ImportancePreferenceController(
context, mImportanceListener, mBackend));
+ mControllers.add(new MinImportancePreferenceController(
+ context, mImportanceListener, mBackend));
+ mControllers.add(new HighImportancePreferenceController(
+ context, mImportanceListener, mBackend));
mControllers.add(new AllowSoundPreferenceController(
context, mImportanceListener, mBackend));
mControllers.add(new SoundPreferenceController(context, this,
diff --git a/src/com/android/settings/notification/HighImportancePreferenceController.java b/src/com/android/settings/notification/HighImportancePreferenceController.java
new file mode 100644
index 0000000..fe843fd
--- /dev/null
+++ b/src/com/android/settings/notification/HighImportancePreferenceController.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 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 android.app.NotificationChannel;
+import android.content.Context;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import androidx.preference.Preference;
+
+public class HighImportancePreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String KEY_IMPORTANCE = "high_importance";
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+
+ public HighImportancePreferenceController(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;
+ }
+ if (mChannel == null) {
+ return false;
+ }
+ if (isDefaultChannel()) {
+ return false;
+ }
+ return mChannel.getImportance() >= IMPORTANCE_DEFAULT;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (mAppRow!= null && mChannel != null) {
+ preference.setEnabled(mAdmin == null && isChannelConfigurable());
+
+ RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
+ pref.setChecked(mChannel.getImportance() >= IMPORTANCE_HIGH);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mChannel != null) {
+ final boolean checked = (boolean) newValue;
+
+ mChannel.setImportance(checked ? IMPORTANCE_HIGH : IMPORTANCE_DEFAULT);
+ mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+ saveChannel();
+ mImportanceListener.onImportanceChanged();
+ }
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ImportancePreference.java b/src/com/android/settings/notification/ImportancePreference.java
new file mode 100644
index 0000000..b8f3e45
--- /dev/null
+++ b/src/com/android/settings/notification/ImportancePreference.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2019 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 android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.LayerDrawable;
+import android.util.ArrayMap;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageButton;
+
+import com.android.settingslib.R;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+public class ImportancePreference extends Preference {
+
+ boolean mIsBlockable = true;
+ boolean mIsConfigurable = true;
+ int mImportance;
+ ImageButton blockButton;
+ ImageButton silenceButton;
+ ImageButton alertButton;
+ ArrayMap<ImageButton, Integer> mImageButtons = new ArrayMap<>();
+ Context mContext;
+
+ public ImportancePreference(Context context, AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init(context);
+ }
+
+ public ImportancePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context);
+ }
+
+ public ImportancePreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public ImportancePreference(Context context) {
+ super(context);
+ init(context);
+ }
+
+ private void init(Context context) {
+ mContext = context;
+ setLayoutResource(R.layout.notif_importance_preference);
+ }
+
+ public void setImportance(int importance) {
+ mImportance = importance;
+ }
+
+ public void setBlockable(boolean blockable) {
+ mIsBlockable = blockable;
+ }
+
+ public void setConfigurable(boolean configurable) {
+ mIsConfigurable = configurable;
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ View blockView = holder.itemView.findViewById(R.id.block);
+ View alertView = holder.itemView.findViewById(R.id.alert);
+ View silenceView = holder.itemView.findViewById(R.id.silence);
+ if (!mIsBlockable) {
+ blockView.setVisibility(View.GONE);
+ if (mImportance == IMPORTANCE_NONE) {
+ mImportance = IMPORTANCE_LOW;
+ callChangeListener(IMPORTANCE_LOW);
+ }
+
+ }
+ blockButton = blockView.findViewById(R.id.block_icon);
+ silenceButton = silenceView.findViewById(R.id.silence_icon);
+ alertButton = alertView.findViewById(R.id.alert_icon);
+ mImageButtons.put(blockButton, mContext.getColor(R.color.notification_block_color));
+ mImageButtons.put(silenceButton, mContext.getColor(R.color.notification_silence_color));
+ mImageButtons.put(alertButton, mContext.getColor(R.color.notification_alert_color));
+
+ switch (mImportance) {
+ case IMPORTANCE_NONE:
+ colorizeImageButton(blockButton.getId());
+ if (!mIsConfigurable) {
+ alertView.setVisibility(View.GONE);
+ silenceView.setVisibility(View.GONE);
+ }
+ break;
+ case IMPORTANCE_MIN:
+ case IMPORTANCE_LOW:
+ colorizeImageButton(silenceButton.getId());
+ if (!mIsConfigurable) {
+ alertView.setVisibility(View.GONE);
+ blockView.setVisibility(View.GONE);
+ }
+ break;
+ case IMPORTANCE_HIGH:
+ default:
+ colorizeImageButton(alertButton.getId());
+ if (!mIsConfigurable) {
+ blockView.setVisibility(View.GONE);
+ silenceView.setVisibility(View.GONE);
+ }
+ break;
+ }
+
+ blockButton.setOnClickListener(v -> {
+ callChangeListener(IMPORTANCE_NONE);
+ colorizeImageButton(blockButton.getId());
+ });
+ silenceButton.setOnClickListener(v -> {
+ callChangeListener(IMPORTANCE_LOW);
+ colorizeImageButton(silenceButton.getId());
+ });
+ alertButton.setOnClickListener(v -> {
+ callChangeListener(IMPORTANCE_DEFAULT);
+ colorizeImageButton(alertButton.getId());
+ });
+ }
+
+ private void colorizeImageButton(int buttonId) {
+ if (mImageButtons != null) {
+ for (int i = 0; i < mImageButtons.size(); i++) {
+ final ImageButton imageButton = mImageButtons.keyAt(i);
+ final int color = mImageButtons.valueAt(i);
+ if (imageButton != null) {
+ LayerDrawable drawable = (LayerDrawable) imageButton.getDrawable();
+ Drawable foreground = drawable.findDrawableByLayerId(R.id.fore);
+ GradientDrawable background =
+ (GradientDrawable) drawable.findDrawableByLayerId(R.id.back);
+ if (buttonId == imageButton.getId()) {
+ foreground.setTint(Color.WHITE);
+ background.setColor(color);
+ } else {
+ foreground.setTint(color);
+ background.setColor(Color.TRANSPARENT);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ImportancePreferenceController.java b/src/com/android/settings/notification/ImportancePreferenceController.java
index 4c20a46..0955571 100644
--- a/src/com/android/settings/notification/ImportancePreferenceController.java
+++ b/src/com/android/settings/notification/ImportancePreferenceController.java
@@ -18,21 +18,15 @@
import static android.app.NotificationChannel.USER_LOCKED_SOUND;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import android.app.NotificationChannel;
-import android.app.NotificationManager;
import android.content.Context;
import android.media.RingtoneManager;
-import androidx.preference.Preference;
-
-import com.android.settings.R;
-import com.android.settings.RestrictedListPreference;
import com.android.settings.core.PreferenceControllerMixin;
+import androidx.preference.Preference;
+
public class ImportancePreferenceController extends NotificationPreferenceController
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
@@ -53,44 +47,33 @@
@Override
public boolean isAvailable() {
- if (!super.isAvailable()) {
+ if (mAppRow == null) {
return false;
}
if (mChannel == null) {
return false;
}
- return !isDefaultChannel();
+ if (isDefaultChannel()) {
+ return false;
+ }
+ return true;
}
@Override
public void updateState(Preference preference) {
if (mAppRow!= null && mChannel != null) {
preference.setEnabled(mAdmin == null && isChannelConfigurable());
- preference.setSummary(getImportanceSummary(mChannel));
-
- int importances = IMPORTANCE_HIGH - IMPORTANCE_MIN + 1;
- CharSequence[] entries = new CharSequence[importances];
- CharSequence[] values = new CharSequence[importances];
-
- int index = 0;
- for (int i = IMPORTANCE_HIGH; i >= IMPORTANCE_MIN; i--) {
- NotificationChannel channel = new NotificationChannel("", "", i);
- entries[index] = getImportanceSummary(channel);
- values[index] = String.valueOf(i);
- index++;
- }
-
- RestrictedListPreference pref = (RestrictedListPreference) preference;
- pref.setEntries(entries);
- pref.setEntryValues(values);
- pref.setValue(String.valueOf(mChannel.getImportance()));
+ ImportancePreference pref = (ImportancePreference) preference;
+ pref.setBlockable(isChannelBlockable());
+ pref.setConfigurable(isChannelConfigurable());
+ pref.setImportance(mChannel.getImportance());
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (mChannel != null) {
- final int importance = Integer.parseInt((String) newValue);
+ final int importance = (Integer) newValue;
// If you are moving from an importance level without sound to one with sound,
// but the sound you had selected was "Silence",
@@ -111,39 +94,4 @@
}
return true;
}
-
- protected String getImportanceSummary(NotificationChannel channel) {
- String summary = "";
- int importance = channel.getImportance();
- switch (importance) {
- case IMPORTANCE_UNSPECIFIED:
- summary = mContext.getString(R.string.notification_importance_unspecified);
- break;
- case NotificationManager.IMPORTANCE_MIN:
- summary = mContext.getString(R.string.notification_importance_min);
- break;
- case NotificationManager.IMPORTANCE_LOW:
- summary = mContext.getString(R.string.notification_importance_low);
- break;
- case NotificationManager.IMPORTANCE_DEFAULT:
- if (SoundPreferenceController.hasValidSound(channel)) {
- summary = mContext.getString(R.string.notification_importance_default);
- } else {
- summary = mContext.getString(R.string.notification_importance_low);
- }
- break;
- case NotificationManager.IMPORTANCE_HIGH:
- case NotificationManager.IMPORTANCE_MAX:
- if (SoundPreferenceController.hasValidSound(channel)) {
- summary = mContext.getString(R.string.notification_importance_high);
- } else {
- summary = mContext.getString(R.string.notification_importance_high_silent);
- }
- break;
- default:
- return "";
- }
-
- return summary;
- }
}
diff --git a/src/com/android/settings/notification/MinImportancePreferenceController.java b/src/com/android/settings/notification/MinImportancePreferenceController.java
new file mode 100644
index 0000000..771ac60
--- /dev/null
+++ b/src/com/android/settings/notification/MinImportancePreferenceController.java
@@ -0,0 +1,84 @@
+/*
+ * 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_MIN;
+
+import android.app.NotificationChannel;
+import android.content.Context;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import androidx.preference.Preference;
+
+public class MinImportancePreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String KEY_IMPORTANCE = "min_importance";
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+
+ public MinImportancePreferenceController(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;
+ }
+ if (mChannel == null) {
+ return false;
+ }
+ if (isDefaultChannel()) {
+ return false;
+ }
+ return mChannel.getImportance() <= IMPORTANCE_LOW;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (mAppRow!= null && mChannel != null) {
+ preference.setEnabled(mAdmin == null && isChannelConfigurable());
+
+ RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
+ pref.setChecked(mChannel.getImportance() == IMPORTANCE_MIN);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mChannel != null) {
+ final boolean checked = (boolean) newValue;
+
+ mChannel.setImportance(checked ? IMPORTANCE_MIN : IMPORTANCE_LOW);
+ mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+ saveChannel();
+ mImportanceListener.onImportanceChanged();
+ }
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/NotificationPreferenceController.java b/src/com/android/settings/notification/NotificationPreferenceController.java
index 22f07be..3f535fb 100644
--- a/src/com/android/settings/notification/NotificationPreferenceController.java
+++ b/src/com/android/settings/notification/NotificationPreferenceController.java
@@ -111,6 +111,9 @@
}
protected boolean isChannelConfigurable() {
+ if (mAppRow != null && mAppRow.lockedImportance) {
+ return false;
+ }
if (mChannel != null && mAppRow != null) {
return !Objects.equals(mChannel.getId(), mAppRow.lockedChannelId);
}
diff --git a/src/com/android/settings/notification/RemoteVolumePreferenceController.java b/src/com/android/settings/notification/RemoteVolumePreferenceController.java
index 0ad307e..37a493e 100644
--- a/src/com/android/settings/notification/RemoteVolumePreferenceController.java
+++ b/src/com/android/settings/notification/RemoteVolumePreferenceController.java
@@ -35,6 +35,7 @@
import java.io.IOException;
import java.util.List;
+import java.util.Objects;
public class RemoteVolumePreferenceController extends
VolumeSeekBarPreferenceController {
@@ -58,14 +59,14 @@
if (mActiveToken == null) {
updateToken(token);
}
- if (mActiveToken == token) {
+ if (Objects.equals(mActiveToken, token)) {
updatePreference(mPreference, mActiveToken, pi);
}
}
@Override
public void onRemoteRemoved(MediaSession.Token t) {
- if (mActiveToken == t) {
+ if (Objects.equals(mActiveToken, t)) {
updateToken(null);
if (mPreference != null) {
mPreference.setVisible(false);
@@ -75,7 +76,7 @@
@Override
public void onRemoteVolumeChanged(MediaSession.Token token, int flags) {
- if (mActiveToken == token) {
+ if (Objects.equals(mActiveToken, token)) {
final MediaController.PlaybackInfo pi = mMediaController.getPlaybackInfo();
if (pi != null) {
setSliderPosition(pi.getCurrentVolume());
@@ -116,13 +117,13 @@
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume() {
super.onResume();
- //TODO(b/126199571): register callback once b/126890783 is fixed
+ mMediaSessions.init();
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause() {
super.onPause();
- //TODO(b/126199571): unregister callback once b/126890783 is fixed
+ mMediaSessions.destroy();
}
@Override
@@ -189,8 +190,7 @@
@Override
public Class<? extends SliceBackgroundWorker> getBackgroundWorkerClass() {
- //TODO(b/126199571): return RemoteVolumeSliceWorker once b/126890783 is fixed
- return null;
+ return RemoteVolumeSliceWorker.class;
}
private void updatePreference(VolumeSeekBarPreference seekBarPreference,
diff --git a/src/com/android/settings/notification/ZenRulePreference.java b/src/com/android/settings/notification/ZenRulePreference.java
index 613eb1d..8bc602a 100644
--- a/src/com/android/settings/notification/ZenRulePreference.java
+++ b/src/com/android/settings/notification/ZenRulePreference.java
@@ -171,6 +171,9 @@
getSettingsActivity(rule, si);
mIntent = AbstractZenModeAutomaticRulePreferenceController.getRuleIntent(action,
settingsActivity, mId);
+ if (mIntent.resolveActivity(mPm) == null) {
+ mIntent = null;
+ }
setKey(mId);
}
diff --git a/src/com/android/settings/panel/PanelSlicesAdapter.java b/src/com/android/settings/panel/PanelSlicesAdapter.java
index c1cb049..47ff631 100644
--- a/src/com/android/settings/panel/PanelSlicesAdapter.java
+++ b/src/com/android/settings/panel/PanelSlicesAdapter.java
@@ -94,6 +94,7 @@
super(view);
sliceView = view.findViewById(R.id.slice_view);
sliceView.setMode(SliceView.MODE_LARGE);
+ sliceView.showTitleItems(true);
mPanelContent = panelContent;
}
diff --git a/src/com/android/settings/slices/CustomSliceManager.java b/src/com/android/settings/slices/CustomSliceManager.java
deleted file mode 100644
index d0a65ba..0000000
--- a/src/com/android/settings/slices/CustomSliceManager.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2018 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.slices;
-
-import android.content.Context;
-import android.net.Uri;
-
-import java.util.Map;
-import java.util.WeakHashMap;
-
-/**
- * Manages custom {@link androidx.slice.Slice Slices}, which are all Slices not backed by
- * preferences.
- */
-public class CustomSliceManager {
-
- private final Context mContext;
- private final Map<Uri, CustomSliceable> mSliceableCache;
-
- public CustomSliceManager(Context context) {
- mContext = context.getApplicationContext();
- mSliceableCache = new WeakHashMap<>();
- }
-
- /**
- * Return a {@link CustomSliceable} associated to the Uri.
- * <p>
- * Do not change this method signature to accommodate for a special-case slicable - a context is
- * the only thing that should be needed to create the object.
- */
- public CustomSliceable getSliceableFromUri(Uri uri) {
- final Uri newUri = CustomSliceRegistry.removeParameterFromUri(uri);
- if (mSliceableCache.containsKey(newUri)) {
- return mSliceableCache.get(newUri);
- }
-
- final Class clazz = CustomSliceRegistry.getSliceClassByUri(newUri);
- if (clazz == null) {
- throw new IllegalArgumentException("No Slice found for uri: " + uri);
- }
-
- final CustomSliceable sliceable = CustomSliceable.createInstance(mContext, clazz);
- mSliceableCache.put(newUri, sliceable);
- return sliceable;
- }
-}
diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java
index 12e7b48..9d88bc5 100644
--- a/src/com/android/settings/slices/CustomSliceRegistry.java
+++ b/src/com/android/settings/slices/CustomSliceRegistry.java
@@ -322,7 +322,7 @@
}
public static Class<? extends CustomSliceable> getSliceClassByUri(Uri uri) {
- return sUriToSlice.get(uri);
+ return sUriToSlice.get(removeParameterFromUri(uri));
}
public static Uri removeParameterFromUri(Uri uri) {
@@ -331,7 +331,7 @@
/**
* Returns {@code true} if {@param uri} is a valid Slice Uri handled by
- * {@link CustomSliceManager}.
+ * {@link CustomSliceRegistry}.
*/
public static boolean isValidUri(Uri uri) {
return sUriToSlice.containsKey(removeParameterFromUri(uri));
@@ -339,7 +339,7 @@
/**
* Returns {@code true} if {@param action} is a valid intent action handled by
- * {@link CustomSliceManager}.
+ * {@link CustomSliceRegistry}.
*/
public static boolean isValidAction(String action) {
return isValidUri(Uri.parse(action));
diff --git a/src/com/android/settings/slices/CustomSliceable.java b/src/com/android/settings/slices/CustomSliceable.java
index 8393d4c..93d08a2 100644
--- a/src/com/android/settings/slices/CustomSliceable.java
+++ b/src/com/android/settings/slices/CustomSliceable.java
@@ -110,7 +110,7 @@
try {
final Constructor<? extends CustomSliceable> constructor =
sliceable.getConstructor(Context.class);
- final Object[] params = new Object[]{context};
+ final Object[] params = new Object[]{context.getApplicationContext()};
return constructor.newInstance(params);
} catch (NoSuchMethodException | InstantiationException |
IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index d019368..3187d10 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -118,9 +118,6 @@
private static final KeyValueListParser KEY_VALUE_LIST_PARSER = new KeyValueListParser(',');
@VisibleForTesting
- CustomSliceManager mCustomSliceManager;
-
- @VisibleForTesting
SlicesDatabaseAccessor mSlicesDatabaseAccessor;
@VisibleForTesting
@@ -140,15 +137,15 @@
mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(getContext());
mSliceDataCache = new ConcurrentHashMap<>();
mSliceWeakDataCache = new WeakHashMap<>();
- mCustomSliceManager = FeatureFactory.getFactory(
- getContext()).getSlicesFeatureProvider().getCustomSliceManager(getContext());
return true;
}
@Override
public void onSlicePinned(Uri sliceUri) {
if (CustomSliceRegistry.isValidUri(sliceUri)) {
- final CustomSliceable sliceable = mCustomSliceManager.getSliceableFromUri(sliceUri);
+ final Context context = getContext();
+ final CustomSliceable sliceable = FeatureFactory.getFactory(context)
+ .getSlicesFeatureProvider().getSliceableFromUri(context, sliceUri);
final IntentFilter filter = sliceable.getIntentFilter();
if (filter != null) {
registerIntentToUri(filter, sliceUri);
@@ -195,9 +192,10 @@
// Before adding a slice to {@link CustomSliceManager}, please get approval
// from the Settings team.
if (CustomSliceRegistry.isValidUri(sliceUri)) {
- final CustomSliceable sliceable = mCustomSliceManager.getSliceableFromUri(
- sliceUri);
- return sliceable.getSlice();
+ final Context context = getContext();
+ return FeatureFactory.getFactory(context)
+ .getSlicesFeatureProvider().getSliceableFromUri(context, sliceUri)
+ .getSlice();
}
if (CustomSliceRegistry.WIFI_CALLING_URI.equals(sliceUri)) {
diff --git a/src/com/android/settings/slices/SlicesFeatureProvider.java b/src/com/android/settings/slices/SlicesFeatureProvider.java
index 16a7424..ae94f29 100644
--- a/src/com/android/settings/slices/SlicesFeatureProvider.java
+++ b/src/com/android/settings/slices/SlicesFeatureProvider.java
@@ -1,6 +1,7 @@
package com.android.settings.slices;
import android.content.Context;
+import android.net.Uri;
import com.android.settings.network.telephony.Enhanced4gLteSliceHelper;
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
@@ -15,6 +16,20 @@
SliceDataConverter getSliceDataConverter(Context context);
/**
+ * Starts a new UI session for the purpose of using Slices.
+ *
+ * A UI session is defined as an duration of time when user stays in a UI screen. Screen
+ * rotation does not break the continuation of session, going to a sub-page and coming out does
+ * not break the continuation either. Leaving the page and coming back breaks it.
+ */
+ void newUiSession();
+
+ /**
+ * Returns the token created in {@link #newUiSession}.
+ */
+ long getUiSessionToken();
+
+ /**
* Asynchronous call to index the data used to build Slices.
* If the data is already indexed, the data will not change.
*/
@@ -26,7 +41,14 @@
*/
void indexSliceData(Context context);
- CustomSliceManager getCustomSliceManager(Context context);
+
+ /**
+ * Return a {@link CustomSliceable} associated to the Uri.
+ * <p>
+ * Do not change this method signature to accommodate for a special-case sliceable - a context
+ * is the only thing that should be needed to create the object.
+ */
+ CustomSliceable getSliceableFromUri(Context context, Uri uri);
/**
* Gets new WifiCallingSliceHelper object
diff --git a/src/com/android/settings/slices/SlicesFeatureProviderImpl.java b/src/com/android/settings/slices/SlicesFeatureProviderImpl.java
index 44863ec..297f2c1 100644
--- a/src/com/android/settings/slices/SlicesFeatureProviderImpl.java
+++ b/src/com/android/settings/slices/SlicesFeatureProviderImpl.java
@@ -17,19 +17,23 @@
package com.android.settings.slices;
import android.content.Context;
+import android.net.Uri;
+import android.os.SystemClock;
import com.android.settings.network.telephony.Enhanced4gLteSliceHelper;
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
import com.android.settingslib.utils.ThreadUtils;
+import java.util.Random;
+
/**
* Manages Slices in Settings.
*/
public class SlicesFeatureProviderImpl implements SlicesFeatureProvider {
+ private long mUiSessionToken;
private SlicesIndexer mSlicesIndexer;
private SliceDataConverter mSliceDataConverter;
- private CustomSliceManager mCustomSliceManager;
@Override
public SliceDataConverter getSliceDataConverter(Context context) {
@@ -40,11 +44,13 @@
}
@Override
- public CustomSliceManager getCustomSliceManager(Context context) {
- if (mCustomSliceManager == null) {
- mCustomSliceManager = new CustomSliceManager(context.getApplicationContext());
- }
- return mCustomSliceManager;
+ public void newUiSession() {
+ mUiSessionToken = SystemClock.elapsedRealtime();
+ }
+
+ @Override
+ public long getUiSessionToken() {
+ return mUiSessionToken;
}
@Override
@@ -69,6 +75,18 @@
return new Enhanced4gLteSliceHelper(context);
}
+ @Override
+ public CustomSliceable getSliceableFromUri(Context context, Uri uri) {
+ final Uri newUri = CustomSliceRegistry.removeParameterFromUri(uri);
+ final Class clazz = CustomSliceRegistry.getSliceClassByUri(newUri);
+ if (clazz == null) {
+ throw new IllegalArgumentException("No Slice found for uri: " + uri);
+ }
+
+ final CustomSliceable sliceable = CustomSliceable.createInstance(context, clazz);
+ return sliceable;
+ }
+
private SlicesIndexer getSliceIndexer(Context context) {
if (mSlicesIndexer == null) {
mSlicesIndexer = new SlicesIndexer(context.getApplicationContext());
diff --git a/src/com/android/settings/wifi/slice/ContextualWifiSlice.java b/src/com/android/settings/wifi/slice/ContextualWifiSlice.java
index fa8c267..4a799d1 100644
--- a/src/com/android/settings/wifi/slice/ContextualWifiSlice.java
+++ b/src/com/android/settings/wifi/slice/ContextualWifiSlice.java
@@ -25,6 +25,7 @@
import androidx.annotation.VisibleForTesting;
import androidx.slice.Slice;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.CustomSliceable;
@@ -35,7 +36,9 @@
private static final String TAG = "ContextualWifiSlice";
@VisibleForTesting
- boolean mPreviouslyDisplayed;
+ static long sActiveUiSession = -1000;
+ @VisibleForTesting
+ static boolean sPreviouslyDisplayed;
public ContextualWifiSlice(Context context) {
super(context);
@@ -48,13 +51,19 @@
@Override
public Slice getSlice() {
- if (!mPreviouslyDisplayed && !TextUtils.equals(getActiveSSID(), WifiSsid.NONE)) {
+ final long currentUiSession = FeatureFactory.getFactory(mContext)
+ .getSlicesFeatureProvider().getUiSessionToken();
+ if (currentUiSession != sActiveUiSession) {
+ sActiveUiSession = currentUiSession;
+ sPreviouslyDisplayed = false;
+ }
+ if (!sPreviouslyDisplayed && !TextUtils.equals(getActiveSSID(), WifiSsid.NONE)) {
Log.d(TAG, "Wifi is connected, no point showing any suggestion.");
return null;
}
- // Set mPreviouslyDisplayed to true - we will show *something* on the screen. So we should
+ // Set sPreviouslyDisplayed to true - we will show *something* on the screen. So we should
// keep showing this card to keep UI stable, even if wifi connects to a network later.
- mPreviouslyDisplayed = true;
+ sPreviouslyDisplayed = true;
return super.getSlice();
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java
index 7999dc8..3509330 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java
@@ -94,13 +94,13 @@
public void setChecked_on_setPowerSaveMode() {
mController.setChecked(true);
- verify(mPowerManager).setPowerSaveMode(true);
+ verify(mPowerManager).setPowerSaveModeEnabled(true);
}
@Test
public void setChecked_off_unsetPowerSaveMode() {
mController.setChecked(false);
- verify(mPowerManager).setPowerSaveMode(false);
+ verify(mPowerManager).setPowerSaveModeEnabled(false);
}
}
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java
index 1325650..10264ab 100644
--- a/tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java
@@ -21,6 +21,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -31,6 +32,7 @@
import android.content.Context;
import android.content.Intent;
import android.telephony.SubscriptionInfo;
+import android.telephony.euicc.EuiccManager;
import org.junit.After;
import org.junit.Before;
@@ -51,6 +53,9 @@
@RunWith(RobolectricTestRunner.class)
public class MobileNetworkListControllerTest {
@Mock
+ EuiccManager mEuiccManager;
+
+ @Mock
private Lifecycle mLifecycle;
@Mock
@@ -58,12 +63,17 @@
private Context mContext;
private MobileNetworkListController mController;
+ private Preference mAddMorePreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(Robolectric.setupActivity(Activity.class));
+ when(mContext.getSystemService(EuiccManager.class)).thenReturn(mEuiccManager);
when(mPreferenceScreen.getContext()).thenReturn(mContext);
+ mAddMorePreference = new Preference(mContext);
+ when(mPreferenceScreen.findPreference(MobileNetworkListController.KEY_ADD_MORE)).thenReturn(
+ mAddMorePreference);
mController = new MobileNetworkListController(mContext, mLifecycle);
}
@@ -79,6 +89,22 @@
}
@Test
+ public void displayPreference_eSimNotSupported_addMoreLinkNotVisible() {
+ when(mEuiccManager.isEnabled()).thenReturn(false);
+ mController.displayPreference(mPreferenceScreen);
+ mController.onResume();
+ assertThat(mAddMorePreference.isVisible()).isFalse();
+ }
+
+ @Test
+ public void displayPreference_eSimSupported_addMoreLinkIsVisible() {
+ when(mEuiccManager.isEnabled()).thenReturn(true);
+ mController.displayPreference(mPreferenceScreen);
+ mController.onResume();
+ assertThat(mAddMorePreference.isVisible()).isTrue();
+ }
+
+ @Test
public void displayPreference_twoSubscriptions_correctlySetup() {
final SubscriptionInfo sub1 = createMockSubscription(1, "sub1");
final SubscriptionInfo sub2 = createMockSubscription(2, "sub2");
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
index ba152b9..3404ca2 100644
--- a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
@@ -16,13 +16,9 @@
package com.android.settings.network;
-import static android.telephony.TelephonyManager.MultiSimVariants.DSDS;
-import static android.telephony.TelephonyManager.MultiSimVariants.UNKNOWN;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
@@ -37,7 +33,6 @@
import android.net.ConnectivityManager;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
-import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager;
import android.text.TextUtils;
@@ -64,8 +59,6 @@
@Mock
private Lifecycle mLifecycle;
@Mock
- private TelephonyManager mTelephonyManager;
- @Mock
private EuiccManager mEuiccManager;
@Mock
private PreferenceScreen mPreferenceScreen;
@@ -78,9 +71,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(Robolectric.setupActivity(Activity.class));
- when(mContext.getSystemService(eq(TelephonyManager.class))).thenReturn(mTelephonyManager);
when(mContext.getSystemService(EuiccManager.class)).thenReturn(mEuiccManager);
- when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(UNKNOWN);
when(mEuiccManager.isEnabled()).thenReturn(true);
mController = new MobileNetworkSummaryController(mContext, mLifecycle);
@@ -97,7 +88,7 @@
@Test
public void isAvailable_wifiOnlyMode_notAvailable() {
- ConnectivityManager cm = mock(ConnectivityManager.class);
+ final ConnectivityManager cm = mock(ConnectivityManager.class);
when(cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(cm);
assertThat(mController.isAvailable()).isFalse();
@@ -212,24 +203,7 @@
}
@Test
- public void addButton_noSubscriptionsSingleSimMode_noAddClickListener() {
- mController.displayPreference(mPreferenceScreen);
- mController.onResume();
- verify(mPreference, never()).setOnAddClickListener(notNull());
- }
-
- @Test
- public void addButton_oneSubscriptionSingleSimMode_noAddClickListener() {
- final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
- SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
- mController.displayPreference(mPreferenceScreen);
- mController.onResume();
- verify(mPreference, never()).setOnAddClickListener(notNull());
- }
-
- @Test
- public void addButton_noSubscriptionsMultiSimModeNoEuiccMgr_noAddClickListener() {
- when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
+ public void addButton_noSubscriptionsNoEuiccMgr_noAddClickListener() {
when(mEuiccManager.isEnabled()).thenReturn(false);
mController.displayPreference(mPreferenceScreen);
mController.onResume();
@@ -237,41 +211,43 @@
}
@Test
- public void addButton_noSubscriptionsMultiSimMode_hasAddClickListenerAndPrefDisabled() {
- when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
- mController.displayPreference(mPreferenceScreen);
- mController.onResume();
- assertThat(mPreference.isEnabled()).isFalse();
- verify(mPreference, never()).setOnAddClickListener(isNull());
- verify(mPreference).setOnAddClickListener(notNull());
- }
-
- @Test
- public void addButton_oneSubscriptionMultiSimMode_hasAddClickListener() {
- when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
+ public void addButton_oneSubscriptionNoEuiccMgr_noAddClickListener() {
+ when(mEuiccManager.isEnabled()).thenReturn(false);
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
mController.displayPreference(mPreferenceScreen);
mController.onResume();
- verify(mPreference, never()).setOnAddClickListener(isNull());
+ verify(mPreference, never()).setOnAddClickListener(notNull());
+ }
+
+ @Test
+ public void addButton_noSubscriptions_noAddClickListener() {
+ mController.displayPreference(mPreferenceScreen);
+ mController.onResume();
+ verify(mPreference, never()).setOnAddClickListener(notNull());
+ }
+
+ @Test
+ public void addButton_oneSubscription_hasAddClickListener() {
+ final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
+ SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
+ mController.displayPreference(mPreferenceScreen);
+ mController.onResume();
verify(mPreference).setOnAddClickListener(notNull());
}
@Test
- public void addButton_twoSubscriptionsMultiSimMode_hasAddClickListener() {
- when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
+ public void addButton_twoSubscriptions_hasAddClickListener() {
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
final SubscriptionInfo sub2 = mock(SubscriptionInfo.class);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
mController.displayPreference(mPreferenceScreen);
mController.onResume();
- verify(mPreference, never()).setOnAddClickListener(isNull());
verify(mPreference).setOnAddClickListener(notNull());
}
@Test
public void addButton_oneSubscriptionAirplaneModeTurnedOn_addButtonGetsDisabled() {
- when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
mController.displayPreference(mPreferenceScreen);
@@ -280,14 +256,13 @@
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
mController.onAirplaneModeChanged(true);
- ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
+ final ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
verify(mPreference, atLeastOnce()).setAddWidgetEnabled(captor.capture());
assertThat(captor.getValue()).isFalse();
}
@Test
public void onResume_oneSubscriptionAirplaneMode_isDisabled() {
- when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
@@ -296,7 +271,7 @@
assertThat(mPreference.isEnabled()).isFalse();
- ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
+ final ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
verify(mPreference, atLeastOnce()).setAddWidgetEnabled(captor.capture());
assertThat(captor.getValue()).isFalse();
}
@@ -318,7 +293,6 @@
@Test
public void onAirplaneModeChanged_oneSubscriptionAirplaneModeGetsTurnedOff_isEnabled() {
- when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
@@ -332,7 +306,7 @@
assertThat(mPreference.isEnabled()).isTrue();
- ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
+ final ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
verify(mPreference, atLeastOnce()).setAddWidgetEnabled(eq(false));
verify(mPreference, atLeastOnce()).setAddWidgetEnabled(captor.capture());
assertThat(captor.getValue()).isTrue();
diff --git a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
index 4f6944a..bdbf40a 100644
--- a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
@@ -111,6 +111,26 @@
}
@Test
+ public void testIsAvailable_notIfChannelNonDefault() {
+ 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_ifChannelDefault() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
public void testIsAvailable_notIfGroupNotBlockable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = true;
diff --git a/tests/robotests/src/com/android/settings/notification/HighImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/HighImportancePreferenceControllerTest.java
new file mode 100644
index 0000000..6e6dad4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/HighImportancePreferenceControllerTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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_NONE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+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.UserManager;
+
+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.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+@RunWith(RobolectricTestRunner.class)
+public class HighImportancePreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+ @Mock
+ private UserManager mUm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+
+ private HighImportancePreferenceController 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 = RuntimeEnvironment.application;
+ mController = spy(new HighImportancePreferenceController(
+ mContext, mImportanceListener, mBackend));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() {
+ mController.isAvailable();
+ mController.updateState(mock(Preference.class));
+ }
+
+ @Test
+ public void testIsAvailable_notIfNull() {
+ mController.onResume(null, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_ifAppBlocked() {
+ 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() {
+ 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() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin() {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new RestrictedSwitchPreference(mContext, null);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_notConfigurable() {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(mContext, null);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_high() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
+ mController.updateState(pref);
+
+ assertTrue(pref.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_default() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
+ mController.updateState(pref);
+
+ assertFalse(pref.isChecked());
+ }
+
+ @Test
+ public void onPreferenceChange() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext, null);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, false);
+
+ assertEquals(IMPORTANCE_DEFAULT, channel.getImportance());
+ verify(mImportanceListener, times(1)).onImportanceChanged();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
index 99d3376..c180ace 100644
--- a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
@@ -27,8 +27,11 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
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;
@@ -36,12 +39,10 @@
import android.app.NotificationManager;
import android.content.Context;
import android.os.UserManager;
-import android.text.TextUtils;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
-import com.android.settings.RestrictedListPreference;
import com.android.settingslib.RestrictedLockUtils;
import org.junit.Before;
@@ -95,20 +96,20 @@
}
@Test
- public void testIsAvailable_notIfAppBlocked() {
+ public void testIsAvailable_ifAppBlocked() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, mock(NotificationChannel.class), null, null);
- assertFalse(mController.isAvailable());
+ assertTrue(mController.isAvailable());
}
@Test
- public void testIsAvailable_notIfChannelBlocked() {
+ public void testIsAvailable_evenIfChannelBlocked() {
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());
+ assertTrue(mController.isAvailable());
}
@Test
@@ -137,11 +138,10 @@
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
- Preference pref = new RestrictedListPreference(mContext, null);
+ Preference pref = new ImportancePreference(mContext, null);
mController.updateState(pref);
assertFalse(pref.isEnabled());
- assertFalse(TextUtils.isEmpty(pref.getSummary()));
}
@Test
@@ -154,11 +154,10 @@
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
- Preference pref = new RestrictedListPreference(mContext, null);
+ Preference pref = new ImportancePreference(mContext, null);
mController.updateState(pref);
assertFalse(pref.isEnabled());
- assertFalse(TextUtils.isEmpty(pref.getSummary()));
}
@Test
@@ -167,11 +166,12 @@
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
- Preference pref = new RestrictedListPreference(mContext, null);
+ ImportancePreference pref = mock(ImportancePreference.class);
mController.updateState(pref);
- assertTrue(pref.isEnabled());
- assertFalse(TextUtils.isEmpty(pref.getSummary()));
+ verify(pref, times(1)).setConfigurable(anyBoolean());
+ verify(pref, times(1)).setBlockable(anyBoolean());
+ verify(pref, times(1)).setImportance(IMPORTANCE_HIGH);
}
@Test
@@ -181,13 +181,12 @@
channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
- RestrictedListPreference pref = new RestrictedListPreference(mContext, null);
+ ImportancePreference pref = new ImportancePreference(mContext, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
- pref.setValue(String.valueOf(IMPORTANCE_HIGH));
- mController.onPreferenceChange(pref, pref.getValue());
+ mController.onPreferenceChange(pref, IMPORTANCE_HIGH);
assertEquals(IMPORTANCE_HIGH, channel.getImportance());
assertNotNull(channel.getSound());
@@ -200,13 +199,12 @@
channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
- RestrictedListPreference pref = new RestrictedListPreference(mContext, null);
+ ImportancePreference pref = new ImportancePreference(mContext, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
- pref.setValue(String.valueOf(IMPORTANCE_LOW));
- mController.onPreferenceChange(pref, pref.getValue());
+ mController.onPreferenceChange(pref, IMPORTANCE_LOW);
assertEquals(IMPORTANCE_LOW, channel.getImportance());
assertNull(channel.getSound());
diff --git a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java
new file mode 100644
index 0000000..eebfbd1
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2019 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 com.google.common.truth.Truth.assertThat;
+
+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 android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.LayerDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+
+import com.android.settings.R;
+import com.android.settingslib.RestrictedLockUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+@RunWith(RobolectricTestRunner.class)
+public class ImportancePreferenceTest {
+
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ }
+
+ private GradientDrawable getBackground(ImageButton button) {
+ return (GradientDrawable) ((LayerDrawable) button.getDrawable())
+ .findDrawableByLayerId(R.id.back);
+ }
+
+ @Test
+ public void createNewPreference_shouldSetLayout() {
+ final ImportancePreference preference = new ImportancePreference(mContext);
+ assertThat(preference.getLayoutResource()).isEqualTo(
+ R.layout.notif_importance_preference);
+ }
+
+ @Test
+ public void onBindViewHolder_hideBlockNonBlockable() {
+ final ImportancePreference preference = new ImportancePreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+
+ preference.setBlockable(false);
+ preference.setConfigurable(true);
+ preference.setImportance(IMPORTANCE_DEFAULT);
+ preference.onBindViewHolder(holder);
+
+ assertThat(holder.itemView.findViewById(R.id.block).getVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_hideNonSelectedNonConfigurable() {
+ final ImportancePreference preference = new ImportancePreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+
+ preference.setBlockable(true);
+ preference.setConfigurable(false);
+ preference.setImportance(IMPORTANCE_DEFAULT);
+ preference.onBindViewHolder(holder);
+
+ assertThat(holder.itemView.findViewById(R.id.block).getVisibility()).isEqualTo(View.GONE);
+ assertThat(holder.itemView.findViewById(R.id.silence).getVisibility()).isEqualTo(View.GONE);
+ assertThat(holder.itemView.findViewById(R.id.alert).getVisibility())
+ .isEqualTo(View.VISIBLE);
+
+ // other button
+ preference.setImportance(IMPORTANCE_LOW);
+ holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+ preference.onBindViewHolder(holder);
+
+ assertThat(holder.itemView.findViewById(R.id.block).getVisibility()).isEqualTo(View.GONE);
+ assertThat(holder.itemView.findViewById(R.id.silence).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(holder.itemView.findViewById(R.id.alert).getVisibility())
+ .isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_selectButton() {
+ final ImportancePreference preference = new ImportancePreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+
+ preference.setBlockable(true);
+ preference.setConfigurable(true);
+ preference.setImportance(IMPORTANCE_DEFAULT);
+
+ ImageButton blockButton = (ImageButton) holder.findViewById(R.id.block_icon);
+ ImageButton silenceButton = (ImageButton) holder.findViewById(R.id.silence_icon);
+ ImageButton alertButton = (ImageButton) holder.findViewById(R.id.alert_icon);
+
+ preference.onBindViewHolder(holder);
+
+ // selected has full color background. others are transparent
+ assertThat(getBackground(alertButton).getColor().getColors()[0]).isNotEqualTo(
+ Color.TRANSPARENT);
+ assertThat(getBackground(silenceButton).getColor().getColors()[0]).isEqualTo(
+ Color.TRANSPARENT);
+ assertThat(getBackground(blockButton).getColor().getColors()[0]).isEqualTo(
+ Color.TRANSPARENT);
+ }
+
+ @Test
+ public void onClick_changesUICallsListener() {
+ final ImportancePreference preference = spy(new ImportancePreference(mContext));
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+
+ preference.setBlockable(true);
+ preference.setConfigurable(true);
+ preference.setImportance(IMPORTANCE_DEFAULT);
+ preference.onBindViewHolder(holder);
+
+ ImageButton blockButton = (ImageButton) holder.findViewById(R.id.block_icon);
+ ImageButton silenceButton = (ImageButton) holder.findViewById(R.id.silence_icon);
+ ImageButton alertButton = (ImageButton) holder.findViewById(R.id.alert_icon);
+
+ silenceButton.callOnClick();
+
+ // selected has full color background. others are transparent
+ assertThat(getBackground(silenceButton).getColor().getColors()[0]).isNotEqualTo(
+ Color.TRANSPARENT);
+ assertThat(getBackground(alertButton).getColor().getColors()[0]).isEqualTo(
+ Color.TRANSPARENT);
+ assertThat(getBackground(blockButton).getColor().getColors()[0]).isEqualTo(
+ Color.TRANSPARENT);
+
+ verify(preference, times(1)).callChangeListener(IMPORTANCE_LOW);
+ }
+
+ @Test
+ public void onBindViewHolder_allButtonsVisible() {
+ final ImportancePreference preference = new ImportancePreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+
+ preference.setBlockable(true);
+ preference.setConfigurable(true);
+ preference.onBindViewHolder(holder);
+
+ assertThat(holder.itemView.findViewById(R.id.block).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(holder.itemView.findViewById(R.id.silence).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(holder.itemView.findViewById(R.id.alert).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/MinImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/MinImportancePreferenceControllerTest.java
new file mode 100644
index 0000000..28058a4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/MinImportancePreferenceControllerTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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_MIN;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+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.UserManager;
+
+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.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+@RunWith(RobolectricTestRunner.class)
+public class MinImportancePreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+ @Mock
+ private UserManager mUm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+
+ private MinImportancePreferenceController 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 = RuntimeEnvironment.application;
+ mController = spy(new MinImportancePreferenceController(
+ mContext, mImportanceListener, mBackend));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() {
+ mController.isAvailable();
+ mController.updateState(mock(Preference.class));
+ }
+
+ @Test
+ public void testIsAvailable_notIfNull() {
+ mController.onResume(null, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_ifAppBlocked() {
+ 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() {
+ 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() {
+ 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() {
+ 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() {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new RestrictedSwitchPreference(mContext, null);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_notConfigurable() {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(mContext, null);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_min() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_MIN);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
+ mController.updateState(pref);
+
+ assertTrue(pref.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_low() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
+ mController.updateState(pref);
+
+ assertFalse(pref.isChecked());
+ }
+
+ @Test
+ public void onPreferenceChange() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext, null);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, true);
+
+ assertEquals(IMPORTANCE_MIN, channel.getImportance());
+ verify(mImportanceListener, times(1)).onImportanceChanged();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
index 1ad9378..2368af5 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
@@ -219,6 +219,20 @@
}
@Test
+ public void testIsConfigurable_appLevel() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = "something";
+ appRow.lockedImportance = true;
+
+ mController.onResume(appRow, mock(NotificationChannel.class), null, null);
+ assertFalse(mController.isChannelConfigurable());
+
+ appRow.lockedImportance = false;
+ mController.onResume(appRow, mock(NotificationChannel.class), null, null);
+ assertTrue(mController.isChannelConfigurable());
+ }
+
+ @Test
public void testIsChannelBlockable_nonSystemAppsBlockable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = false;
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index a693f34..23025b2 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -135,7 +135,6 @@
mProvider.mSliceWeakDataCache = new HashMap<>();
mProvider.mSliceDataCache = new HashMap<>();
mProvider.mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(mContext);
- mProvider.mCustomSliceManager = new CustomSliceManager(mContext);
when(mProvider.getContext()).thenReturn(mContext);
SlicesDatabaseHelper.getInstance(mContext).setIndexedState();
diff --git a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java
index 0e92c05..96bca07 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java
@@ -55,6 +55,7 @@
@After
public void cleanUp() {
DatabaseTestUtils.clearDb(mContext);
+ mDatabase.close();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/slices/SpecialCaseSliceManagerTest.java b/tests/robotests/src/com/android/settings/slices/SpecialCaseSliceManagerTest.java
index b563868..d483f9e 100644
--- a/tests/robotests/src/com/android/settings/slices/SpecialCaseSliceManagerTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SpecialCaseSliceManagerTest.java
@@ -37,6 +37,9 @@
@RunWith(RobolectricTestRunner.class)
public class SpecialCaseSliceManagerTest {
+ private final String FAKE_PARAMETER_KEY = "fake_parameter_key";
+ private final String FAKE_PARAMETER_VALUE = "fake_value";
+
private Context mContext;
@Before
@@ -55,6 +58,20 @@
}
@Test
+ public void getSliceableFromUriWithParameter_returnsCorrectObject() {
+ final Uri parameterUri = FakeSliceable.URI
+ .buildUpon()
+ .clearQuery()
+ .appendQueryParameter(FAKE_PARAMETER_KEY, FAKE_PARAMETER_VALUE)
+ .build();
+
+ final CustomSliceable sliceable = CustomSliceable.createInstance(
+ mContext, CustomSliceRegistry.getSliceClassByUri(parameterUri));
+
+ assertThat(sliceable).isInstanceOf(FakeSliceable.class);
+ }
+
+ @Test
public void isValidUri_validUri_returnsTrue() {
final boolean isValidUri = CustomSliceRegistry.isValidUri(FakeSliceable.URI);
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java b/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java
index d681afe..520d988 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java
@@ -36,6 +36,8 @@
import com.android.settings.R;
import com.android.settings.slices.CustomSliceRegistry;
+import com.android.settings.slices.SlicesFeatureProviderImpl;
+import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
import org.junit.Test;
@@ -52,11 +54,15 @@
private ContentResolver mResolver;
private WifiManager mWifiManager;
private ContextualWifiSlice mWifiSlice;
+ private FakeFeatureFactory mFeatureFactory;
@Before
public void setUp() {
mContext = spy(RuntimeEnvironment.application);
mResolver = mock(ContentResolver.class);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
+ mFeatureFactory.slicesFeatureProvider = new SlicesFeatureProviderImpl();
+ mFeatureFactory.slicesFeatureProvider.newUiSession();
doReturn(mResolver).when(mContext).getContentResolver();
mWifiManager = mContext.getSystemService(WifiManager.class);
@@ -65,10 +71,28 @@
mWifiManager.setWifiEnabled(true);
mWifiSlice = new ContextualWifiSlice(mContext);
+ mWifiSlice.sPreviouslyDisplayed = false;
}
@Test
public void getWifiSlice_hasActiveConnection_shouldReturnNull() {
+ mWifiSlice.sPreviouslyDisplayed = false;
+ final WifiConfiguration config = new WifiConfiguration();
+ config.SSID = "123";
+ mWifiManager.connect(config, null /* listener */);
+
+ final Slice wifiSlice = mWifiSlice.getSlice();
+
+ assertThat(wifiSlice).isNull();
+ }
+
+ @Test
+ public void getWifiSlice_newSession_hasActiveConnection_shouldReturnNull() {
+ // Session: use a non-active value
+ // previous displayed: yes
+ mWifiSlice.sPreviouslyDisplayed = true;
+ mWifiSlice.sActiveUiSession = ~mFeatureFactory.slicesFeatureProvider.getUiSessionToken();
+
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "123";
mWifiManager.connect(config, null /* listener */);
@@ -80,7 +104,8 @@
@Test
public void getWifiSlice_previousDisplayed_hasActiveConnection_shouldHaveTitleAndToggle() {
- mWifiSlice.mPreviouslyDisplayed = true;
+ mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken();
+ mWifiSlice.sPreviouslyDisplayed = true;
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "123";
mWifiManager.connect(config, null /* listener */);
@@ -101,7 +126,8 @@
@Test
public void getWifiSlice_contextualWifiSlice_shouldReturnContextualWifiSliceUri() {
- mWifiSlice.mPreviouslyDisplayed = true;
+ mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken();
+ mWifiSlice.sPreviouslyDisplayed = true;
final Slice wifiSlice = mWifiSlice.getSlice();