Redesign channel listing and channel page

Test: atest
Bug: 127796543
Fixes: 129452112
Fixes: 129453207
Change-Id: I1d520c9e35860303235b7ffbb18a76cbc4f4b8bc
This commit is contained in:
Julia Reynolds
2019-04-12 16:52:40 -04:00
parent 670bf45b50
commit 5c097c6d3c
21 changed files with 405 additions and 579 deletions

View 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>

View 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>

View 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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 &amp; 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 &amp; 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 &amp; 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 &amp; 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>

View File

@@ -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>

View File

@@ -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"

View File

@@ -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);
}
}

View File

@@ -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(

View File

@@ -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);
}
}
};
}

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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));
}
}