Update design of channel pages.
Test: atest Bug: 127796543 Change-Id: I4fabeafe2602c341554959303e67bc69c8817a8f
This commit is contained in:
43
res/drawable/ic_notification_alert.xml
Normal file
43
res/drawable/ic_notification_alert.xml
Normal file
@@ -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>
|
43
res/drawable/ic_notification_block.xml
Normal file
43
res/drawable/ic_notification_block.xml
Normal file
@@ -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>
|
43
res/drawable/ic_notification_silence.xml
Normal file
43
res/drawable/ic_notification_silence.xml
Normal file
@@ -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>
|
104
res/layout/notif_importance_preference.xml
Normal file
104
res/layout/notif_importance_preference.xml
Normal file
@@ -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>
|
@@ -124,6 +124,11 @@
|
|||||||
<color name="face_anim_particle_color_4">#fffdd835</color> <!-- Material Yellow 600 -->
|
<color name="face_anim_particle_color_4">#fffdd835</color> <!-- Material Yellow 600 -->
|
||||||
<color name="face_anim_particle_error">#ff9e9e9e</color> <!-- Material Gray 500 -->
|
<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 -->
|
<!-- launcher icon color -->
|
||||||
<color name="icon_launcher_setting_color">@*android:color/accent_device_default_light</color>
|
<color name="icon_launcher_setting_color">@*android:color/accent_device_default_light</color>
|
||||||
|
|
||||||
|
@@ -68,6 +68,9 @@
|
|||||||
<dimen name="notification_app_icon_size">64dp</dimen>
|
<dimen name="notification_app_icon_size">64dp</dimen>
|
||||||
<dimen name="notification_app_icon_badge_size">20dp</dimen>
|
<dimen name="notification_app_icon_badge_size">20dp</dimen>
|
||||||
<dimen name="notification_app_icon_badge_margin">4dp</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_rule_checkbox_padding">7dp</dimen>
|
||||||
<dimen name="zen_schedule_day_margin">17dp</dimen>
|
<dimen name="zen_schedule_day_margin">17dp</dimen>
|
||||||
|
|
||||||
|
@@ -7771,7 +7771,7 @@
|
|||||||
summary on the channel page-->
|
summary on the channel page-->
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=100] Notification Importance title: min importance level title -->
|
<!-- [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 -->
|
<!-- [CHAR LIMIT=100] Notification Importance title: low importance level title -->
|
||||||
<string name="notification_importance_low_title">Medium</string>
|
<string name="notification_importance_low_title">Medium</string>
|
||||||
@@ -7780,7 +7780,16 @@
|
|||||||
<string name="notification_importance_default_title">High</string>
|
<string name="notification_importance_default_title">High</string>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=100] Notification Importance title: high importance level title -->
|
<!-- [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). -->
|
<!-- [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>
|
<string name="allow_interruption">Allow interruptions</string>
|
||||||
|
@@ -25,11 +25,6 @@
|
|||||||
android:order="1"
|
android:order="1"
|
||||||
android:layout="@layout/settings_entity_header" />
|
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 -->
|
<!-- Importance toggle -->
|
||||||
<com.android.settingslib.RestrictedSwitchPreference
|
<com.android.settingslib.RestrictedSwitchPreference
|
||||||
android:key="allow_sound"
|
android:key="allow_sound"
|
||||||
@@ -38,10 +33,23 @@
|
|||||||
android:summary="@string/allow_interruption_summary" />
|
android:summary="@string/allow_interruption_summary" />
|
||||||
|
|
||||||
<!-- Importance -->
|
<!-- Importance -->
|
||||||
<com.android.settings.RestrictedListPreference
|
<com.android.settings.notification.ImportancePreference
|
||||||
android:key="importance"
|
android:key="importance"
|
||||||
android:order="10"
|
android:order="4"
|
||||||
android:title="@string/notification_importance_title" />
|
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
|
<PreferenceCategory
|
||||||
android:key="channel_advanced"
|
android:key="channel_advanced"
|
||||||
@@ -113,6 +121,7 @@
|
|||||||
|
|
||||||
<com.android.settings.notification.NotificationFooterPreference
|
<com.android.settings.notification.NotificationFooterPreference
|
||||||
android:key="block_desc"
|
android:key="block_desc"
|
||||||
android:order="110"/>
|
android:order="110"
|
||||||
|
settings:allowDividerAbove="false"/>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@@ -152,6 +152,10 @@ public class AppNotificationSettings extends NotificationSettingsBase {
|
|||||||
context, mImportanceListener, mBackend));
|
context, mImportanceListener, mBackend));
|
||||||
mControllers.add(new ImportancePreferenceController(
|
mControllers.add(new ImportancePreferenceController(
|
||||||
context, mImportanceListener, mBackend));
|
context, mImportanceListener, mBackend));
|
||||||
|
mControllers.add(new MinImportancePreferenceController(
|
||||||
|
context, mImportanceListener, mBackend));
|
||||||
|
mControllers.add(new HighImportancePreferenceController(
|
||||||
|
context, mImportanceListener, mBackend));
|
||||||
mControllers.add(new SoundPreferenceController(context, this,
|
mControllers.add(new SoundPreferenceController(context, this,
|
||||||
mImportanceListener, mBackend));
|
mImportanceListener, mBackend));
|
||||||
mControllers.add(new LightsPreferenceController(context, mBackend));
|
mControllers.add(new LightsPreferenceController(context, mBackend));
|
||||||
|
@@ -94,9 +94,12 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
|
|||||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||||
mControllers = new ArrayList<>();
|
mControllers = new ArrayList<>();
|
||||||
mControllers.add(new HeaderPreferenceController(context, this));
|
mControllers.add(new HeaderPreferenceController(context, this));
|
||||||
mControllers.add(new BlockPreferenceController(context, mImportanceListener, mBackend));
|
|
||||||
mControllers.add(new ImportancePreferenceController(
|
mControllers.add(new ImportancePreferenceController(
|
||||||
context, mImportanceListener, mBackend));
|
context, mImportanceListener, mBackend));
|
||||||
|
mControllers.add(new MinImportancePreferenceController(
|
||||||
|
context, mImportanceListener, mBackend));
|
||||||
|
mControllers.add(new HighImportancePreferenceController(
|
||||||
|
context, mImportanceListener, mBackend));
|
||||||
mControllers.add(new AllowSoundPreferenceController(
|
mControllers.add(new AllowSoundPreferenceController(
|
||||||
context, mImportanceListener, mBackend));
|
context, mImportanceListener, mBackend));
|
||||||
mControllers.add(new SoundPreferenceController(context, this,
|
mControllers.add(new SoundPreferenceController(context, this,
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
172
src/com/android/settings/notification/ImportancePreference.java
Normal file
172
src/com/android/settings/notification/ImportancePreference.java
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -18,21 +18,15 @@ package com.android.settings.notification;
|
|||||||
|
|
||||||
import static android.app.NotificationChannel.USER_LOCKED_SOUND;
|
import static android.app.NotificationChannel.USER_LOCKED_SOUND;
|
||||||
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
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.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.media.RingtoneManager;
|
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 com.android.settings.core.PreferenceControllerMixin;
|
||||||
|
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
public class ImportancePreferenceController extends NotificationPreferenceController
|
public class ImportancePreferenceController extends NotificationPreferenceController
|
||||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
|
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
|
||||||
|
|
||||||
@@ -53,44 +47,33 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
if (!super.isAvailable()) {
|
if (mAppRow == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mChannel == null) {
|
if (mChannel == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return !isDefaultChannel();
|
if (isDefaultChannel()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
if (mAppRow!= null && mChannel != null) {
|
if (mAppRow!= null && mChannel != null) {
|
||||||
preference.setEnabled(mAdmin == null && isChannelConfigurable());
|
preference.setEnabled(mAdmin == null && isChannelConfigurable());
|
||||||
preference.setSummary(getImportanceSummary(mChannel));
|
ImportancePreference pref = (ImportancePreference) preference;
|
||||||
|
pref.setBlockable(isChannelBlockable());
|
||||||
int importances = IMPORTANCE_HIGH - IMPORTANCE_MIN + 1;
|
pref.setConfigurable(isChannelConfigurable());
|
||||||
CharSequence[] entries = new CharSequence[importances];
|
pref.setImportance(mChannel.getImportance());
|
||||||
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()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
if (mChannel != null) {
|
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,
|
// If you are moving from an importance level without sound to one with sound,
|
||||||
// but the sound you had selected was "Silence",
|
// but the sound you had selected was "Silence",
|
||||||
@@ -111,39 +94,4 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
|
|||||||
}
|
}
|
||||||
return true;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -110,6 +110,26 @@ public class BlockPreferenceControllerTest {
|
|||||||
assertFalse(mController.isAvailable());
|
assertFalse(mController.isAvailable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Test
|
||||||
public void testIsAvailable_notIfGroupNotBlockable() {
|
public void testIsAvailable_notIfGroupNotBlockable() {
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
|
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
@@ -27,8 +27,11 @@ import static org.junit.Assert.assertNotNull;
|
|||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
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 static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
@@ -36,12 +39,10 @@ import android.app.NotificationChannel;
|
|||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.settings.RestrictedListPreference;
|
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -95,20 +96,20 @@ public class ImportancePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_notIfAppBlocked() {
|
public void testIsAvailable_ifAppBlocked() {
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.banned = true;
|
appRow.banned = true;
|
||||||
mController.onResume(appRow, mock(NotificationChannel.class), null, null);
|
mController.onResume(appRow, mock(NotificationChannel.class), null, null);
|
||||||
assertFalse(mController.isAvailable());
|
assertTrue(mController.isAvailable());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_notIfChannelBlocked() {
|
public void testIsAvailable_evenIfChannelBlocked() {
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
NotificationChannel channel = mock(NotificationChannel.class);
|
NotificationChannel channel = mock(NotificationChannel.class);
|
||||||
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
|
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
|
||||||
mController.onResume(appRow, channel, null, null);
|
mController.onResume(appRow, channel, null, null);
|
||||||
assertFalse(mController.isAvailable());
|
assertTrue(mController.isAvailable());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -137,11 +138,10 @@ public class ImportancePreferenceControllerTest {
|
|||||||
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
|
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
|
||||||
RestrictedLockUtils.EnforcedAdmin.class));
|
RestrictedLockUtils.EnforcedAdmin.class));
|
||||||
|
|
||||||
Preference pref = new RestrictedListPreference(mContext, null);
|
Preference pref = new ImportancePreference(mContext, null);
|
||||||
mController.updateState(pref);
|
mController.updateState(pref);
|
||||||
|
|
||||||
assertFalse(pref.isEnabled());
|
assertFalse(pref.isEnabled());
|
||||||
assertFalse(TextUtils.isEmpty(pref.getSummary()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -154,11 +154,10 @@ public class ImportancePreferenceControllerTest {
|
|||||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||||
mController.onResume(appRow, channel, null, null);
|
mController.onResume(appRow, channel, null, null);
|
||||||
|
|
||||||
Preference pref = new RestrictedListPreference(mContext, null);
|
Preference pref = new ImportancePreference(mContext, null);
|
||||||
mController.updateState(pref);
|
mController.updateState(pref);
|
||||||
|
|
||||||
assertFalse(pref.isEnabled());
|
assertFalse(pref.isEnabled());
|
||||||
assertFalse(TextUtils.isEmpty(pref.getSummary()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -167,11 +166,12 @@ public class ImportancePreferenceControllerTest {
|
|||||||
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
|
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
|
||||||
mController.onResume(appRow, channel, null, null);
|
mController.onResume(appRow, channel, null, null);
|
||||||
|
|
||||||
Preference pref = new RestrictedListPreference(mContext, null);
|
ImportancePreference pref = mock(ImportancePreference.class);
|
||||||
mController.updateState(pref);
|
mController.updateState(pref);
|
||||||
|
|
||||||
assertTrue(pref.isEnabled());
|
verify(pref, times(1)).setConfigurable(anyBoolean());
|
||||||
assertFalse(TextUtils.isEmpty(pref.getSummary()));
|
verify(pref, times(1)).setBlockable(anyBoolean());
|
||||||
|
verify(pref, times(1)).setImportance(IMPORTANCE_HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -181,13 +181,12 @@ public class ImportancePreferenceControllerTest {
|
|||||||
channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
|
channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
|
||||||
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
|
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);
|
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
|
||||||
mController.displayPreference(mScreen);
|
mController.displayPreference(mScreen);
|
||||||
mController.updateState(pref);
|
mController.updateState(pref);
|
||||||
|
|
||||||
pref.setValue(String.valueOf(IMPORTANCE_HIGH));
|
mController.onPreferenceChange(pref, IMPORTANCE_HIGH);
|
||||||
mController.onPreferenceChange(pref, pref.getValue());
|
|
||||||
|
|
||||||
assertEquals(IMPORTANCE_HIGH, channel.getImportance());
|
assertEquals(IMPORTANCE_HIGH, channel.getImportance());
|
||||||
assertNotNull(channel.getSound());
|
assertNotNull(channel.getSound());
|
||||||
@@ -200,13 +199,12 @@ public class ImportancePreferenceControllerTest {
|
|||||||
channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
|
channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
|
||||||
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
|
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);
|
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
|
||||||
mController.displayPreference(mScreen);
|
mController.displayPreference(mScreen);
|
||||||
mController.updateState(pref);
|
mController.updateState(pref);
|
||||||
|
|
||||||
pref.setValue(String.valueOf(IMPORTANCE_LOW));
|
mController.onPreferenceChange(pref, IMPORTANCE_LOW);
|
||||||
mController.onPreferenceChange(pref, pref.getValue());
|
|
||||||
|
|
||||||
assertEquals(IMPORTANCE_LOW, channel.getImportance());
|
assertEquals(IMPORTANCE_LOW, channel.getImportance());
|
||||||
assertNull(channel.getSound());
|
assertNull(channel.getSound());
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user