Redesign channel listing and channel page
Test: atest Bug: 127796543 Fixes: 129452112 Fixes: 129453207 Change-Id: I1d520c9e35860303235b7ffbb18a76cbc4f4b8bc
This commit is contained in:
23
res/drawable/button_border_selected.xml
Normal file
23
res/drawable/button_border_selected.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?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.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="?android:attr/colorAccent"/>
|
||||
<corners android:radius="@dimen/rect_button_radius" />
|
||||
</shape>
|
24
res/drawable/button_border_unselected.xml
Normal file
24
res/drawable/button_border_unselected.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="@color/notification_importance_button_unselected"/>
|
||||
|
||||
<corners android:radius="@dimen/rect_button_radius" />
|
||||
</shape>
|
26
res/drawable/button_ripple_radius.xml
Normal file
26
res/drawable/button_ripple_radius.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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.
|
||||
-->
|
||||
<ripple
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?android:attr/colorControlHighlight">
|
||||
<item android:id="@android:id/mask">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@android:color/white" />
|
||||
<corners android:radius="@dimen/rect_button_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
@@ -19,25 +19,23 @@ Copyright (C) 2019 The Android Open Source Project
|
||||
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" />
|
||||
<size
|
||||
android:height="24dp"
|
||||
android:width="24dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/fore"
|
||||
android:gravity="center">
|
||||
<vector
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
android:width="13dp"
|
||||
android:height="13dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="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"/>
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M8.98,16.65c-0.47,0 -0.91,-0.27 -1.12,-0.69l-1.93,-4.61L5.46,12.3c-0.21,0.43 -0.64,0.69 -1.12,0.69H2v-2h1.88l1,-2C5.1,8.56 5.52,8.3 6,8.3s0.9,0.26 1.12,0.69l1.73,4.14l2,-7c0.2,-0.46 0.65,-0.76 1.15,-0.76s0.95,0.3 1.15,0.76l0.04,0.12l1.96,6.88l1.7,-4.08c0.49,-0.98 1.84,-0.91 2.26,-0.06l1,2H22v2h-2.35c-0.47,0 -0.91,-0.27 -1.12,-0.7l-0.47,-0.95l-1.9,4.55c-0.25,0.5 -0.69,0.77 -1.18,0.75c-0.48,-0.01 -0.92,-0.31 -1.11,-0.76l-0.04,-0.12L12,9.37l-1.87,6.52c-0.19,0.45 -0.63,0.74 -1.11,0.76C9.01,16.65 9,16.65 8.98,16.65zM20.32,11.4L20.32,11.4C20.32,11.4 20.32,11.4 20.32,11.4z" />
|
||||
</vector>
|
||||
</item>
|
||||
</layer-list>
|
@@ -19,25 +19,23 @@ Copyright (C) 2019 The Android Open Source Project
|
||||
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" />
|
||||
<size
|
||||
android:height="24dp"
|
||||
android:width="24dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/fore"
|
||||
android:gravity="center">
|
||||
<vector
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
android:width="13dp"
|
||||
android:height="13dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="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" />
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M15,14.5c-1.38,0 -2.5,-1.12 -2.5,-2.5c0,-0.28 -0.22,-0.5 -0.5,-0.5s-0.5,0.22 -0.5,0.5c0,1.38 -1.12,2.5 -2.5,2.5S6.5,13.38 6.5,12c0,-0.28 -0.22,-0.5 -0.5,-0.5c-0.24,0 -0.46,0.18 -0.49,0.42C5.41,12.55 4.89,13 4.27,13H2v-2h1.71C4.1,10.11 5,9.5 6,9.5c1.38,0 2.5,1.12 2.5,2.5c0,0.28 0.22,0.5 0.5,0.5s0.5,-0.22 0.5,-0.5c0,-1.38 1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5c0,0.28 0.22,0.5 0.5,0.5s0.5,-0.22 0.5,-0.5c0,-1.38 1.12,-2.5 2.5,-2.5c1.02,0 1.91,0.6 2.29,1.5H22v2h-2.27c-0.62,0 -1.14,-0.45 -1.23,-1.08c-0.04,-0.24 -0.25,-0.42 -0.49,-0.42c-0.28,0 -0.5,0.22 -0.5,0.5C17.5,13.38 16.38,14.5 15,14.5z"/>
|
||||
</vector>
|
||||
</item>
|
||||
</layer-list>
|
@@ -21,84 +21,53 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/block"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="33.33"
|
||||
android:id="@+id/buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="@dimen/notification_importance_toggle_marginTop"
|
||||
android:orientation="horizontal"
|
||||
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
|
||||
<Button
|
||||
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="@dimen/notification_importance_toggle_size"
|
||||
android:minWidth="@dimen/notification_importance_button_width"
|
||||
android:paddingStart="@dimen/notification_importance_button_horiz_padding"
|
||||
android:paddingEnd="@dimen/notification_importance_button_horiz_padding"
|
||||
android:drawablePadding="@dimen/notification_importance_drawable_padding"
|
||||
android:foreground="@drawable/button_ripple_radius"
|
||||
android:drawableLeft="@drawable/ic_notification_alert"
|
||||
android:text="@string/notification_alert_title" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/silence"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/notification_importance_toggle_size"
|
||||
android:minWidth="@dimen/notification_importance_button_width"
|
||||
android:paddingStart="@dimen/notification_importance_button_horiz_padding"
|
||||
android:paddingEnd="@dimen/notification_importance_button_horiz_padding"
|
||||
android:drawablePadding="@dimen/notification_importance_drawable_padding"
|
||||
android:foreground="@drawable/button_ripple_radius"
|
||||
android:layout_marginStart="@dimen/notification_importance_button_separation"
|
||||
android:drawableLeft="@drawable/ic_notification_silence"
|
||||
android:text="@string/notification_silence_title" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/notification_alert_title"
|
||||
android:layout_marginTop="@dimen/notification_importance_toggle_marginTop"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="@dimen/notification_importance_text_marginTop"
|
||||
android:layout_marginBottom="@dimen/notification_importance_toggle_marginBottom"
|
||||
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" />
|
||||
</LinearLayout>
|
||||
android:paddingStart="@dimen/notification_importance_description_padding"
|
||||
android:paddingEnd="@dimen/notification_importance_description_padding"
|
||||
android:textAppearance="@style/TextAppearance.NotificationImportanceDetail" />
|
||||
|
||||
</LinearLayout>
|
@@ -124,8 +124,9 @@
|
||||
|
||||
<!-- notification settings -->
|
||||
<color name="notification_block_color">#ffff0000</color>
|
||||
<color name="notification_silence_color">#fbbc04</color>
|
||||
<color name="notification_alert_color">#30a751</color>
|
||||
<color name="notification_silence_color">#FF32c1de</color>
|
||||
<color name="notification_alert_color">#FFF87B2B</color>
|
||||
<color name="notification_importance_button_unselected">#FFDADCE0</color>
|
||||
|
||||
<!-- launcher icon color -->
|
||||
<color name="icon_launcher_setting_color">@*android:color/accent_device_default_light</color>
|
||||
|
@@ -69,11 +69,22 @@
|
||||
<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="notification_importance_toggle_marginTop">28dp</dimen>
|
||||
<dimen name="notification_importance_toggle_marginBottom">28dp</dimen>
|
||||
<dimen name="notification_importance_text_marginTop">20dp</dimen>
|
||||
<dimen name="notification_importance_button_separation">16dp</dimen>
|
||||
<dimen name="notification_importance_button_width">178dp</dimen>
|
||||
<dimen name="notification_importance_button_horiz_padding">36dp</dimen>
|
||||
<dimen name="notification_importance_drawable_padding">8dp</dimen>
|
||||
<dimen name="notification_importance_description_padding">20dp</dimen>
|
||||
<dimen name="notification_importance_description_text">14sp</dimen>
|
||||
<dimen name="notification_importance_button_text">16sp</dimen>
|
||||
|
||||
<dimen name="zen_schedule_rule_checkbox_padding">7dp</dimen>
|
||||
<dimen name="zen_schedule_day_margin">17dp</dimen>
|
||||
|
||||
<dimen name="rect_button_radius">8dp</dimen>
|
||||
|
||||
<!-- Default text size for caption preview samples. Uses dp rather than sp because captions are not scaled. -->
|
||||
<dimen name="caption_preview_text_size">48dp</dimen>
|
||||
|
||||
|
@@ -7951,10 +7951,10 @@
|
||||
<string name="notification_block_title">Block</string>
|
||||
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title -->
|
||||
<string name="notification_silence_title">Show silently</string>
|
||||
<string name="notification_silence_title">Gentle</string>
|
||||
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title -->
|
||||
<string name="notification_alert_title">Alert</string>
|
||||
<string name="notification_alert_title">Prioritized</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>
|
||||
@@ -7964,17 +7964,26 @@
|
||||
|
||||
<!-- Channel summaries for the app notification page -->
|
||||
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: min importance level title -->
|
||||
<string name="notification_channel_summary_min">Low importance</string>
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: min importance level summary -->
|
||||
<string name="notification_channel_summary_min">In the pull-down shade, collapse notifications to one line</string>
|
||||
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: low importance level title -->
|
||||
<string name="notification_channel_summary_low">Medium importance</string>
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: low importance level summary -->
|
||||
<string name="notification_channel_summary_low">Gentle notifications will display in pull-down list</string>
|
||||
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: normal importance level title -->
|
||||
<string name="notification_channel_summary_default">High importance</string>
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: low importance level summary -->
|
||||
<string name="notification_channel_summary_low_status">Gentle notifications will display in pull-down list & status bar</string>
|
||||
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: high importance level title -->
|
||||
<string name="notification_channel_summary_high">Urgent importance</string>
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: low importance level summary -->
|
||||
<string name="notification_channel_summary_low_lock">Gentle notifications will display in pull-down list & on lock screen</string>
|
||||
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: low importance level summary -->
|
||||
<string name="notification_channel_summary_low_status_lock">Gentle notifications will display in pull-down list, status bar & on lock screen</string>
|
||||
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: normal importance level summary -->
|
||||
<string name="notification_channel_summary_default">Prioritized notifications will alert and display in pull-down list, status bar & on lock screen</string>
|
||||
|
||||
<!-- [CHAR LIMIT=100] Notification Importance title: high importance level summary -->
|
||||
<string name="notification_channel_summary_high">When phone is unlocked, show notifications as a banner across top of screen</string>
|
||||
|
||||
<!-- [CHAR LIMIT=100] Label for on/off toggle -->
|
||||
<string name="notification_switch_label">Show notifications</string>
|
||||
|
@@ -542,4 +542,24 @@
|
||||
<item name="sudUsePartnerHeavyTheme">true</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.NotificationImportanceDetail">
|
||||
<item name="android:textSize">@dimen/notification_importance_description_text</item>
|
||||
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
|
||||
<item name="android:gravity">center</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.NotificationImportanceButton">
|
||||
<item name="android:textSize">@dimen/notification_importance_button_text</item>
|
||||
<item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
|
||||
<item name="android:gravity">center</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.NotificationImportanceButton.Selected" parent="TextAppearance.NotificationImportanceButton">
|
||||
<item name="android:textColor">?android:attr/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.NotificationImportanceButton.Unselected" parent="TextAppearance.NotificationImportanceButton">
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
@@ -25,6 +25,11 @@
|
||||
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"
|
||||
@@ -43,13 +48,15 @@
|
||||
android:key="min_importance"
|
||||
android:order="5"
|
||||
settings:allowDividerAbove="true"
|
||||
android:title="@string/notification_importance_min_title"/>
|
||||
android:title="@string/notification_importance_min_title"
|
||||
android:summary="@string/notification_channel_summary_min"/>
|
||||
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="high_importance"
|
||||
android:order="6"
|
||||
settings:allowDividerAbove="true"
|
||||
android:title="@string/notification_importance_high_title"/>
|
||||
android:title="@string/notification_importance_high_title"
|
||||
android:summary="@string/notification_channel_summary_high"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="channel_advanced"
|
||||
|
@@ -33,6 +33,7 @@ import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.widget.MasterSwitchPreference;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
@@ -255,7 +256,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {
|
||||
int childCount = groupGroup.getPreferenceCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
Preference pref = groupGroup.getPreference(i);
|
||||
if (pref instanceof ChannelSummaryPreference) {
|
||||
if (pref instanceof MasterSwitchPreference) {
|
||||
toRemove.add(pref);
|
||||
}
|
||||
}
|
||||
|
@@ -94,6 +94,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
|
||||
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(
|
||||
|
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* 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 android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.TwoTargetPreference;
|
||||
|
||||
/**
|
||||
* A custom preference that provides inline checkbox and tappable target.
|
||||
*/
|
||||
public class ChannelSummaryPreference extends TwoTargetPreference {
|
||||
|
||||
private Context mContext;
|
||||
private Intent mIntent;
|
||||
private CheckBox mCheckBox;
|
||||
private boolean mChecked;
|
||||
private boolean mEnableCheckBox = true;
|
||||
|
||||
public ChannelSummaryPreference(Context context) {
|
||||
super(context);
|
||||
setLayoutResource(R.layout.preference_checkable_two_target);
|
||||
mContext = context;
|
||||
setWidgetLayoutResource(R.layout.zen_rule_widget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||
super.onBindViewHolder(view);
|
||||
View settingsWidget = view.findViewById(android.R.id.widget_frame);
|
||||
View divider = view.findViewById(R.id.two_target_divider);
|
||||
if (mIntent != null) {
|
||||
divider.setVisibility(View.VISIBLE);
|
||||
settingsWidget.setVisibility(View.VISIBLE);
|
||||
settingsWidget.setOnClickListener(v -> mContext.startActivity(mIntent));
|
||||
} else {
|
||||
divider.setVisibility(View.GONE);
|
||||
settingsWidget.setVisibility(View.GONE);
|
||||
settingsWidget.setOnClickListener(null);
|
||||
}
|
||||
|
||||
View checkboxContainer = view.findViewById(R.id.checkbox_container);
|
||||
if (checkboxContainer != null) {
|
||||
checkboxContainer.setOnClickListener(mOnCheckBoxClickListener);
|
||||
}
|
||||
mCheckBox = (CheckBox) view.findViewById(com.android.internal.R.id.checkbox);
|
||||
if (mCheckBox != null) {
|
||||
mCheckBox.setChecked(mChecked);
|
||||
mCheckBox.setEnabled(mEnableCheckBox);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return mChecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIntent(Intent intent) {
|
||||
mIntent = intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
mOnCheckBoxClickListener.onClick(null);
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
mChecked = checked;
|
||||
if (mCheckBox != null) {
|
||||
mCheckBox.setChecked(checked);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCheckBoxEnabled(boolean enabled) {
|
||||
mEnableCheckBox = enabled;
|
||||
if (mCheckBox != null) {
|
||||
mCheckBox.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private View.OnClickListener mOnCheckBoxClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mCheckBox != null && !mCheckBox.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
setChecked(!mChecked);
|
||||
if (!callChangeListener(mChecked)) {
|
||||
setChecked(!mChecked);
|
||||
} else {
|
||||
persistBoolean(mChecked);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@@ -20,17 +20,12 @@ 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 android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settingslib.R;
|
||||
|
||||
@@ -39,14 +34,15 @@ 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;
|
||||
private boolean mIsConfigurable = true;
|
||||
private int mImportance;
|
||||
private boolean mDisplayInStatusBar;
|
||||
private boolean mDisplayOnLockscreen;
|
||||
private Button mSilenceButton;
|
||||
private Button mAlertButton;
|
||||
private Context mContext;
|
||||
Drawable selectedBackground;
|
||||
Drawable unselectedBackground;
|
||||
|
||||
public ImportancePreference(Context context, AttributeSet attrs,
|
||||
int defStyleAttr, int defStyleRes) {
|
||||
@@ -71,6 +67,8 @@ public class ImportancePreference extends Preference {
|
||||
|
||||
private void init(Context context) {
|
||||
mContext = context;
|
||||
selectedBackground = mContext.getDrawable(R.drawable.button_border_selected);
|
||||
unselectedBackground = mContext.getDrawable(R.drawable.button_border_unselected);
|
||||
setLayoutResource(R.layout.notif_importance_preference);
|
||||
}
|
||||
|
||||
@@ -78,94 +76,81 @@ public class ImportancePreference extends Preference {
|
||||
mImportance = importance;
|
||||
}
|
||||
|
||||
public void setBlockable(boolean blockable) {
|
||||
mIsBlockable = blockable;
|
||||
}
|
||||
|
||||
public void setConfigurable(boolean configurable) {
|
||||
mIsConfigurable = configurable;
|
||||
}
|
||||
|
||||
public void setDisplayInStatusBar(boolean display) {
|
||||
mDisplayInStatusBar = display;
|
||||
}
|
||||
|
||||
public void setDisplayOnLockscreen(boolean display) {
|
||||
mDisplayOnLockscreen = display;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
TextView textView = (TextView) holder.findViewById(R.id.description);
|
||||
mSilenceButton = (Button) holder.findViewById(R.id.silence);
|
||||
mAlertButton = (Button) holder.findViewById(R.id.alert);
|
||||
|
||||
if (!mIsConfigurable) {
|
||||
mSilenceButton.setEnabled(false);
|
||||
mAlertButton.setEnabled(false);
|
||||
}
|
||||
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);
|
||||
}
|
||||
mAlertButton.setBackground(unselectedBackground);
|
||||
mSilenceButton.setBackground(selectedBackground);
|
||||
break;
|
||||
case IMPORTANCE_HIGH:
|
||||
default:
|
||||
colorizeImageButton(alertButton.getId());
|
||||
if (!mIsConfigurable) {
|
||||
blockView.setVisibility(View.GONE);
|
||||
silenceView.setVisibility(View.GONE);
|
||||
}
|
||||
mSilenceButton.setBackground(unselectedBackground);
|
||||
mAlertButton.setBackground(selectedBackground);
|
||||
break;
|
||||
}
|
||||
setImportanceSummary(textView, mImportance);
|
||||
|
||||
blockButton.setOnClickListener(v -> {
|
||||
callChangeListener(IMPORTANCE_NONE);
|
||||
colorizeImageButton(blockButton.getId());
|
||||
});
|
||||
silenceButton.setOnClickListener(v -> {
|
||||
mSilenceButton.setOnClickListener(v -> {
|
||||
callChangeListener(IMPORTANCE_LOW);
|
||||
colorizeImageButton(silenceButton.getId());
|
||||
mAlertButton.setBackground(unselectedBackground);
|
||||
mSilenceButton.setBackground(selectedBackground);
|
||||
mSilenceButton.setTextAppearance(
|
||||
R.style.TextAppearance_NotificationImportanceButton_Selected);
|
||||
mAlertButton.setTextAppearance(
|
||||
R.style.TextAppearance_NotificationImportanceButton_Unselected);
|
||||
setImportanceSummary(textView, IMPORTANCE_LOW);
|
||||
});
|
||||
alertButton.setOnClickListener(v -> {
|
||||
mAlertButton.setOnClickListener(v -> {
|
||||
callChangeListener(IMPORTANCE_DEFAULT);
|
||||
colorizeImageButton(alertButton.getId());
|
||||
mSilenceButton.setBackground(unselectedBackground);
|
||||
mAlertButton.setBackground(selectedBackground);
|
||||
mAlertButton.setTextAppearance(
|
||||
R.style.TextAppearance_NotificationImportanceButton_Selected);
|
||||
mSilenceButton.setTextAppearance(
|
||||
R.style.TextAppearance_NotificationImportanceButton_Unselected);
|
||||
setImportanceSummary(textView, IMPORTANCE_DEFAULT);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
void setImportanceSummary(TextView view, int importance) {
|
||||
if (importance >= IMPORTANCE_DEFAULT) {
|
||||
view.setText(R.string.notification_channel_summary_default);
|
||||
} else {
|
||||
foreground.setTint(color);
|
||||
background.setColor(Color.TRANSPARENT);
|
||||
}
|
||||
}
|
||||
if (mDisplayInStatusBar) {
|
||||
if (mDisplayOnLockscreen) {
|
||||
view.setText(R.string.notification_channel_summary_low_status_lock);
|
||||
} else {
|
||||
view.setText(R.string.notification_channel_summary_low_status);
|
||||
}
|
||||
} else if (mDisplayOnLockscreen) {
|
||||
view.setText(R.string.notification_channel_summary_low_lock);
|
||||
} else {
|
||||
view.setText(R.string.notification_channel_summary_low);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -47,22 +47,13 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (mAppRow == null) {
|
||||
return false;
|
||||
}
|
||||
if (mAppRow.banned) {
|
||||
if (!super.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
if (mChannel == null) {
|
||||
return false;
|
||||
}
|
||||
if (isDefaultChannel()) {
|
||||
return false;
|
||||
}
|
||||
if (mChannelGroup != null && mChannelGroup.isBlocked()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return !isDefaultChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,9 +61,10 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
|
||||
if (mAppRow!= null && mChannel != null) {
|
||||
preference.setEnabled(mAdmin == null && isChannelConfigurable());
|
||||
ImportancePreference pref = (ImportancePreference) preference;
|
||||
pref.setBlockable(isChannelBlockable());
|
||||
pref.setConfigurable(isChannelConfigurable());
|
||||
pref.setImportance(mChannel.getImportance());
|
||||
pref.setDisplayInStatusBar(mBackend.showSilentInStatusBar(mContext.getPackageName()));
|
||||
// TODO: b/128445911 pass along lock screen setting
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -360,6 +360,15 @@ public class NotificationBackend {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public boolean showSilentInStatusBar(String pkg) {
|
||||
try {
|
||||
return !sINM.shouldHideSilentStatusIcons(pkg);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error calling NoMan", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void recordAggregatedUsageEvents(Context context, AppRow appRow) {
|
||||
long now = System.currentTimeMillis();
|
||||
long startTime = now - (DateUtils.DAY_IN_MILLIS * DAYS_TO_CHECK);
|
||||
|
@@ -34,6 +34,12 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.BlendMode;
|
||||
import android.graphics.BlendModeColorFilter;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
@@ -50,6 +56,7 @@ import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.widget.MasterSwitchPreference;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -272,11 +279,14 @@ abstract public class NotificationSettingsBase extends DashboardFragment {
|
||||
|
||||
protected Preference populateSingleChannelPrefs(PreferenceGroup parent,
|
||||
final NotificationChannel channel, final boolean groupBlocked) {
|
||||
ChannelSummaryPreference channelPref = new ChannelSummaryPreference(getPrefContext());
|
||||
channelPref.setCheckBoxEnabled(mSuspendedAppsAdmin == null
|
||||
MasterSwitchPreference channelPref = new MasterSwitchPreference(getPrefContext());
|
||||
channelPref.setSwitchEnabled(mSuspendedAppsAdmin == null
|
||||
&& isChannelBlockable(channel)
|
||||
&& isChannelConfigurable(channel)
|
||||
&& !groupBlocked);
|
||||
channelPref.setIcon(channel.getImportance() > IMPORTANCE_LOW
|
||||
? R.drawable.ic_notification_alert : R.drawable.ic_notification_silence);
|
||||
channelPref.setIconSize(MasterSwitchPreference.ICON_SIZE_SMALL);
|
||||
channelPref.setKey(channel.getId());
|
||||
channelPref.setTitle(channel.getName());
|
||||
channelPref.setSummary(NotificationBackend.getSentSummary(
|
||||
@@ -295,19 +305,21 @@ abstract public class NotificationSettingsBase extends DashboardFragment {
|
||||
.toIntent());
|
||||
|
||||
channelPref.setOnPreferenceChangeListener(
|
||||
new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference,
|
||||
Object o) {
|
||||
(preference, o) -> {
|
||||
boolean value = (Boolean) o;
|
||||
int importance = value ? IMPORTANCE_LOW : IMPORTANCE_NONE;
|
||||
channel.setImportance(importance);
|
||||
channel.lockFields(
|
||||
NotificationChannel.USER_LOCKED_IMPORTANCE);
|
||||
MasterSwitchPreference channelPref1 = (MasterSwitchPreference) preference;
|
||||
channelPref1.setIcon(channel.getImportance() > IMPORTANCE_LOW
|
||||
? R.drawable.ic_notification_alert
|
||||
: R.drawable.ic_notification_silence);
|
||||
toggleBehaviorIconState(channelPref1.getIcon(),
|
||||
importance != IMPORTANCE_NONE);
|
||||
mBackend.updateChannel(mPkg, mUid, channel);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (parent.findPreference(channelPref.getKey()) == null) {
|
||||
parent.addPreference(channelPref);
|
||||
@@ -315,6 +327,19 @@ abstract public class NotificationSettingsBase extends DashboardFragment {
|
||||
return channelPref;
|
||||
}
|
||||
|
||||
private void toggleBehaviorIconState(Drawable icon, boolean enabled) {
|
||||
LayerDrawable layerDrawable = (LayerDrawable) icon;
|
||||
GradientDrawable background =
|
||||
(GradientDrawable) layerDrawable.findDrawableByLayerId(R.id.back);
|
||||
if (enabled) {
|
||||
background.clearColorFilter();
|
||||
} else {
|
||||
background.setColorFilter(new BlendModeColorFilter(
|
||||
mContext.getColor(R.color.material_grey_300),
|
||||
BlendMode.SRC_IN));
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isChannelConfigurable(NotificationChannel channel) {
|
||||
if (channel != null && mAppRow != null) {
|
||||
return !channel.getId().equals(mAppRow.lockedChannelId);
|
||||
|
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* 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 com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
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 ChannelSummaryPreferenceTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createNewPreference_shouldSetLayout() {
|
||||
final ChannelSummaryPreference preference = new ChannelSummaryPreference(mContext);
|
||||
assertThat(preference.getLayoutResource()).isEqualTo(
|
||||
R.layout.preference_checkable_two_target);
|
||||
assertThat(preference.getWidgetLayoutResource()).isEqualTo(
|
||||
R.layout.zen_rule_widget);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_shouldUpdateButtonCheckedState() {
|
||||
final ChannelSummaryPreference preference = new ChannelSummaryPreference(mContext);
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
|
||||
inflater.inflate(R.layout.preference_checkable_two_target, null));
|
||||
final LinearLayout widgetView = holder.itemView.findViewById(R.id.checkbox_container);
|
||||
inflater.inflate(R.layout.preference_widget_checkbox, widgetView, true);
|
||||
final CheckBox toggle = (CheckBox) holder.findViewById(com.android.internal.R.id.checkbox);
|
||||
preference.onBindViewHolder(holder);
|
||||
|
||||
preference.setChecked(true);
|
||||
assertThat(toggle.isChecked()).isTrue();
|
||||
|
||||
preference.setChecked(false);
|
||||
assertThat(toggle.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setCheckboxEnabled_shouldUpdateButtonEnabledState() {
|
||||
final ChannelSummaryPreference preference = new ChannelSummaryPreference(mContext);
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
|
||||
inflater.inflate(R.layout.preference_checkable_two_target, null));
|
||||
final LinearLayout widgetView = holder.itemView.findViewById(R.id.checkbox_container);
|
||||
inflater.inflate(R.layout.preference_widget_checkbox, widgetView, true);
|
||||
final CheckBox toggle = (CheckBox) holder.findViewById(com.android.internal.R.id.checkbox);
|
||||
preference.onBindViewHolder(holder);
|
||||
|
||||
preference.setCheckBoxEnabled(true);
|
||||
assertThat(toggle.isEnabled()).isTrue();
|
||||
|
||||
preference.setCheckBoxEnabled(false);
|
||||
assertThat(toggle.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setCheckBoxEnabled_shouldUpdateButtonEnabledState_beforeViewBound() {
|
||||
final ChannelSummaryPreference preference = new ChannelSummaryPreference(mContext);
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
|
||||
inflater.inflate(R.layout.preference_checkable_two_target, null));
|
||||
final LinearLayout widgetView = holder.itemView.findViewById(R.id.checkbox_container);
|
||||
inflater.inflate(R.layout.preference_widget_checkbox, widgetView, true);
|
||||
final CheckBox toggle = (CheckBox) holder.findViewById(com.android.internal.R.id.checkbox);
|
||||
|
||||
preference.setCheckBoxEnabled(false);
|
||||
preference.onBindViewHolder(holder);
|
||||
assertThat(toggle.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickWidgetView_shouldToggleButton() {
|
||||
final ChannelSummaryPreference preference = new ChannelSummaryPreference(mContext);
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
|
||||
inflater.inflate(R.layout.preference_checkable_two_target, null));
|
||||
final LinearLayout widgetView = holder.itemView.findViewById(R.id.checkbox_container);
|
||||
assertThat(widgetView).isNotNull();
|
||||
|
||||
inflater.inflate(R.layout.preference_widget_checkbox, widgetView, true);
|
||||
final CheckBox toggle = (CheckBox) holder.findViewById(com.android.internal.R.id.checkbox);
|
||||
preference.onBindViewHolder(holder);
|
||||
|
||||
widgetView.performClick();
|
||||
assertThat(toggle.isChecked()).isTrue();
|
||||
|
||||
widgetView.performClick();
|
||||
assertThat(toggle.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickWidgetView_shouldNotToggleButtonIfDisabled() {
|
||||
final ChannelSummaryPreference preference = new ChannelSummaryPreference(mContext);
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
|
||||
inflater.inflate(R.layout.preference_checkable_two_target, null));
|
||||
final LinearLayout widgetView = holder.itemView.findViewById(R.id.checkbox_container);
|
||||
assertThat(widgetView).isNotNull();
|
||||
|
||||
inflater.inflate(R.layout.preference_widget_checkbox, widgetView, true);
|
||||
final CheckBox toggle = (CheckBox) holder.findViewById(com.android.internal.R.id.checkbox);
|
||||
preference.onBindViewHolder(holder);
|
||||
toggle.setEnabled(false);
|
||||
|
||||
widgetView.performClick();
|
||||
assertThat(toggle.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickWidgetView_shouldNotifyPreferenceChanged() {
|
||||
final ChannelSummaryPreference preference = new ChannelSummaryPreference(mContext);
|
||||
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
|
||||
LayoutInflater.from(mContext).inflate(
|
||||
R.layout.preference_checkable_two_target, null));
|
||||
final View widgetView = holder.findViewById(R.id.checkbox_container);
|
||||
final Preference.OnPreferenceChangeListener
|
||||
listener = mock(Preference.OnPreferenceChangeListener.class);
|
||||
preference.setOnPreferenceChangeListener(listener);
|
||||
preference.onBindViewHolder(holder);
|
||||
|
||||
preference.setChecked(false);
|
||||
widgetView.performClick();
|
||||
verify(listener).onPreferenceChange(preference, true);
|
||||
|
||||
preference.setChecked(true);
|
||||
widgetView.performClick();
|
||||
verify(listener).onPreferenceChange(preference, false);
|
||||
}
|
||||
}
|
@@ -117,12 +117,12 @@ public class ImportancePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_evenIfChannelBlocked() {
|
||||
public void testIsAvailable_ifChannelBlocked() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
assertTrue(mController.isAvailable());
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,8 +183,8 @@ public class ImportancePreferenceControllerTest {
|
||||
mController.updateState(pref);
|
||||
|
||||
verify(pref, times(1)).setConfigurable(anyBoolean());
|
||||
verify(pref, times(1)).setBlockable(anyBoolean());
|
||||
verify(pref, times(1)).setImportance(IMPORTANCE_HIGH);
|
||||
verify(pref, times(1)).setDisplayInStatusBar(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -27,18 +27,12 @@ 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 android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -46,7 +40,6 @@ import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -59,11 +52,6 @@ public class ImportancePreferenceTest {
|
||||
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);
|
||||
@@ -72,36 +60,26 @@ public class ImportancePreferenceTest {
|
||||
}
|
||||
|
||||
@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() {
|
||||
public void onBindViewHolder_nonConfigurable() {
|
||||
final ImportancePreference preference = new ImportancePreference(mContext);
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
|
||||
inflater.inflate(R.layout.notif_importance_preference, null));
|
||||
Drawable unselected = mock(Drawable.class);
|
||||
Drawable selected = mock(Drawable.class);
|
||||
preference.selectedBackground = selected;
|
||||
preference.unselectedBackground = unselected;
|
||||
|
||||
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);
|
||||
assertThat(holder.itemView.findViewById(R.id.silence).isEnabled()).isFalse();
|
||||
assertThat(holder.itemView.findViewById(R.id.alert).isEnabled()).isFalse();
|
||||
|
||||
assertThat(holder.itemView.findViewById(R.id.alert).getBackground()).isEqualTo(selected);
|
||||
assertThat(holder.itemView.findViewById(R.id.silence).getBackground())
|
||||
.isEqualTo(unselected);
|
||||
|
||||
// other button
|
||||
preference.setImportance(IMPORTANCE_LOW);
|
||||
@@ -109,37 +87,31 @@ public class ImportancePreferenceTest {
|
||||
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);
|
||||
assertThat(holder.itemView.findViewById(R.id.alert).getBackground()).isEqualTo(unselected);
|
||||
assertThat(holder.itemView.findViewById(R.id.silence).getBackground()).isEqualTo(selected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_selectButton() {
|
||||
public void onBindViewHolder_selectButtonAndText() {
|
||||
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));
|
||||
Drawable unselected = mock(Drawable.class);
|
||||
Drawable selected = mock(Drawable.class);
|
||||
preference.selectedBackground = selected;
|
||||
preference.unselectedBackground = unselected;
|
||||
|
||||
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);
|
||||
assertThat(holder.itemView.findViewById(R.id.alert).getBackground()).isEqualTo(selected);
|
||||
assertThat(holder.itemView.findViewById(R.id.silence).getBackground())
|
||||
.isEqualTo(unselected);
|
||||
assertThat(((TextView) holder.itemView.findViewById(R.id.description)).getText()).isEqualTo(
|
||||
mContext.getString(R.string.notification_channel_summary_default));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -148,45 +120,84 @@ public class ImportancePreferenceTest {
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
|
||||
inflater.inflate(R.layout.notif_importance_preference, null));
|
||||
Drawable unselected = mock(Drawable.class);
|
||||
Drawable selected = mock(Drawable.class);
|
||||
preference.selectedBackground = selected;
|
||||
preference.unselectedBackground = unselected;
|
||||
|
||||
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);
|
||||
Button silenceButton = holder.itemView.findViewById(R.id.silence);
|
||||
|
||||
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);
|
||||
assertThat(holder.itemView.findViewById(R.id.alert).getBackground()).isEqualTo(unselected);
|
||||
assertThat(holder.itemView.findViewById(R.id.silence).getBackground()).isEqualTo(selected);
|
||||
assertThat(((TextView) holder.itemView.findViewById(R.id.description)).getText()).isEqualTo(
|
||||
mContext.getString(R.string.notification_channel_summary_low));
|
||||
|
||||
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));
|
||||
public void setImportanceSummary_status() {
|
||||
TextView tv = new TextView(mContext);
|
||||
|
||||
preference.setBlockable(true);
|
||||
preference.setConfigurable(true);
|
||||
preference.onBindViewHolder(holder);
|
||||
final ImportancePreference preference = spy(new ImportancePreference(mContext));
|
||||
|
||||
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);
|
||||
preference.setDisplayInStatusBar(true);
|
||||
preference.setDisplayOnLockscreen(false);
|
||||
|
||||
preference.setImportanceSummary(tv, IMPORTANCE_LOW);
|
||||
|
||||
assertThat(tv.getText()).isEqualTo(
|
||||
mContext.getString(R.string.notification_channel_summary_low_status));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setImportanceSummary_lock() {
|
||||
TextView tv = new TextView(mContext);
|
||||
|
||||
final ImportancePreference preference = spy(new ImportancePreference(mContext));
|
||||
|
||||
preference.setDisplayInStatusBar(false);
|
||||
preference.setDisplayOnLockscreen(true);
|
||||
|
||||
preference.setImportanceSummary(tv, IMPORTANCE_LOW);
|
||||
|
||||
assertThat(tv.getText()).isEqualTo(
|
||||
mContext.getString(R.string.notification_channel_summary_low_lock));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setImportanceSummary_statusLock() {
|
||||
TextView tv = new TextView(mContext);
|
||||
|
||||
final ImportancePreference preference = spy(new ImportancePreference(mContext));
|
||||
|
||||
preference.setDisplayInStatusBar(true);
|
||||
preference.setDisplayOnLockscreen(true);
|
||||
|
||||
preference.setImportanceSummary(tv, IMPORTANCE_LOW);
|
||||
|
||||
assertThat(tv.getText()).isEqualTo(
|
||||
mContext.getString(R.string.notification_channel_summary_low_status_lock));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setImportanceSummary_statusLock_default() {
|
||||
TextView tv = new TextView(mContext);
|
||||
|
||||
final ImportancePreference preference = spy(new ImportancePreference(mContext));
|
||||
|
||||
preference.setDisplayInStatusBar(true);
|
||||
preference.setDisplayOnLockscreen(true);
|
||||
|
||||
preference.setImportanceSummary(tv, IMPORTANCE_DEFAULT);
|
||||
|
||||
assertThat(tv.getText()).isEqualTo(
|
||||
mContext.getString(R.string.notification_channel_summary_default));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user