diff --git a/res/drawable/button_border_selected.xml b/res/drawable/button_border_selected.xml
new file mode 100644
index 00000000000..2681bf051b4
--- /dev/null
+++ b/res/drawable/button_border_selected.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/button_border_unselected.xml b/res/drawable/button_border_unselected.xml
new file mode 100644
index 00000000000..72e9076ccf2
--- /dev/null
+++ b/res/drawable/button_border_unselected.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/button_ripple_radius.xml b/res/drawable/button_ripple_radius.xml
new file mode 100644
index 00000000000..511520c2866
--- /dev/null
+++ b/res/drawable/button_ripple_radius.xml
@@ -0,0 +1,26 @@
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/ic_notification_alert.xml b/res/drawable/ic_notification_alert.xml
index 07e7b48700b..927f7ccfc3c 100644
--- a/res/drawable/ic_notification_alert.xml
+++ b/res/drawable/ic_notification_alert.xml
@@ -19,25 +19,23 @@ Copyright (C) 2019 The Android Open Source Project
android:id="@+id/back">
+ android:color="@color/notification_alert_color" />
-
+ android:height="24dp"
+ android:width="24dp"/>
-
+ android:width="13dp"
+ android:height="13dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ 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" />
\ No newline at end of file
diff --git a/res/drawable/ic_notification_silence.xml b/res/drawable/ic_notification_silence.xml
index 673340f6532..9da56dd0bbf 100644
--- a/res/drawable/ic_notification_silence.xml
+++ b/res/drawable/ic_notification_silence.xml
@@ -19,25 +19,23 @@ Copyright (C) 2019 The Android Open Source Project
android:id="@+id/back">
+ android:color="@color/notification_silence_color" />
-
+ android:height="24dp"
+ android:width="24dp"/>
-
+ android:width="13dp"
+ android:height="13dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ 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"/>
-
\ No newline at end of file
+
diff --git a/res/layout/notif_importance_preference.xml b/res/layout/notif_importance_preference.xml
index 5d79ff3af67..bc0d5aa90b3 100644
--- a/res/layout/notif_importance_preference.xml
+++ b/res/layout/notif_importance_preference.xml
@@ -21,84 +21,53 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
- android:orientation="horizontal">
+ android:orientation="vertical">
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+ android:text="@string/notification_alert_title"
+ android:gravity="center"
+ android:layout_marginTop="@dimen/notification_importance_text_marginTop"
+ android:layout_marginBottom="@dimen/notification_importance_toggle_marginBottom"
+ android:paddingStart="@dimen/notification_importance_description_padding"
+ android:paddingEnd="@dimen/notification_importance_description_padding"
+ android:textAppearance="@style/TextAppearance.NotificationImportanceDetail" />
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 23fe25518d3..d4363b1486e 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -124,8 +124,9 @@
#ffff0000
- #fbbc04
- #30a751
+ #FF32c1de
+ #FFF87B2B
+ #FFDADCE0
@*android:color/accent_device_default_light
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 09828553ded..c871ac8b525 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -69,11 +69,22 @@
20dp
4dp
48dp
- 8dp
- 16dp
+ 28dp
+ 28dp
+ 20dp
+ 16dp
+ 178dp
+ 36dp
+ 8dp
+ 20dp
+ 14sp
+ 16sp
+
7dp
17dp
+ 8dp
+
48dp
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 61d952aa40d..c6e7db59d97 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7951,10 +7951,10 @@
Block
- Show silently
+ Gentle
- Alert
+ Prioritized
Allow interruptions
@@ -7964,17 +7964,26 @@
-
- Low importance
+
+ In the pull-down shade, collapse notifications to one line
-
- Medium importance
+
+ Gentle notifications will display in pull-down list
-
- High importance
+
+ Gentle notifications will display in pull-down list & status bar
-
- Urgent importance
+
+ Gentle notifications will display in pull-down list & on lock screen
+
+
+ Gentle notifications will display in pull-down list, status bar & on lock screen
+
+
+ Prioritized notifications will alert and display in pull-down list, status bar & on lock screen
+
+
+ When phone is unlocked, show notifications as a banner across top of screen
Show notifications
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 9a02fcd0fdd..8678e6ecec5 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -542,4 +542,24 @@
- true
+
+
+
+
+
+
+
+
diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml
index 14e0366af31..267281f28cb 100644
--- a/res/xml/channel_notification_settings.xml
+++ b/res/xml/channel_notification_settings.xml
@@ -25,6 +25,11 @@
android:order="1"
android:layout="@layout/settings_entity_header" />
+
+
+ android:title="@string/notification_importance_min_title"
+ android:summary="@string/notification_channel_summary_min"/>
+ android:title="@string/notification_importance_high_title"
+ android:summary="@string/notification_channel_summary_high"/>
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(
diff --git a/src/com/android/settings/notification/ChannelSummaryPreference.java b/src/com/android/settings/notification/ChannelSummaryPreference.java
deleted file mode 100644
index 338e5e07848..00000000000
--- a/src/com/android/settings/notification/ChannelSummaryPreference.java
+++ /dev/null
@@ -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);
- }
- }
- };
-}
diff --git a/src/com/android/settings/notification/ImportancePreference.java b/src/com/android/settings/notification/ImportancePreference.java
index b8f3e4587c3..5572b125140 100644
--- a/src/com/android/settings/notification/ImportancePreference.java
+++ b/src/com/android/settings/notification/ImportancePreference.java
@@ -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 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);
- } else {
- foreground.setTint(color);
- background.setColor(Color.TRANSPARENT);
- }
- }
+ void setImportanceSummary(TextView view, int importance) {
+ if (importance >= IMPORTANCE_DEFAULT) {
+ view.setText(R.string.notification_channel_summary_default);
+ } else {
+ 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);
}
}
}
diff --git a/src/com/android/settings/notification/ImportancePreferenceController.java b/src/com/android/settings/notification/ImportancePreferenceController.java
index 94a268b7bfc..6fde9aa67ef 100644
--- a/src/com/android/settings/notification/ImportancePreferenceController.java
+++ b/src/com/android/settings/notification/ImportancePreferenceController.java
@@ -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
}
}
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index 765193b843e..f27f9792e03 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -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);
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index b9fabb6600e..163671a979b 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -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) {
- boolean value = (Boolean) o;
- int importance = value ? IMPORTANCE_LOW : IMPORTANCE_NONE;
- channel.setImportance(importance);
- channel.lockFields(
- NotificationChannel.USER_LOCKED_IMPORTANCE);
- mBackend.updateChannel(mPkg, mUid, channel);
+ (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;
- }
+ 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);
diff --git a/tests/robotests/src/com/android/settings/notification/ChannelSummaryPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/ChannelSummaryPreferenceTest.java
deleted file mode 100644
index 408b2b66f25..00000000000
--- a/tests/robotests/src/com/android/settings/notification/ChannelSummaryPreferenceTest.java
+++ /dev/null
@@ -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);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
index cee7a060f9b..c9f62e98c3b 100644
--- a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
@@ -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
diff --git a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java
index eebfbd1bda1..63bc8284255 100644
--- a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java
@@ -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));
}
}