--- /dev/null
+<!--
+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="@color/GM2_green_500" />
+ <size
+ android:height="36dp"
+ android:width="36dp"/>
+ </shape>
+ </item>
+ <item
+ android:id="@+id/fore"
+ android:gravity="center">
+ <vector
+ android:width="32dp"
+ android:height="32dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ 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>
--- /dev/null
+<!--
+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="@color/GM2_yellow_500" />
+ <size
+ android:height="36dp"
+ android:width="36dp"/>
+ </shape>
+ </item>
+ <item
+ android:id="@+id/fore"
+ android:gravity="center">
+ <vector
+ android:width="32dp"
+ android:height="32dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ 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>
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical"
+ android:paddingStart="@*android:dimen/notification_content_margin_start"
android:background="@color/notification_guts_bg_color">
<!-- Package Info -->
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginStart="@*android:dimen/notification_content_margin_start"
android:clipChildren="false"
android:clipToPadding="false">
<ImageView
android:id="@+id/pkgname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Info"
+ style="@style/TextAppearance.NotificationInfo.Primary"
android:layout_marginStart="3dp"
android:layout_marginEnd="2dp"
android:singleLine="true"
android:id="@+id/pkg_divider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Info"
+ style="@style/TextAppearance.NotificationInfo.Primary"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:text="@*android:string/notification_header_divider_symbol"
android:id="@+id/delegate_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Info"
+ style="@style/TextAppearance.NotificationInfo.Primary"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:ellipsize="end"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
- android:paddingHorizontal="16dp"
+
android:orientation="horizontal">
<!-- Optional link to app. Only appears if the channel is not disabled and the app
asked for it -->
<ImageButton
android:id="@+id/app_settings"
- android:layout_width="40dp"
- android:layout_height="56dp"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
android:layout_centerVertical="true"
- android:paddingRight="16dp"
android:visibility="gone"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/notification_app_settings"
- android:src="@drawable/ic_settings"
- android:tint="?android:attr/colorAccent" />
+ android:src="@drawable/ic_info"
+ android:tint="@color/notification_guts_link_icon_tint" />
<!-- 24 dp icon with 16 dp padding all around to mirror notification content margins -->
<ImageButton
android:id="@+id/info"
- android:layout_width="24dp"
- android:layout_height="56dp"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
android:layout_centerVertical="true"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/notification_more_settings"
- android:src="@drawable/ic_info"
- android:tint="?android:attr/colorAccent" />
+ android:src="@drawable/ic_settings"
+ android:tint="@color/notification_guts_link_icon_tint" />
</LinearLayout>
</RelativeLayout>
+ <!-- Channel Info Block -->
<LinearLayout
- android:id="@+id/prompt"
+ android:id="@+id/channel_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/notification_guts_button_spacing"
- android:clipChildren="false"
- android:clipToPadding="false"
+ android:paddingEnd="@*android:dimen/notification_content_margin_end"
android:orientation="vertical">
-
- <!-- Channel Info Block -->
- <LinearLayout
+ <RelativeLayout
+ android:id="@+id/names"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="@*android:dimen/notification_content_margin_start"
- android:layout_marginEnd="@*android:dimen/notification_content_margin_start"
- android:orientation="vertical">
- <RelativeLayout
- android:id="@+id/names"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <TextView
- android:id="@+id/group_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
- android:layout_marginStart="2dp"
- android:layout_marginEnd="2dp"
- android:ellipsize="end"
- android:maxLines="1"
- android:layout_centerVertical="true" />
- <TextView
- android:id="@+id/pkg_group_divider"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
- android:layout_marginStart="2dp"
- android:layout_marginEnd="2dp"
- android:text="@*android:string/notification_header_divider_symbol"
- android:layout_centerVertical="true"
- android:layout_toEndOf="@id/group_name" />
- <!-- Channel Name -->
- <TextView
- android:id="@+id/channel_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- style="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
- android:layout_toEndOf="@id/pkg_group_divider"/>
- </RelativeLayout>
- <!-- Question prompt -->
+ android:layout_height="wrap_content">
<TextView
- android:id="@+id/block_prompt"
+ android:id="@+id/group_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@*android:style/TextAppearance.DeviceDefault.Notification" />
- </LinearLayout>
+ style="@style/TextAppearance.NotificationInfo.Primary"
+ android:layout_marginStart="2dp"
+ android:layout_marginEnd="2dp"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:layout_centerVertical="true" />
+ <TextView
+ android:id="@+id/pkg_group_divider"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/TextAppearance.NotificationInfo.Primary"
+ android:layout_marginStart="2dp"
+ android:layout_marginEnd="2dp"
+ android:text="@*android:string/notification_header_divider_symbol"
+ android:layout_centerVertical="true"
+ android:layout_toEndOf="@id/group_name" />
+ <!-- Channel Name -->
+ <TextView
+ android:id="@+id/channel_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ style="@style/TextAppearance.NotificationInfo.Primary"
+ android:layout_toEndOf="@id/pkg_group_divider"/>
+ </RelativeLayout>
+ </LinearLayout>
- <!-- Settings and Done buttons -->
+ <LinearLayout
+ android:id="@+id/blocking_helper"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/notification_guts_button_spacing"
+ android:paddingEnd="@*android:dimen/notification_content_margin_end"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="vertical">
+ <!-- blocking helper text. no need for non-configurable check b/c controls won't be
+ activated in that case -->
+ <TextView
+ android:id="@+id/blocking_helper_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="2dp"
+ android:text="@string/inline_blocking_helper"
+ style="@*android:style/TextAppearance.DeviceDefault.Notification" />
<RelativeLayout
- android:id="@+id/block_or_minimize"
+ android:id="@+id/block_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/notification_guts_button_spacing"
- android:layout_marginStart="@dimen/notification_guts_button_side_margin"
- android:layout_marginEnd="@dimen/notification_guts_button_side_margin"
- android:clipChildren="false"
- android:clipToPadding="false">
+ android:layout_marginTop="@dimen/notification_guts_button_spacing">
<TextView
- android:id="@+id/done"
- android:text="@string/inline_ok_button"
+ android:id="@+id/blocking_helper_turn_off_notifications"
+ android:text="@string/inline_turn_off_notifications"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
- android:maxWidth="100dp"
+ android:layout_alignParentStart="true"
+ android:width="110dp"
+ android:paddingEnd="15dp"
+ android:breakStrategy="simple"
style="@style/TextAppearance.NotificationInfo.Button"/>
-
- <LinearLayout
- android:id="@+id/block_buttons"
+ <TextView
+ android:id="@+id/deliver_silently"
+ android:text="@string/inline_deliver_silently_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
+ android:paddingEnd="15dp"
+ android:width="110dp"
+ android:breakStrategy="simple"
+ android:layout_toStartOf="@+id/keep_showing"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ <TextView
+ android:id="@+id/keep_showing"
+ android:text="@string/inline_keep_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
+ android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
+ android:width="110dp"
+ android:breakStrategy="simple"
android:layout_alignParentEnd="true"
- android:maxWidth="200dp"
- android:orientation="horizontal">
- <TextView
- android:id="@+id/deliver_silently"
- android:text="@string/inline_silent_button_silent"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
- android:paddingRight="24dp"
- android:maxWidth="125dp"
- style="@style/TextAppearance.NotificationInfo.Button"/>
- <TextView
- android:id="@+id/block"
- android:text="@string/inline_block_button"
- android:minWidth="48dp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:maxWidth="75dp"
- android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
- style="@style/TextAppearance.NotificationInfo.Button"/>
- <TextView
- android:id="@+id/minimize"
- android:text="@string/inline_minimize_button"
- android:minWidth="48dp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:maxWidth="75dp"
- android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
- style="@style/TextAppearance.NotificationInfo.Button"/>
- </LinearLayout>
+ style="@style/TextAppearance.NotificationInfo.Button"/>
</RelativeLayout>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/inline_controls"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/notification_guts_button_spacing"
+ android:paddingEnd="@*android:dimen/notification_content_margin_end"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="vertical">
+
+ <!-- Non configurable app/channel text. appears instead of @+id/interruptiveness_settings-->
+ <TextView
+ android:id="@+id/non_configurable_text"
+ android:text="@string/notification_unblockable_desc"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/notification_guts_option_vertical_padding"
+ style="@*android:style/TextAppearance.DeviceDefault.Notification" />
+
+ <!-- Non configurable multichannel text. appears instead of @+id/interruptiveness_settings-->
+ <TextView
+ android:id="@+id/non_configurable_multichannel_text"
+ android:text="@string/notification_multichannel_desc"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/notification_guts_option_vertical_padding"
+ style="@*android:style/TextAppearance.DeviceDefault.Notification" />
+
<LinearLayout
android:id="@+id/interruptiveness_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical"
- android:visibility="gone">
+ android:orientation="vertical">
+ <!-- Interruptive row -->
<LinearLayout
+ android:id="@+id/alert_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="2dp"
- android:layout_marginStart="@dimen/notification_guts_button_side_margin"
- android:layout_marginEnd="@dimen/notification_guts_button_side_margin"
- android:gravity="center"
+ android:paddingTop="@dimen/notification_guts_option_vertical_padding"
+ android:paddingBottom="@dimen/notification_guts_option_vertical_padding"
+ android:paddingStart="@dimen/notification_guts_option_horizontal_padding"
android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/int_alert"
+ android:src="@drawable/ic_notification_interruptive"
+ android:background="@android:color/transparent"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="@string/inline_silent_button_alert"/>
+
<LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center_horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/notification_guts_option_horizontal_padding"
+ android:paddingEnd="@dimen/notification_guts_option_horizontal_padding"
android:orientation="vertical">
- <FrameLayout
- android:id="@+id/int_block_wrapper"
- android:padding="4dp"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:gravity="center">
- <ImageButton
- android:id="@+id/int_block"
- android:background="@drawable/circle_white_40dp"
- android:src="@drawable/ic_notification_block"
- android:layout_gravity="center"
- android:layout_width="40dp"
- android:layout_height="40dp"
- android:clickable="false"
- android:contentDescription="@string/inline_block_button"
- android:tint="@color/GM2_grey_400"
- style="@style/TextAppearance.NotificationInfo.Button"/>
- </FrameLayout>
<TextView
- android:id="@+id/int_block_label"
- android:text="@string/inline_block_button"
- android:layout_gravity="center_horizontal"
- android:gravity="center"
+ android:id="@+id/int_alert_label"
+ android:text="@string/inline_silent_button_alert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
- style="@style/TextAppearance.NotificationInfo.ButtonLabel"/>
+ style="@style/TextAppearance.NotificationInfo.Primary"/>
+ <TextView
+ android:id="@+id/int_alert_summary"
+ android:text="@string/hint_text_alert"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ style="@style/TextAppearance.NotificationInfo.Secondary"/>
</LinearLayout>
+ </LinearLayout>
+
+ <!-- Gentle row -->
+ <LinearLayout
+ android:id="@+id/silent_row"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/notification_guts_option_vertical_padding"
+ android:paddingBottom="@dimen/notification_guts_option_vertical_padding"
+ android:paddingStart="@dimen/notification_guts_option_horizontal_padding"
+ android:layout_marginTop="@dimen/notification_guts_option_vertical_margin"
+ android:orientation="horizontal">
+ <ImageView
+ android:id="@+id/int_silent"
+ android:src="@drawable/ic_notification_gentle"
+ android:layout_gravity="center"
+ android:layout_width="36dp"
+ android:layout_height="36dp"
+ android:background="@android:color/transparent"
+ android:contentDescription="@string/inline_silent_button_silent"/>
<LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center_horizontal"
- android:orientation="vertical">
- <FrameLayout
- android:id="@+id/int_silent_wrapper"
- android:padding="4dp"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:gravity="center">
- <ImageButton
- android:id="@+id/int_silent"
- android:background="@drawable/circle_white_40dp"
- android:src="@drawable/ic_notifications_silence"
- android:layout_gravity="center"
- android:layout_width="40dp"
- android:layout_height="40dp"
- android:clickable="false"
- android:contentDescription="@string/inline_silent_button_silent"
- android:tint="@color/GM2_grey_400"
- style="@style/TextAppearance.NotificationInfo.Button"/>
- </FrameLayout>
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingStart="@dimen/notification_guts_option_horizontal_padding"
+ android:paddingEnd="@dimen/notification_guts_option_horizontal_padding">
<TextView
android:id="@+id/int_silent_label"
android:text="@string/inline_silent_button_silent"
- android:layout_gravity="center_horizontal"
- android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
- style="@style/TextAppearance.NotificationInfo.ButtonLabel"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center_horizontal"
- android:orientation="vertical">
- <FrameLayout
- android:id="@+id/int_alert_wrapper"
- android:padding="4dp"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:gravity="center">
- <ImageButton
- android:id="@+id/int_alert"
- android:background="@drawable/circle_white_40dp"
- android:src="@drawable/ic_notifications_alert"
- android:layout_gravity="center"
- android:layout_width="40dp"
- android:layout_height="40dp"
- android:contentDescription="@string/inline_silent_button_alert"
- android:clickable="false"
- android:tint="@color/GM2_grey_400"
- style="@style/TextAppearance.NotificationInfo.Button"/>
- </FrameLayout>
+ style="@style/TextAppearance.NotificationInfo.Primary"/>
<TextView
- android:id="@+id/int_alert_label"
- android:text="@string/inline_silent_button_alert"
- android:layout_gravity="center_horizontal"
- android:gravity="center"
+ android:id="@+id/int_silent_summary"
+ android:text="@string/hint_text_silent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
- android:maxLines="1"
- style="@style/TextAppearance.NotificationInfo.ButtonLabel"/>
+ style="@style/TextAppearance.NotificationInfo.Secondary"/>
</LinearLayout>
</LinearLayout>
+ </LinearLayout>
+
+ <RelativeLayout
+ android:id="@+id/bottom_buttons"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/notification_guts_button_spacing"
+ android:paddingBottom="@dimen/notification_guts_button_spacing">
<TextView
- android:id="@+id/hint_text"
- android:layout_marginStart="@*android:dimen/notification_content_margin_start"
- android:layout_marginEnd="@*android:dimen/notification_content_margin_start"
+ android:id="@+id/turn_off_notifications"
+ android:text="@string/inline_turn_off_notifications"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@style/TextAppearance.NotificationInfo.HintText" />
+ android:layout_centerVertical="true"
+ android:layout_alignParentStart="true"
+ android:maxWidth="200dp"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
<TextView
- android:id="@+id/done_button"
+ android:id="@+id/done"
+ android:text="@string/inline_ok_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="right"
- android:paddingRight="24dp"
- android:text="@string/inline_done_button"
- style="@style/TextAppearance.NotificationInfo.Button" />
- </LinearLayout>
+ android:layout_centerVertical="true"
+ android:maxWidth="125dp"
+ android:layout_alignParentEnd="true"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ </RelativeLayout>
+
</LinearLayout>
<com.android.systemui.statusbar.notification.row.NotificationUndoLayout
<!-- The color of the text inside a notification -->
<color name="notification_primary_text_color">@*android:color/notification_primary_text_color_dark</color>
+ <color name="notification_guts_selection_bg">#202124</color>
+ <color name="notification_guts_selection_border">#669DF6</color>
+ <color name="notification_guts_link_icon_tint">@color/GM2_grey_200</color>
+
<!-- The color of the background in the top part of QSCustomizer -->
<color name="qs_customize_background">@color/GM2_grey_900</color>
<!-- The "inside" of a notification, reached via longpress -->
<color name="notification_guts_bg_color">@color/GM2_grey_50</color>
+ <color name="notification_guts_selection_bg">#FFFFFF</color>
+ <color name="notification_guts_selection_border">#4285F4</color>
+ <color name="notification_guts_link_icon_tint">@color/GM2_grey_900</color>
+
<color name="assist_orb_color">#ffffff</color>
<color name="keyguard_user_switcher_background_gradient_color">#77000000</color>
<color name="GM2_red_300">#F28B82</color>
<color name="GM2_red_500">#B71C1C</color>
+
+ <color name="GM2_yellow_500">#FFFBBC04</color>
+ <color name="GM2_green_500">#FF34A853</color>
</resources>
<dimen name="notification_menu_icon_padding">20dp</dimen>
<!-- The vertical space around the buttons in the inline settings -->
- <dimen name="notification_guts_button_spacing">6dp</dimen>
+ <dimen name="notification_guts_button_spacing">12dp</dimen>
<!-- Extra horizontal space for properly aligning guts buttons with the notification content -->
<dimen name="notification_guts_button_side_margin">8dp</dimen>
<!-- The height of the header in inline settings -->
<dimen name="notification_guts_header_height">24dp</dimen>
+ <!-- The text size of the header in inline settings -->
+ <dimen name="notification_guts_header_text_size">16sp</dimen>
+
+ <!-- The horizontal space between items in the alert selections in the inline settings -->
+ <dimen name="notification_guts_option_horizontal_padding">15dp</dimen>
+
+ <!-- The vertical space between items in the alert selections in the inline settings -->
+ <dimen name="notification_guts_option_vertical_padding">15dp</dimen>
+
+ <!-- The vertical space between the alert selections in the inline settings -->
+ <dimen name="notification_guts_option_vertical_margin">6dp</dimen>
+
<!-- The minimum height for the snackbar shown after the snooze option has been chosen. -->
<dimen name="snooze_snackbar_min_height">56dp</dimen>
<string name="inline_done_button">Done</string>
<!-- Notification Inline controls: button to dismiss the blocking helper [CHAR_LIMIT=20] -->
- <string name="inline_ok_button">OK</string>
+ <string name="inline_ok_button">Apply</string>
<!-- Notification Inline controls: continue receiving notifications prompt, channel level -->
<string name="inline_keep_showing">Keep showing these notifications?</string>
<string name="inline_minimize_button">Minimize</string>
<!-- Notification inline controls: button to show notifications silently, without alerting the user [CHAR_LIMIT=35] -->
- <string name="inline_silent_button_silent">Show silently</string>
+ <string name="inline_silent_button_silent">Gentle</string>
<!-- Notification inline controls: button to continue showing notifications silently [CHAR_LIMIT=35] -->
<string name="inline_silent_button_stay_silent">Stay silent</string>
<!-- Notification inline controls: button to make notifications alert the user [CHAR_LIMIT=35] -->
- <string name="inline_silent_button_alert">Alert</string>
+ <string name="inline_silent_button_alert">Interruptive</string>
<!-- Notification inline controls: button to continue alerting the user when notifications arrive [CHAR_LIMIT=35] -->
<string name="inline_silent_button_keep_alerting">Keep alerting</string>
+ <!-- Notification inline controls: button to show block screen [CHAR_LIMIT=35] -->
+ <string name="inline_turn_off_notifications">Turn off notifications</string>
+
<!-- Notification Inline controls: continue receiving notifications prompt, app level -->
<string name="inline_keep_showing_app">Keep showing notifications from this app?</string>
<string name="hint_text_silent">Silent notifications appear in the shade, but do not appear on the lock screen, present a banner, or play a sound.</string>
<!-- Hint text for alert button in the interruptiveness settings [CHAR_LIMIT=NONE]-->
- <string name="hint_text_alert">Alerted notifications appear in the shade, on the lock screen, present a banner, and play a sound.</string>
+ <string name="hint_text_alert">These notifications will make a sound and show in the notification drawer, status bar, and lock screen</string>
<!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
<string name="notification_unblockable_desc">These notifications can\'t be turned off</string>
+ <!-- Notification: Control panel: label that displays when viewing settings for a group of notifications posted to multiple channels. -->
+ <string name="notification_multichannel_desc">This group of notifications cannot be configured here</string>
+
<!-- Notification: Control panel: Label for the app that posted this notification, if it's not the package that the notification was posted for -->
<string name="notification_delegate_header">via <xliff:g id="app_name" example="YouTube">%1$s</xliff:g></string>
</style>
<style name="TextAppearance.NotificationInfo.Primary">
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
<item name="android:textSize">16sp</item>
<item name="android:alpha">0.87</item>
</style>
</style>
<style name="TextAppearance.NotificationInfo.Button">
- <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
- <item name="android:textSize">14sp</item>
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
+ <item name="android:textSize">16sp</item>
<item name="android:textColor">?android:attr/colorAccent</item>
<item name="android:background">@drawable/btn_borderless_rect</item>
<item name="android:gravity">center</item>
<item name="android:focusable">true</item>
- <item name="android:paddingTop">@dimen/notification_guts_button_vertical_padding</item>
- <item name="android:paddingBottom">@dimen/notification_guts_button_vertical_padding</item>
- <item name="android:paddingLeft">@dimen/notification_guts_button_horizontal_padding</item>
- <item name="android:paddingRight">@dimen/notification_guts_button_horizontal_padding</item>
</style>
<style name="TextAppearance.HeadsUpStatusBarText"
// - User sentiment is negative (DEBUG flag can bypass)
// - The notification shade is fully expanded (guarantees we're not touching a HUN).
// - The row is blockable (i.e. not non-blockable)
- // - The dismissed row is a valid group (>1 or 0 children) or the only child in the group
+ // - The dismissed row is a valid group (>1 or 0 children from the same channel)
+ // or the only child in the group
if ((row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE || DEBUG)
&& mIsShadeExpanded
&& !row.getIsNonblockable()
- && (!row.isChildInGroup() || row.isOnlyChildInGroup())) {
+ && ((!row.isChildInGroup() || row.isOnlyChildInGroup())
+ && row.getNumUniqueChannels() <= 1)) {
// Dismiss any current blocking helper before continuing forward (only one can be shown
// at a given time).
dismissCurrentBlockingHelper();
mDeviceProvisionedController.isDeviceProvisioned(),
row.getIsNonblockable(),
isForBlockingHelper,
- row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE,
row.getEntry().importance,
row.getEntry().isHighPriority());
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
import android.metrics.LogMaker;
import android.os.Handler;
import android.os.RemoteException;
public static final int ACTION_NONE = 0;
static final int ACTION_UNDO = 1;
+ // standard controls
static final int ACTION_TOGGLE_SILENT = 2;
+ // unused
static final int ACTION_BLOCK = 3;
+ // blocking helper
static final int ACTION_DELIVER_SILENTLY = 4;
+ // standard controls
private static final int ACTION_ALERT = 5;
private INotificationManager mINotificationManager;
private NotificationChannel mSingleNotificationChannel;
private int mStartingChannelImportance;
private boolean mWasShownHighPriority;
- private int mNotificationBlockState = ACTION_NONE;
/**
* The last importance level chosen by the user. Null if the user has not chosen an importance
* level; non-null once the user takes an action which indicates an explicit preference.
private boolean mIsNonblockable;
private StatusBarNotification mSbn;
private AnimatorSet mExpandAnimation;
- private boolean mIsForeground;
private boolean mIsDeviceProvisioned;
private CheckSaveListener mCheckSaveListener;
private OnSettingsClickListener mOnSettingsClickListener;
private OnAppSettingsClickListener mAppSettingsClickListener;
private NotificationGuts mGutsContainer;
+ private GradientDrawable mSelectedBackground;
/** Whether this view is being shown as part of the blocking helper. */
private boolean mIsForBlockingHelper;
*/
private String mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
- private OnClickListener mOnKeepShowing = v -> {
- mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
- if (mIsForBlockingHelper) {
- closeControls(v);
- mMetricsLogger.write(getLogMaker().setCategory(
- MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
- .setType(MetricsEvent.TYPE_ACTION)
- .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT));
- }
- };
-
+ // used by standard ui
private OnClickListener mOnAlert = v -> {
mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
mChosenImportance = IMPORTANCE_DEFAULT;
- updateButtonsAndHelpText(ACTION_ALERT);
+ updateButtons(ACTION_ALERT);
+ };
+
+ // used by standard ui
+ private OnClickListener mOnSilent = v -> {
+ mExitReason = NotificationCounters.BLOCKING_HELPER_DELIVER_SILENTLY;
+ mChosenImportance = IMPORTANCE_LOW;
+ updateButtons(ACTION_TOGGLE_SILENT);
};
+ // used by standard ui
private OnClickListener mOnDismissSettings = v -> {
closeControls(v);
};
+ // used by blocking helper
+ private OnClickListener mOnKeepShowing = v -> {
+ mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
+ closeControls(v);
+ mMetricsLogger.write(getLogMaker().setCategory(
+ MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
+ .setType(MetricsEvent.TYPE_ACTION)
+ .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT));
+ };
+
+ // used by blocking helper
private OnClickListener mOnDeliverSilently = v -> {
handleSaveImportance(
ACTION_DELIVER_SILENTLY, MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT);
- if (!mIsForBlockingHelper) {
- updateButtonsAndHelpText(ACTION_DELIVER_SILENTLY);
- }
- };
-
- private OnClickListener mOnStopOrMinimizeNotifications = v -> {
- handleSaveImportance(ACTION_BLOCK, MetricsEvent.BLOCKING_HELPER_CLICK_BLOCKED);
- if (!mIsForBlockingHelper) {
- updateButtonsAndHelpText(ACTION_BLOCK);
- }
};
private void handleSaveImportance(int action, int metricsSubtype) {
.setType(MetricsEvent.TYPE_DISMISS)
.setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_UNDO));
} else {
+ // TODO: this can't happen?
mMetricsLogger.write(importanceChangeLogMaker().setType(MetricsEvent.TYPE_DISMISS));
}
saveImportanceAndExitReason(ACTION_UNDO);
bindNotification(pm, iNotificationManager, pkg, notificationChannel,
numUniqueChannelsInRow, sbn, checkSaveListener, onSettingsClick,
onAppSettingsClick, isDeviceProvisioned, isNonblockable,
- false /* isBlockingHelper */, false /* isUserSentimentNegative */,
+ false /* isBlockingHelper */,
importance, wasShownHighPriority);
}
boolean isDeviceProvisioned,
boolean isNonblockable,
boolean isForBlockingHelper,
- boolean isUserSentimentNegative,
int importance,
boolean wasShownHighPriority)
throws RemoteException {
mStartingChannelImportance = mSingleNotificationChannel.getImportance();
mWasShownHighPriority = wasShownHighPriority;
mIsNonblockable = isNonblockable;
- mIsForeground =
- (mSbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
mIsForBlockingHelper = isForBlockingHelper;
mAppUid = mSbn.getUid();
mDelegatePkg = mSbn.getOpPkg();
mIsDeviceProvisioned = isDeviceProvisioned;
+ mSelectedBackground = new GradientDrawable();
+ mSelectedBackground.setShape(GradientDrawable.RECTANGLE);
+ mSelectedBackground.setColor(mContext.getColor(R.color.notification_guts_selection_bg));
+ final float cornerRadii = getResources().getDisplayMetrics().density * 8;
+ mSelectedBackground.setCornerRadii(new float[]{cornerRadii, cornerRadii, cornerRadii,
+ cornerRadii, cornerRadii, cornerRadii, cornerRadii, cornerRadii});
+ mSelectedBackground.setStroke((int) (getResources().getDisplayMetrics().density * 2),
+ mContext.getColor(R.color.notification_guts_selection_border));
+
int numTotalChannels = mINotificationManager.getNumNotificationChannelsForPackage(
pkg, mAppUid, false /* includeDeleted */);
if (mNumUniqueChannelsInRow == 0) {
}
bindHeader();
- bindPrompt();
- bindButtons();
+ bindChannelDetails();
+
+ if (mIsForBlockingHelper) {
+ bindBlockingHelper();
+ } else {
+ bindInlineControls();
+ }
mMetricsLogger.write(notificationControlsLogMaker());
}
- private void bindHeader() throws RemoteException {
+ private void bindBlockingHelper() {
+ findViewById(R.id.inline_controls).setVisibility(GONE);
+ findViewById(R.id.blocking_helper).setVisibility(VISIBLE);
+
+ findViewById(R.id.undo).setOnClickListener(mOnUndo);
+
+ View turnOffButton = findViewById(R.id.blocking_helper_turn_off_notifications);
+ turnOffButton.setOnClickListener(getSettingsOnClickListener());
+ turnOffButton.setVisibility(turnOffButton.hasOnClickListeners() ? VISIBLE : GONE);
+
+ TextView keepShowing = findViewById(R.id.keep_showing);
+ keepShowing.setOnClickListener(mOnKeepShowing);
+
+ View deliverSilently = findViewById(R.id.deliver_silently);
+ deliverSilently.setOnClickListener(mOnDeliverSilently);
+ }
+
+ private void bindInlineControls() {
+ findViewById(R.id.inline_controls).setVisibility(VISIBLE);
+ findViewById(R.id.blocking_helper).setVisibility(GONE);
+
+ if (mIsNonblockable) {
+ findViewById(R.id.non_configurable_text).setVisibility(VISIBLE);
+ findViewById(R.id.non_configurable_multichannel_text).setVisibility(GONE);
+ findViewById(R.id.interruptiveness_settings).setVisibility(GONE);
+ } else if (mNumUniqueChannelsInRow > 1) {
+ findViewById(R.id.non_configurable_text).setVisibility(GONE);
+ findViewById(R.id.interruptiveness_settings).setVisibility(GONE);
+ findViewById(R.id.non_configurable_multichannel_text).setVisibility(VISIBLE);
+ } else {
+ findViewById(R.id.non_configurable_text).setVisibility(GONE);
+ findViewById(R.id.non_configurable_multichannel_text).setVisibility(GONE);
+ findViewById(R.id.interruptiveness_settings).setVisibility(VISIBLE);
+ }
+
+ View turnOffButton = findViewById(R.id.turn_off_notifications);
+ turnOffButton.setOnClickListener(getSettingsOnClickListener());
+ turnOffButton.setVisibility(turnOffButton.hasOnClickListeners() && !mIsNonblockable
+ ? VISIBLE : GONE);
+
+ View done = findViewById(R.id.done);
+ done.setOnClickListener(mOnDismissSettings);
+
+
+ View silent = findViewById(R.id.silent_row);
+ View alert = findViewById(R.id.alert_row);
+ silent.setOnClickListener(mOnSilent);
+ alert.setOnClickListener(mOnAlert);
+
+ if (mWasShownHighPriority) {
+ updateButtons(ACTION_ALERT);
+ } else {
+ updateButtons(ACTION_TOGGLE_SILENT);
+ }
+ }
+
+ private void bindHeader() {
// Package name
Drawable pkgicon = null;
ApplicationInfo info;
// Delegate
bindDelegate();
- // Settings button.
+ // Set up app settings link (i.e. Customize)
+ View settingsLinkView = findViewById(R.id.app_settings);
+ Intent settingsIntent = getAppSettingsIntent(mPm, mPackageName,
+ mSingleNotificationChannel,
+ mSbn.getId(), mSbn.getTag());
+ if (settingsIntent != null
+ && !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
+ settingsLinkView.setVisibility(VISIBLE);
+ settingsLinkView.setOnClickListener((View view) -> {
+ mAppSettingsClickListener.onClick(view, settingsIntent);
+ });
+ } else {
+ settingsLinkView.setVisibility(View.GONE);
+ }
+
+ // System Settings button.
final View settingsButton = findViewById(R.id.info);
+ settingsButton.setOnClickListener(getSettingsOnClickListener());
+ settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE);
+ }
+
+ private OnClickListener getSettingsOnClickListener() {
if (mAppUid >= 0 && mOnSettingsClickListener != null && mIsDeviceProvisioned) {
- settingsButton.setVisibility(View.VISIBLE);
final int appUidF = mAppUid;
- settingsButton.setOnClickListener(
- (View view) -> {
- logBlockingHelperCounter(
- NotificationCounters.BLOCKING_HELPER_NOTIF_SETTINGS);
- mOnSettingsClickListener.onClick(view,
- mNumUniqueChannelsInRow > 1 ? null : mSingleNotificationChannel,
- appUidF);
- });
- } else {
- settingsButton.setVisibility(View.GONE);
+ return ((View view) -> {
+ logBlockingHelperCounter(
+ NotificationCounters.BLOCKING_HELPER_NOTIF_SETTINGS);
+ mOnSettingsClickListener.onClick(view,
+ mNumUniqueChannelsInRow > 1 ? null : mSingleNotificationChannel,
+ appUidF);
+ });
}
+ return null;
}
- private void bindPrompt() throws RemoteException {
- final TextView blockPrompt = findViewById(R.id.block_prompt);
+ private void bindChannelDetails() throws RemoteException {
bindName();
bindGroup();
- if (mIsNonblockable) {
- blockPrompt.setText(R.string.notification_unblockable_desc);
- }
}
private void bindName() {
}
}
- private void bindButtons() {
- findViewById(R.id.undo).setOnClickListener(mOnUndo);
-
- boolean showInterruptivenessSettings =
- !mIsNonblockable
- && !mIsForeground
- && !mIsForBlockingHelper
- && NotificationUtils.useNewInterruptionModel(mContext);
- if (showInterruptivenessSettings) {
- findViewById(R.id.block_or_minimize).setVisibility(GONE);
- findViewById(R.id.interruptiveness_settings).setVisibility(VISIBLE);
- View done = findViewById(R.id.done_button);
- done.setOnClickListener(mOnDismissSettings);
- View block = findViewById(R.id.int_block_wrapper);
- View silent = findViewById(R.id.int_silent_wrapper);
- View alert = findViewById(R.id.int_alert_wrapper);
- block.setOnClickListener(mOnStopOrMinimizeNotifications);
- silent.setOnClickListener(mOnDeliverSilently);
- alert.setOnClickListener(mOnAlert);
- if (mNotificationBlockState != ACTION_NONE) {
- updateButtonsAndHelpText(mNotificationBlockState);
- } else if (mWasShownHighPriority) {
- updateButtonsAndHelpText(ACTION_ALERT);
- } else {
- updateButtonsAndHelpText(ACTION_DELIVER_SILENTLY);
- }
- } else {
- findViewById(R.id.block_or_minimize).setVisibility(VISIBLE);
- findViewById(R.id.interruptiveness_settings).setVisibility(GONE);
- View block = findViewById(R.id.block);
- TextView done = findViewById(R.id.done);
- View minimize = findViewById(R.id.minimize);
- View deliverSilently = findViewById(R.id.deliver_silently);
-
-
- block.setOnClickListener(mOnStopOrMinimizeNotifications);
- done.setOnClickListener(mOnKeepShowing);
- minimize.setOnClickListener(mOnStopOrMinimizeNotifications);
- deliverSilently.setOnClickListener(mOnDeliverSilently);
-
- if (mIsNonblockable) {
- done.setText(android.R.string.ok);
- block.setVisibility(GONE);
- minimize.setVisibility(GONE);
- deliverSilently.setVisibility(GONE);
- } else if (mIsForeground) {
- block.setVisibility(GONE);
- minimize.setVisibility(VISIBLE);
- } else {
- block.setVisibility(VISIBLE);
- minimize.setVisibility(GONE);
- }
-
- // Set up app settings link (i.e. Customize)
- View settingsLinkView = findViewById(R.id.app_settings);
- Intent settingsIntent = getAppSettingsIntent(mPm, mPackageName,
- mSingleNotificationChannel,
- mSbn.getId(), mSbn.getTag());
- if (!mIsForBlockingHelper
- && settingsIntent != null
- && !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
- settingsLinkView.setVisibility(VISIBLE);
- settingsLinkView.setOnClickListener((View view) -> {
- mAppSettingsClickListener.onClick(view, settingsIntent);
- });
- } else {
- settingsLinkView.setVisibility(View.GONE);
- }
- }
- }
-
- private void updateButtonsAndHelpText(int blockState) {
- mNotificationBlockState = blockState;
- ImageView block = findViewById(R.id.int_block);
- ImageView silent = findViewById(R.id.int_silent);
- ImageView alert = findViewById(R.id.int_alert);
- TextView hintText = findViewById(R.id.hint_text);
+ private void updateButtons(int blockState) {
+ View silent = findViewById(R.id.silent_row);
+ View alert = findViewById(R.id.alert_row);
switch (blockState) {
- case ACTION_BLOCK:
- block.setBackgroundResource(R.drawable.circle_blue_40dp);
- block.setColorFilter(Color.WHITE);
- silent.setBackgroundResource(R.drawable.circle_white_40dp);
- silent.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
- alert.setBackgroundResource(R.drawable.circle_white_40dp);
- alert.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
- hintText.setText(R.string.hint_text_block);
- break;
- case ACTION_DELIVER_SILENTLY:
- silent.setBackgroundResource(R.drawable.circle_blue_40dp);
- silent.setColorFilter(Color.WHITE);
- block.setBackgroundResource(R.drawable.circle_white_40dp);
- block.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
- alert.setBackgroundResource(R.drawable.circle_white_40dp);
- alert.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
- hintText.setText(R.string.hint_text_silent);
+ case ACTION_TOGGLE_SILENT:
+ silent.setBackground(mSelectedBackground);
+ alert.setBackground(null);
break;
case ACTION_ALERT:
- alert.setBackgroundResource(R.drawable.circle_blue_40dp);
- alert.setColorFilter(Color.WHITE);
- block.setBackgroundResource(R.drawable.circle_white_40dp);
- block.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
- silent.setBackgroundResource(R.drawable.circle_white_40dp);
- silent.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
- hintText.setText(R.string.hint_text_alert);
+ alert.setBackground(mSelectedBackground);
+ silent.setBackground(null);
break;
}
}
mChosenImportance = IMPORTANCE_DEFAULT;
}
break;
- case ACTION_BLOCK:
- mExitReason = NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS;
- if (mIsForeground) {
- mChosenImportance = IMPORTANCE_MIN;
- } else {
- mChosenImportance = IMPORTANCE_NONE;
- }
- break;
default:
throw new IllegalArgumentException();
}
}
+ // only used for blocking helper
private void swapContent(@NotificationInfoAction int action, boolean animate) {
if (mExpandAnimation != null) {
mExpandAnimation.cancel();
}
- View prompt = findViewById(R.id.prompt);
+ View blockingHelper = findViewById(R.id.blocking_helper);
ViewGroup confirmation = findViewById(R.id.confirmation);
TextView confirmationText = findViewById(R.id.confirmation_text);
- View header = findViewById(R.id.header);
saveImportanceAndExitReason(action);
case ACTION_DELIVER_SILENTLY:
confirmationText.setText(R.string.notification_channel_silenced);
break;
- case ACTION_TOGGLE_SILENT:
- if (mWasShownHighPriority) {
- confirmationText.setText(R.string.notification_channel_silenced);
- } else {
- confirmationText.setText(R.string.notification_channel_unsilenced);
- }
- break;
- case ACTION_BLOCK:
- if (mIsForeground) {
- confirmationText.setText(R.string.notification_channel_minimized);
- } else {
- confirmationText.setText(R.string.notification_channel_disabled);
- }
- break;
default:
throw new IllegalArgumentException();
}
boolean isUndo = action == ACTION_UNDO;
- prompt.setVisibility(isUndo ? VISIBLE : GONE);
+ blockingHelper.setVisibility(isUndo ? VISIBLE : GONE);
+ findViewById(R.id.channel_info).setVisibility(isUndo ? VISIBLE : GONE);
+ findViewById(R.id.header).setVisibility(isUndo ? VISIBLE : GONE);
confirmation.setVisibility(isUndo ? GONE : VISIBLE);
- header.setVisibility(isUndo ? VISIBLE : GONE);
if (animate) {
- ObjectAnimator promptAnim = ObjectAnimator.ofFloat(prompt, View.ALPHA,
- prompt.getAlpha(), isUndo ? 1f : 0f);
+ ObjectAnimator promptAnim = ObjectAnimator.ofFloat(blockingHelper, View.ALPHA,
+ blockingHelper.getAlpha(), isUndo ? 1f : 0f);
promptAnim.setInterpolator(isUndo ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
ObjectAnimator confirmAnim = ObjectAnimator.ofFloat(confirmation, View.ALPHA,
confirmation.getAlpha(), isUndo ? 0f : 1f);
@Override
public void onAnimationEnd(Animator animation) {
if (!mCancelled) {
- prompt.setVisibility(isUndo ? VISIBLE : GONE);
+ blockingHelper.setVisibility(isUndo ? VISIBLE : GONE);
confirmation.setVisibility(isUndo ? GONE : VISIBLE);
}
}
}
mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
- View prompt = findViewById(R.id.prompt);
- ViewGroup confirmation = findViewById(R.id.confirmation);
- View header = findViewById(R.id.header);
- prompt.setVisibility(VISIBLE);
- prompt.setAlpha(1f);
- confirmation.setVisibility(GONE);
- confirmation.setAlpha(1f);
- header.setVisibility(VISIBLE);
- header.setAlpha(1f);
+ if (mIsForBlockingHelper) {
+ bindBlockingHelper();
+ } else {
+ bindInlineControls();
+ }
mMetricsLogger.write(notificationControlsLogMaker().setType(MetricsEvent.TYPE_CLOSE));
}
* commit the updated importance.
*
* <p><b>Note,</b> this will only get called once the view is dismissing. This means that the
- * user does not have the ability to undo the action anymore. See {@link #swapContent(boolean)}
- * for where undo is handled.
+ * user does not have the ability to undo the action anymore. See
+ * {@link #swapContent(boolean, boolean)} for where undo is handled.
*/
@VisibleForTesting
void closeControls(View v) {
package com.android.systemui.statusbar.notification.row;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.NotificationChannel;
import android.content.Context;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
verify(mGutsManager).openGuts(row, 0, 0, mMenuItem);
}
+ @Test
+ public void testPerhapsShowBlockingHelper_notShownForMultiChannelGroup() throws Exception {
+ ExpandableNotificationRow groupRow = createBlockableGroupRowSpy(10);
+ int i = 0;
+ for (ExpandableNotificationRow childRow : groupRow.getNotificationChildren()) {
+ childRow.getEntry().channel =
+ new NotificationChannel(Integer.toString(i++), "", IMPORTANCE_DEFAULT);
+ }
+
+ groupRow.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+
+ assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(groupRow, mMenuRow));
+
+ verify(mGutsManager, never()).openGuts(groupRow, 0, 0, mMenuItem);
+ }
@Test
public void testPerhapsShowBlockingHelper_shownForLargeGroup() throws Exception {
eq(false),
eq(false),
eq(true) /* isForBlockingHelper */,
- eq(true) /* isUserSentimentNegative */,
eq(0),
eq(false) /* wasShownHighPriority */);
}
eq(false),
eq(false),
eq(false) /* isForBlockingHelper */,
- eq(true) /* isUserSentimentNegative */,
eq(0),
eq(false) /* wasShownHighPriority */);
}
eq(false),
eq(false),
eq(true) /* isForBlockingHelper */,
- eq(true) /* isUserSentimentNegative */,
eq(IMPORTANCE_DEFAULT),
eq(true) /* wasShownHighPriority */);
}
eq(true),
eq(false),
eq(false) /* isForBlockingHelper */,
- eq(true) /* isUserSentimentNegative */,
eq(0),
eq(false) /* wasShownHighPriority */);
}
eq(false),
eq(false),
eq(true) /* isForBlockingHelper */,
- eq(true) /* isUserSentimentNegative */,
eq(0),
eq(false) /* wasShownHighPriority */);
}
}
@Test
- public void testBindNotification_BlockButton() throws Exception {
+ public void testBindNotification_BlockLink_BlockingHelper() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_DEFAULT, true);
- final View block = mNotificationInfo.findViewById(R.id.int_block);
- final View minimize = mNotificationInfo.findViewById(R.id.block_or_minimize);
- assertEquals(VISIBLE, block.getVisibility());
- assertEquals(GONE, minimize.getVisibility());
- }
-
- @Test
- public void testBindNotification_BlockButton_BlockingHelper() throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- true /* isBlockingHelper */, false, IMPORTANCE_DEFAULT, true);
- final View block = mNotificationInfo.findViewById(R.id.block);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, mock(
+ NotificationInfo.OnSettingsClickListener.class), null, true, false,
+ true /* isBlockingHelper */, IMPORTANCE_DEFAULT, true);
+ final View block =
+ mNotificationInfo.findViewById(R.id.blocking_helper_turn_off_notifications);
final View interruptivenessSettings = mNotificationInfo.findViewById(
- R.id.interruptiveness_settings);
+ R.id.inline_controls);
assertEquals(VISIBLE, block.getVisibility());
assertEquals(GONE, interruptivenessSettings.getVisibility());
}
@Test
- public void testBindNotification_SilenceButton_CurrentlyAlerting() throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_DEFAULT, true);
- final TextView silent = mNotificationInfo.findViewById(R.id.int_silent_label);
- assertEquals(VISIBLE, silent.getVisibility());
- assertEquals(
- mContext.getString(R.string.inline_silent_button_silent), silent.getText());
- }
-
- @Test
- public void testBindNotification_verifyButtonTexts() throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_LOW, false);
- final TextView block = mNotificationInfo.findViewById(R.id.int_block_label);
- final TextView alert = mNotificationInfo.findViewById(R.id.int_alert_label);
- final TextView silent = mNotificationInfo.findViewById(R.id.int_silent_label);
- assertEquals(VISIBLE, silent.getVisibility());
- assertEquals(VISIBLE, block.getVisibility());
- assertEquals(VISIBLE, alert.getVisibility());
- assertEquals(
- mContext.getString(R.string.inline_silent_button_silent),
- silent.getText());
- assertEquals(
- mContext.getString(R.string.inline_silent_button_alert), alert.getText());
- assertEquals(
- mContext.getString(R.string.inline_block_button), block.getText());
- }
-
- @Test
- public void testBindNotification_verifyHintTextForSilent() throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_LOW, false);
- TextView hintText = mNotificationInfo.findViewById(R.id.hint_text);
- assertEquals(mContext.getString(R.string.hint_text_silent), hintText.getText());
- }
-
- @Test
- public void testBindNotification_verifyHintTextForBlock() throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_LOW, false);
- View blockWrapper = mNotificationInfo.findViewById(R.id.int_block_wrapper);
- blockWrapper.performClick();
- TextView hintText = mNotificationInfo.findViewById(R.id.hint_text);
- assertEquals(mContext.getString(R.string.hint_text_block), hintText.getText());
- }
-
- @Test
- public void testBindNotification_verifyHintTextForAlert() throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_DEFAULT, true);
- TextView hintText = mNotificationInfo.findViewById(R.id.hint_text);
- assertEquals(mContext.getString(R.string.hint_text_alert), hintText.getText());
- }
-
- @Test
- public void testBindNotification_MinButton() throws Exception {
- mSbn.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_DEFAULT, true);
- final View block = mNotificationInfo.findViewById(R.id.block);
- final View interruptivenessSettings = mNotificationInfo.findViewById(
- R.id.interruptiveness_settings);
- final View minimize = mNotificationInfo.findViewById(R.id.minimize);
- assertEquals(GONE, block.getVisibility());
- assertEquals(GONE, interruptivenessSettings.getVisibility());
- assertEquals(VISIBLE, minimize.getVisibility());
- }
-
- @Test
public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
null, null, null,
false, true,
- true, true,
+ true,
IMPORTANCE_DEFAULT, true);
verify(mMetricsLogger).write(argThat(logMaker ->
logMaker.getCategory() == MetricsEvent.ACTION_NOTE_CONTROLS
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
null, null, null,
false, true,
- true, true,
+ true,
IMPORTANCE_DEFAULT, true);
mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
verify(mMetricsLogger).count(eq("HowCanNotifsBeRealIfAppsArent"), eq(1));
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, mSbn, null, null,
- null, true, true, IMPORTANCE_DEFAULT, true);
+ null, true, false, IMPORTANCE_DEFAULT, true);
final TextView channelNameView =
mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(GONE, channelNameView.getVisibility());
public void testStopInvisibleIfBundleFromDifferentChannels() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, mSbn, null, null,
- null, true, true, IMPORTANCE_DEFAULT, true);
- final TextView blockView = mNotificationInfo.findViewById(R.id.block);
- assertEquals(GONE, blockView.getVisibility());
+ null, true, false, IMPORTANCE_DEFAULT, true);
+ assertEquals(GONE, mNotificationInfo.findViewById(
+ R.id.interruptiveness_settings).getVisibility());
+ assertEquals(VISIBLE, mNotificationInfo.findViewById(
+ R.id.non_configurable_multichannel_text).getVisibility());
}
@Test
- public void testbindNotification_UnblockableTextVisibleWhenAppUnblockable() throws Exception {
+ public void testBindNotification_whenAppUnblockable() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
IMPORTANCE_DEFAULT, true);
- final TextView view = mNotificationInfo.findViewById(R.id.block_prompt);
+ final TextView view = mNotificationInfo.findViewById(R.id.non_configurable_text);
assertEquals(View.VISIBLE, view.getVisibility());
assertEquals(mContext.getString(R.string.notification_unblockable_desc),
view.getText());
+ assertEquals(GONE,
+ mNotificationInfo.findViewById(R.id.interruptiveness_settings).getVisibility());
}
@Test
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_DEFAULT, false);
-
- mNotificationInfo.findViewById(R.id.int_block).performClick();
- mTestableLooper.processAllMessages();
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
- anyString(), eq(TEST_UID), any());
- }
-
- @Test
- public void testDoesNotUpdateNotificationChannelAfterImportanceChangedMin()
- throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_DEFAULT, false);
+ IMPORTANCE_LOW, false);
- mNotificationInfo.findViewById(R.id.minimize).performClick();
+ mNotificationInfo.findViewById(R.id.alert_row).performClick();
mTestableLooper.processAllMessages();
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), any());
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
IMPORTANCE_DEFAULT, true);
- mNotificationInfo.findViewById(R.id.int_silent).performClick();
- mTestableLooper.processAllMessages();
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
- anyString(), eq(TEST_UID), any());
- }
-
- @Test
- public void testDoesNotUpdateNotificationChannelAfterImportanceChangedUnSilenced()
- throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_DEFAULT, false);
-
- mNotificationInfo.findViewById(R.id.int_alert).performClick();
+ mNotificationInfo.findViewById(R.id.silent_row).performClick();
mTestableLooper.processAllMessages();
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), any());
}
@Test
- public void testHandleCloseControls_setsNotificationsDisabledForMultipleChannelNotifications()
- throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
- 10 /* numUniqueChannelsInRow */, mSbn, null /* checkSaveListener */,
- null /* onSettingsClick */, null /* onAppSettingsClick */,
- true, false /* isNonblockable */, IMPORTANCE_DEFAULT, false
- );
-
- mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
- mNotificationInfo.findViewById(R.id.done_button).performClick();
- mNotificationInfo.handleCloseControls(true, false);
-
- mTestableLooper.processAllMessages();
- verify(mMockINotificationManager, times(1))
- .setNotificationsEnabledWithImportanceLockForPackage(
- anyString(), eq(TEST_UID), eq(false));
- }
-
-
- @Test
- public void testHandleCloseControls_keepsNotificationsEnabledForMultipleChannelNotifications()
- throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
- 10 /* numUniqueChannelsInRow */, mSbn, null /* checkSaveListener */,
- null /* onSettingsClick */, null /* onAppSettingsClick */,
- true, false /* isNonblockable */, IMPORTANCE_DEFAULT, false
- );
-
- mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
- mNotificationInfo.findViewById(R.id.done_button).performClick();
- mNotificationInfo.handleCloseControls(true, false);
-
- mTestableLooper.processAllMessages();
- verify(mMockINotificationManager, times(1))
- .setNotificationsEnabledWithImportanceLockForPackage(
- anyString(), eq(TEST_UID), eq(false));
- }
-
- @Test
- public void testCloseControls_blockingHelperSavesImportanceForMultipleChannelNotifications()
- throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
- 10 /* numUniqueChannelsInRow */, mSbn, null /* checkSaveListener */,
- null /* onSettingsClick */, null /* onAppSettingsClick */,
- true /* provisioned */,
- false /* isNonblockable */, true /* isForBlockingHelper */,
- true /* isUserSentimentNegative */, IMPORTANCE_DEFAULT, true);
-
- NotificationGuts guts = spy(new NotificationGuts(mContext, null));
- when(guts.getWindowToken()).thenReturn(mock(IBinder.class));
- doNothing().when(guts).animateClose(anyInt(), anyInt(), anyBoolean());
- doNothing().when(guts).setExposed(anyBoolean(), anyBoolean());
- guts.setGutsContent(mNotificationInfo);
- mNotificationInfo.setGutsParent(guts);
-
- mNotificationInfo.findViewById(R.id.done).performClick();
-
- verify(mBlockingHelperManager).dismissCurrentBlockingHelper();
- mTestableLooper.processAllMessages();
- verify(mMockINotificationManager, times(1))
- .setNotificationsEnabledWithImportanceLockForPackage(
- anyString(), eq(TEST_UID), eq(true));
- }
-
- @Test
public void testCloseControls_nonNullCheckSaveListenerDoesntDelayKeepShowing_BlockingHelper()
throws Exception {
NotificationInfo.CheckSaveListener listener =
10 /* numUniqueChannelsInRow */, mSbn, listener /* checkSaveListener */,
null /* onSettingsClick */, null /* onAppSettingsClick */, true /* provisioned */,
false /* isNonblockable */, true /* isForBlockingHelper */,
- true /* isUserSentimentNegative */, IMPORTANCE_DEFAULT, true);
+ IMPORTANCE_DEFAULT, true);
NotificationGuts guts = spy(new NotificationGuts(mContext, null));
when(guts.getWindowToken()).thenReturn(mock(IBinder.class));
guts.setGutsContent(mNotificationInfo);
mNotificationInfo.setGutsParent(guts);
- mNotificationInfo.findViewById(R.id.done).performClick();
+ mNotificationInfo.findViewById(R.id.keep_showing).performClick();
verify(mBlockingHelperManager).dismissCurrentBlockingHelper();
mTestableLooper.processAllMessages();
10 /* numUniqueChannelsInRow */, mSbn, listener /* checkSaveListener */,
null /* onSettingsClick */, null /* onAppSettingsClick */,
false /* isNonblockable */, true /* isForBlockingHelper */,
- true, true /* isUserSentimentNegative */, /* isNoisy */
- IMPORTANCE_DEFAULT, true);
+ true, IMPORTANCE_DEFAULT, true);
mNotificationInfo.handleCloseControls(true /* save */, false /* force */);
null /* onSettingsClick */, null /* onAppSettingsClick */,
true /* provisioned */,
false /* isNonblockable */, true /* isForBlockingHelper */,
- true /* isUserSentimentNegative */, IMPORTANCE_DEFAULT, true);
+ IMPORTANCE_DEFAULT, true);
- mNotificationInfo.findViewById(R.id.block).performClick();
+ mNotificationInfo.findViewById(R.id.deliver_silently).performClick();
mTestableLooper.processAllMessages();
verify(listener).checkSave(any(Runnable.class), eq(mSbn));
}
false /* isNonblockable */,
true /* isForBlockingHelper */,
true,
- false /* isUserSentimentNegative */,
IMPORTANCE_DEFAULT, true);
NotificationGuts guts = mock(NotificationGuts.class);
doCallRealMethod().when(guts).closeControls(anyInt(), anyInt(), anyBoolean(), anyBoolean());
}
@Test
- public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
- true, false, IMPORTANCE_DEFAULT, false);
- mNotificationInfo.findViewById(R.id.block).performClick();
- waitForUndoButton();
-
- mTestableLooper.processAllMessages();
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
- anyString(), eq(TEST_UID), any());
- }
-
- @Test
- public void testBlockChangedCallsUpdateNotificationChannel_notBlockingHelper()
+ public void testSilentlyChangedCallsUpdateNotificationChannel_blockingHelper()
throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
- null, null, null,
- true, false,
- IMPORTANCE_DEFAULT, false);
-
- mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
- mNotificationInfo.findViewById(R.id.done_button).performClick();
- mNotificationInfo.handleCloseControls(true, false);
-
- ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
- verify(mMetricsLogger, times(2)).write(logMakerCaptor.capture());
- assertEquals(MetricsProto.MetricsEvent.TYPE_ACTION,
- logMakerCaptor.getValue().getType());
- assertEquals(IMPORTANCE_NONE - IMPORTANCE_LOW,
- logMakerCaptor.getValue().getSubtype());
-
- mTestableLooper.processAllMessages();
- ArgumentCaptor<NotificationChannel> updated =
- ArgumentCaptor.forClass(NotificationChannel.class);
- verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
- anyString(), eq(TEST_UID), updated.capture());
- assertTrue((updated.getValue().getUserLockedFields()
- & USER_LOCKED_IMPORTANCE) != 0);
- assertEquals(IMPORTANCE_NONE, updated.getValue().getImportance());
- }
-
- @Test
- public void testBlockChangedCallsUpdateNotificationChannel_blockingHelper() throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
true /*provisioned */,
false /* isNonblockable */,
true /* isForBlockingHelper */,
- true /* isUserSentimentNegative */,
IMPORTANCE_DEFAULT,
false);
- mNotificationInfo.findViewById(R.id.block).performClick();
+ mNotificationInfo.findViewById(R.id.deliver_silently).performClick();
waitForUndoButton();
mNotificationInfo.handleCloseControls(true, false);
- ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
- verify(mMetricsLogger, times(3)).write(logMakerCaptor.capture());
- assertEquals(MetricsProto.MetricsEvent.TYPE_ACTION,
- logMakerCaptor.getValue().getType());
- assertEquals(IMPORTANCE_NONE - IMPORTANCE_LOW,
- logMakerCaptor.getValue().getSubtype());
-
mTestableLooper.processAllMessages();
ArgumentCaptor<NotificationChannel> updated =
ArgumentCaptor.forClass(NotificationChannel.class);
anyString(), eq(TEST_UID), updated.capture());
assertTrue((updated.getValue().getUserLockedFields()
& USER_LOCKED_IMPORTANCE) != 0);
- assertEquals(IMPORTANCE_NONE, updated.getValue().getImportance());
+ assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance());
}
-
@Test
- public void testNonBlockableAppDoesNotBecomeMin() throws Exception {
+ public void testKeepUpdatesNotificationChannel_blockingHelper() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
- true, false, IMPORTANCE_DEFAULT, false);
- mNotificationInfo.findViewById(R.id.minimize).performClick();
- waitForUndoButton();
-
- mTestableLooper.processAllMessages();
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
- anyString(), eq(TEST_UID), any());
- }
-
- @Test
- public void testMinChangedCallsUpdateNotificationChannel() throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mSbn.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- true, false, IMPORTANCE_DEFAULT, false);
-
- mNotificationInfo.findViewById(R.id.minimize).performClick();
- waitForUndoButton();
- mNotificationInfo.handleCloseControls(true, false);
-
- mTestableLooper.processAllMessages();
- ArgumentCaptor<NotificationChannel> updated =
- ArgumentCaptor.forClass(NotificationChannel.class);
- verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
- anyString(), eq(TEST_UID), updated.capture());
- assertTrue((updated.getValue().getUserLockedFields()
- & USER_LOCKED_IMPORTANCE) != 0);
- assertEquals(IMPORTANCE_MIN, updated.getValue().getImportance());
- }
-
- @Test
- public void testSilentlyChangedCallsUpdateNotificationChannel_blockingHelper()
- throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(
- mMockPackageManager,
- mMockINotificationManager,
- TEST_PACKAGE_NAME,
- mNotificationChannel,
- 1 /* numChannels */,
- mSbn,
- null /* checkSaveListener */,
- null /* onSettingsClick */,
- null /* onAppSettingsClick */,
- true /*provisioned */,
- false /* isNonblockable */,
- true /* isForBlockingHelper */,
- true /* isUserSentimentNegative */,
- IMPORTANCE_DEFAULT,
- false);
+ IMPORTANCE_LOW, false);
- mNotificationInfo.findViewById(R.id.deliver_silently).performClick();
- waitForUndoButton();
+ mNotificationInfo.findViewById(R.id.keep_showing).performClick();
mNotificationInfo.handleCloseControls(true, false);
mTestableLooper.processAllMessages();
ArgumentCaptor.forClass(NotificationChannel.class);
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), updated.capture());
- assertTrue((updated.getValue().getUserLockedFields()
- & USER_LOCKED_IMPORTANCE) != 0);
- assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance());
+ assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE));
+ assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance());
}
@Test
- public void testKeepUpdatesNotificationChannel() throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
+ public void testNoActionsUpdatesNotificationChannel_blockingHelper() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
IMPORTANCE_DEFAULT, false);
mNotificationInfo.handleCloseControls(true, false);
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), updated.capture());
assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE));
- assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance());
+ assertEquals(IMPORTANCE_DEFAULT, mNotificationChannel.getImportance());
}
@Test
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
IMPORTANCE_DEFAULT, true);
- mNotificationInfo.findViewById(R.id.int_silent_wrapper).performClick();
- mNotificationInfo.findViewById(R.id.done_button).performClick();
+ mNotificationInfo.findViewById(R.id.silent_row).performClick();
+ mNotificationInfo.findViewById(R.id.done).performClick();
mNotificationInfo.handleCloseControls(true, false);
mTestableLooper.processAllMessages();
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
IMPORTANCE_DEFAULT, false);
- mNotificationInfo.findViewById(R.id.int_alert_wrapper).performClick();
- mNotificationInfo.findViewById(R.id.done_button).performClick();
+ mNotificationInfo.findViewById(R.id.alert_row).performClick();
+ mNotificationInfo.findViewById(R.id.done).performClick();
mNotificationInfo.handleCloseControls(true, false);
mTestableLooper.processAllMessages();
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
IMPORTANCE_DEFAULT, true);
- mNotificationInfo.findViewById(R.id.int_silent_wrapper).performClick();
- mNotificationInfo.findViewById(R.id.done_button).performClick();
+ mNotificationInfo.findViewById(R.id.silent_row).performClick();
+ mNotificationInfo.findViewById(R.id.done).performClick();
mNotificationInfo.handleCloseControls(true, false);
mTestableLooper.processAllMessages();
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
IMPORTANCE_LOW, false);
- mNotificationInfo.findViewById(R.id.int_alert_wrapper).performClick();
- mNotificationInfo.findViewById(R.id.done_button).performClick();
+ mNotificationInfo.findViewById(R.id.alert_row).performClick();
+ mNotificationInfo.findViewById(R.id.done).performClick();
mNotificationInfo.handleCloseControls(true, false);
mTestableLooper.processAllMessages();
}
@Test
- public void testCloseControlsDoesNotUpdateMinIfSaveIsFalse() throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
- true, false, IMPORTANCE_DEFAULT, false);
-
- mNotificationInfo.findViewById(R.id.minimize).performClick();
- waitForUndoButton();
- mNotificationInfo.handleCloseControls(false, false);
-
- mTestableLooper.processAllMessages();
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
- eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
- }
-
- @Test
public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_DEFAULT, false);
+ IMPORTANCE_LOW, false);
- mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
- mNotificationInfo.findViewById(R.id.done_button).performClick();
+ mNotificationInfo.findViewById(R.id.alert_row).performClick();
+ mNotificationInfo.findViewById(R.id.done).performClick();
mNotificationInfo.handleCloseControls(false, false);
mTestableLooper.processAllMessages();
}
@Test
- public void testBlockDoesNothingIfCheckSaveListenerIsNoOp() throws Exception {
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
- (Runnable saveImportance, StatusBarNotification sbn) -> {
- }, null, null, true, true, IMPORTANCE_DEFAULT, false);
-
- mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
- mTestableLooper.processAllMessages();
- mNotificationInfo.handleCloseControls(true, false);
-
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
- eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
- }
-
- @Test
public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
(Runnable saveImportance, StatusBarNotification sbn) -> {
saveImportance.run();
- }, null, null, true, false, IMPORTANCE_DEFAULT, false
+ }, null, null, true, false, IMPORTANCE_LOW, false
);
- mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
- mNotificationInfo.findViewById(R.id.done_button).performClick();
+ mNotificationInfo.findViewById(R.id.alert_row).performClick();
+ mNotificationInfo.findViewById(R.id.done).performClick();
mTestableLooper.processAllMessages();
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
public void testWillBeRemovedReturnsFalseBeforeBind() throws Exception {
assertFalse(mNotificationInfo.willBeRemoved());
}
-
- @Test
- public void testUndoText_min() throws Exception {
- mSbn.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
- mNotificationChannel.setImportance(IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
- true, false, IMPORTANCE_DEFAULT, false);
-
- mNotificationInfo.findViewById(R.id.minimize).performClick();
- waitForUndoButton();
- TextView confirmationText = mNotificationInfo.findViewById(R.id.confirmation_text);
- assertTrue(confirmationText.getText().toString().contains("minimized"));
- }
}