diff --git a/res/drawable/ic_notification_alert.xml b/res/drawable/ic_notification_alert.xml
new file mode 100644
index 00000000000..07e7b48700b
--- /dev/null
+++ b/res/drawable/ic_notification_alert.xml
@@ -0,0 +1,43 @@
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/ic_notification_block.xml b/res/drawable/ic_notification_block.xml
new file mode 100644
index 00000000000..d4f0a2aa877
--- /dev/null
+++ b/res/drawable/ic_notification_block.xml
@@ -0,0 +1,43 @@
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/ic_notification_silence.xml b/res/drawable/ic_notification_silence.xml
new file mode 100644
index 00000000000..673340f6532
--- /dev/null
+++ b/res/drawable/ic_notification_silence.xml
@@ -0,0 +1,43 @@
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/notif_importance_preference.xml b/res/layout/notif_importance_preference.xml
new file mode 100644
index 00000000000..5d79ff3af67
--- /dev/null
+++ b/res/layout/notif_importance_preference.xml
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 7b55a2bb94b..2fbba7e3114 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -124,6 +124,11 @@
#fffdd835
#ff9e9e9e
+
+ #ffff0000
+ #fbbc04
+ #30a751
+
@*android:color/accent_device_default_light
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a36d8abc7ef..f5b6e958789 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -68,6 +68,9 @@
64dp
20dp
4dp
+ 48dp
+ 8dp
+ 16dp
7dp
17dp
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2f338788153..7a7f54e8a90 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7771,7 +7771,7 @@
summary on the channel page-->
- Low
+ Minimize
Medium
@@ -7780,7 +7780,16 @@
High
- Urgent
+ Pop on screen
+
+
+ Block
+
+
+ Show silently
+
+
+ Alert
Allow interruptions
diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml
index 94a2cdb3d2c..6015f7f6fe0 100644
--- a/res/xml/channel_notification_settings.xml
+++ b/res/xml/channel_notification_settings.xml
@@ -25,11 +25,6 @@
android:order="1"
android:layout="@layout/settings_entity_header" />
-
-
-
+ android:order="4"
+ android:title="@string/notification_importance_title"
+ settings:allowDividerBelow="true"/>
+
+
+
+
+ android:order="110"
+ settings:allowDividerAbove="false"/>
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 9f5ece24a56..5fd26a64c95 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -152,6 +152,10 @@ public class AppNotificationSettings extends NotificationSettingsBase {
context, mImportanceListener, mBackend));
mControllers.add(new ImportancePreferenceController(
context, mImportanceListener, mBackend));
+ mControllers.add(new MinImportancePreferenceController(
+ context, mImportanceListener, mBackend));
+ mControllers.add(new HighImportancePreferenceController(
+ context, mImportanceListener, mBackend));
mControllers.add(new SoundPreferenceController(context, this,
mImportanceListener, mBackend));
mControllers.add(new LightsPreferenceController(context, mBackend));
diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java
index f92e529aab1..850fde2f67d 100644
--- a/src/com/android/settings/notification/ChannelNotificationSettings.java
+++ b/src/com/android/settings/notification/ChannelNotificationSettings.java
@@ -94,9 +94,12 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
protected List 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(
+ context, mImportanceListener, mBackend));
+ mControllers.add(new HighImportancePreferenceController(
+ context, mImportanceListener, mBackend));
mControllers.add(new AllowSoundPreferenceController(
context, mImportanceListener, mBackend));
mControllers.add(new SoundPreferenceController(context, this,
diff --git a/src/com/android/settings/notification/HighImportancePreferenceController.java b/src/com/android/settings/notification/HighImportancePreferenceController.java
new file mode 100644
index 00000000000..fe843fd5078
--- /dev/null
+++ b/src/com/android/settings/notification/HighImportancePreferenceController.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+
+import android.app.NotificationChannel;
+import android.content.Context;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import androidx.preference.Preference;
+
+public class HighImportancePreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String KEY_IMPORTANCE = "high_importance";
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+
+ public HighImportancePreferenceController(Context context,
+ NotificationSettingsBase.ImportanceListener importanceListener,
+ NotificationBackend backend) {
+ super(context, backend);
+ mImportanceListener = importanceListener;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_IMPORTANCE;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ if (mChannel == null) {
+ return false;
+ }
+ if (isDefaultChannel()) {
+ return false;
+ }
+ return mChannel.getImportance() >= IMPORTANCE_DEFAULT;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (mAppRow!= null && mChannel != null) {
+ preference.setEnabled(mAdmin == null && isChannelConfigurable());
+
+ RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
+ pref.setChecked(mChannel.getImportance() >= IMPORTANCE_HIGH);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mChannel != null) {
+ final boolean checked = (boolean) newValue;
+
+ mChannel.setImportance(checked ? IMPORTANCE_HIGH : IMPORTANCE_DEFAULT);
+ mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+ saveChannel();
+ mImportanceListener.onImportanceChanged();
+ }
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ImportancePreference.java b/src/com/android/settings/notification/ImportancePreference.java
new file mode 100644
index 00000000000..b8f3e4587c3
--- /dev/null
+++ b/src/com/android/settings/notification/ImportancePreference.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.LayerDrawable;
+import android.util.ArrayMap;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageButton;
+
+import com.android.settingslib.R;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+public class ImportancePreference extends Preference {
+
+ boolean mIsBlockable = true;
+ boolean mIsConfigurable = true;
+ int mImportance;
+ ImageButton blockButton;
+ ImageButton silenceButton;
+ ImageButton alertButton;
+ ArrayMap mImageButtons = new ArrayMap<>();
+ Context mContext;
+
+ public ImportancePreference(Context context, AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init(context);
+ }
+
+ public ImportancePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context);
+ }
+
+ public ImportancePreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public ImportancePreference(Context context) {
+ super(context);
+ init(context);
+ }
+
+ private void init(Context context) {
+ mContext = context;
+ setLayoutResource(R.layout.notif_importance_preference);
+ }
+
+ public void setImportance(int importance) {
+ mImportance = importance;
+ }
+
+ public void setBlockable(boolean blockable) {
+ mIsBlockable = blockable;
+ }
+
+ public void setConfigurable(boolean configurable) {
+ mIsConfigurable = configurable;
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ View blockView = holder.itemView.findViewById(R.id.block);
+ View alertView = holder.itemView.findViewById(R.id.alert);
+ View silenceView = holder.itemView.findViewById(R.id.silence);
+ if (!mIsBlockable) {
+ blockView.setVisibility(View.GONE);
+ if (mImportance == IMPORTANCE_NONE) {
+ mImportance = IMPORTANCE_LOW;
+ callChangeListener(IMPORTANCE_LOW);
+ }
+
+ }
+ blockButton = blockView.findViewById(R.id.block_icon);
+ silenceButton = silenceView.findViewById(R.id.silence_icon);
+ alertButton = alertView.findViewById(R.id.alert_icon);
+ mImageButtons.put(blockButton, mContext.getColor(R.color.notification_block_color));
+ mImageButtons.put(silenceButton, mContext.getColor(R.color.notification_silence_color));
+ mImageButtons.put(alertButton, mContext.getColor(R.color.notification_alert_color));
+
+ switch (mImportance) {
+ case IMPORTANCE_NONE:
+ colorizeImageButton(blockButton.getId());
+ if (!mIsConfigurable) {
+ alertView.setVisibility(View.GONE);
+ silenceView.setVisibility(View.GONE);
+ }
+ break;
+ case IMPORTANCE_MIN:
+ case IMPORTANCE_LOW:
+ colorizeImageButton(silenceButton.getId());
+ if (!mIsConfigurable) {
+ alertView.setVisibility(View.GONE);
+ blockView.setVisibility(View.GONE);
+ }
+ break;
+ case IMPORTANCE_HIGH:
+ default:
+ colorizeImageButton(alertButton.getId());
+ if (!mIsConfigurable) {
+ blockView.setVisibility(View.GONE);
+ silenceView.setVisibility(View.GONE);
+ }
+ break;
+ }
+
+ blockButton.setOnClickListener(v -> {
+ callChangeListener(IMPORTANCE_NONE);
+ colorizeImageButton(blockButton.getId());
+ });
+ silenceButton.setOnClickListener(v -> {
+ callChangeListener(IMPORTANCE_LOW);
+ colorizeImageButton(silenceButton.getId());
+ });
+ alertButton.setOnClickListener(v -> {
+ callChangeListener(IMPORTANCE_DEFAULT);
+ colorizeImageButton(alertButton.getId());
+ });
+ }
+
+ private void colorizeImageButton(int buttonId) {
+ if (mImageButtons != null) {
+ for (int i = 0; i < mImageButtons.size(); i++) {
+ final ImageButton imageButton = mImageButtons.keyAt(i);
+ final int color = mImageButtons.valueAt(i);
+ if (imageButton != null) {
+ LayerDrawable drawable = (LayerDrawable) imageButton.getDrawable();
+ Drawable foreground = drawable.findDrawableByLayerId(R.id.fore);
+ GradientDrawable background =
+ (GradientDrawable) drawable.findDrawableByLayerId(R.id.back);
+ if (buttonId == imageButton.getId()) {
+ foreground.setTint(Color.WHITE);
+ background.setColor(color);
+ } else {
+ foreground.setTint(color);
+ background.setColor(Color.TRANSPARENT);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ImportancePreferenceController.java b/src/com/android/settings/notification/ImportancePreferenceController.java
index 4c20a46409d..09555718b6f 100644
--- a/src/com/android/settings/notification/ImportancePreferenceController.java
+++ b/src/com/android/settings/notification/ImportancePreferenceController.java
@@ -18,21 +18,15 @@ package com.android.settings.notification;
import static android.app.NotificationChannel.USER_LOCKED_SOUND;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import android.app.NotificationChannel;
-import android.app.NotificationManager;
import android.content.Context;
import android.media.RingtoneManager;
-import androidx.preference.Preference;
-
-import com.android.settings.R;
-import com.android.settings.RestrictedListPreference;
import com.android.settings.core.PreferenceControllerMixin;
+import androidx.preference.Preference;
+
public class ImportancePreferenceController extends NotificationPreferenceController
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
@@ -53,44 +47,33 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
@Override
public boolean isAvailable() {
- if (!super.isAvailable()) {
+ if (mAppRow == null) {
return false;
}
if (mChannel == null) {
return false;
}
- return !isDefaultChannel();
+ if (isDefaultChannel()) {
+ return false;
+ }
+ return true;
}
@Override
public void updateState(Preference preference) {
if (mAppRow!= null && mChannel != null) {
preference.setEnabled(mAdmin == null && isChannelConfigurable());
- preference.setSummary(getImportanceSummary(mChannel));
-
- int importances = IMPORTANCE_HIGH - IMPORTANCE_MIN + 1;
- CharSequence[] entries = new CharSequence[importances];
- CharSequence[] values = new CharSequence[importances];
-
- int index = 0;
- for (int i = IMPORTANCE_HIGH; i >= IMPORTANCE_MIN; i--) {
- NotificationChannel channel = new NotificationChannel("", "", i);
- entries[index] = getImportanceSummary(channel);
- values[index] = String.valueOf(i);
- index++;
- }
-
- RestrictedListPreference pref = (RestrictedListPreference) preference;
- pref.setEntries(entries);
- pref.setEntryValues(values);
- pref.setValue(String.valueOf(mChannel.getImportance()));
+ ImportancePreference pref = (ImportancePreference) preference;
+ pref.setBlockable(isChannelBlockable());
+ pref.setConfigurable(isChannelConfigurable());
+ pref.setImportance(mChannel.getImportance());
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (mChannel != null) {
- final int importance = Integer.parseInt((String) newValue);
+ final int importance = (Integer) newValue;
// If you are moving from an importance level without sound to one with sound,
// but the sound you had selected was "Silence",
@@ -111,39 +94,4 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
}
return true;
}
-
- protected String getImportanceSummary(NotificationChannel channel) {
- String summary = "";
- int importance = channel.getImportance();
- switch (importance) {
- case IMPORTANCE_UNSPECIFIED:
- summary = mContext.getString(R.string.notification_importance_unspecified);
- break;
- case NotificationManager.IMPORTANCE_MIN:
- summary = mContext.getString(R.string.notification_importance_min);
- break;
- case NotificationManager.IMPORTANCE_LOW:
- summary = mContext.getString(R.string.notification_importance_low);
- break;
- case NotificationManager.IMPORTANCE_DEFAULT:
- if (SoundPreferenceController.hasValidSound(channel)) {
- summary = mContext.getString(R.string.notification_importance_default);
- } else {
- summary = mContext.getString(R.string.notification_importance_low);
- }
- break;
- case NotificationManager.IMPORTANCE_HIGH:
- case NotificationManager.IMPORTANCE_MAX:
- if (SoundPreferenceController.hasValidSound(channel)) {
- summary = mContext.getString(R.string.notification_importance_high);
- } else {
- summary = mContext.getString(R.string.notification_importance_high_silent);
- }
- break;
- default:
- return "";
- }
-
- return summary;
- }
}
diff --git a/src/com/android/settings/notification/MinImportancePreferenceController.java b/src/com/android/settings/notification/MinImportancePreferenceController.java
new file mode 100644
index 00000000000..771ac609fc5
--- /dev/null
+++ b/src/com/android/settings/notification/MinImportancePreferenceController.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+
+import android.app.NotificationChannel;
+import android.content.Context;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import androidx.preference.Preference;
+
+public class MinImportancePreferenceController extends NotificationPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String KEY_IMPORTANCE = "min_importance";
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+
+ public MinImportancePreferenceController(Context context,
+ NotificationSettingsBase.ImportanceListener importanceListener,
+ NotificationBackend backend) {
+ super(context, backend);
+ mImportanceListener = importanceListener;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_IMPORTANCE;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ if (mChannel == null) {
+ return false;
+ }
+ if (isDefaultChannel()) {
+ return false;
+ }
+ return mChannel.getImportance() <= IMPORTANCE_LOW;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (mAppRow!= null && mChannel != null) {
+ preference.setEnabled(mAdmin == null && isChannelConfigurable());
+
+ RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
+ pref.setChecked(mChannel.getImportance() == IMPORTANCE_MIN);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mChannel != null) {
+ final boolean checked = (boolean) newValue;
+
+ mChannel.setImportance(checked ? IMPORTANCE_MIN : IMPORTANCE_LOW);
+ mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+ saveChannel();
+ mImportanceListener.onImportanceChanged();
+ }
+ return true;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
index 4f6944a3ce4..bdbf40a35ac 100644
--- a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
@@ -110,6 +110,26 @@ public class BlockPreferenceControllerTest {
assertFalse(mController.isAvailable());
}
+ @Test
+ public void testIsAvailable_notIfChannelNonDefault() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = true;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_ifChannelDefault() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
@Test
public void testIsAvailable_notIfGroupNotBlockable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
diff --git a/tests/robotests/src/com/android/settings/notification/HighImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/HighImportancePreferenceControllerTest.java
new file mode 100644
index 00000000000..6e6dad4c839
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/HighImportancePreferenceControllerTest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.UserManager;
+
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+@RunWith(RobolectricTestRunner.class)
+public class HighImportancePreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+ @Mock
+ private UserManager mUm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+
+ private HighImportancePreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = RuntimeEnvironment.application;
+ mController = spy(new HighImportancePreferenceController(
+ mContext, mImportanceListener, mBackend));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() {
+ mController.isAvailable();
+ mController.updateState(mock(Preference.class));
+ }
+
+ @Test
+ public void testIsAvailable_notIfNull() {
+ mController.onResume(null, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_ifAppBlocked() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, mock(NotificationChannel.class), null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfChannelBlocked() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notForDefaultChannel() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin() {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new RestrictedSwitchPreference(mContext, null);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_notConfigurable() {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(mContext, null);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_high() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
+ mController.updateState(pref);
+
+ assertTrue(pref.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_default() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
+ mController.updateState(pref);
+
+ assertFalse(pref.isChecked());
+ }
+
+ @Test
+ public void onPreferenceChange() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext, null);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, false);
+
+ assertEquals(IMPORTANCE_DEFAULT, channel.getImportance());
+ verify(mImportanceListener, times(1)).onImportanceChanged();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
index 99d3376e82e..c180acede19 100644
--- a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceControllerTest.java
@@ -27,8 +27,11 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Notification;
@@ -36,12 +39,10 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.UserManager;
-import android.text.TextUtils;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
-import com.android.settings.RestrictedListPreference;
import com.android.settingslib.RestrictedLockUtils;
import org.junit.Before;
@@ -95,20 +96,20 @@ public class ImportancePreferenceControllerTest {
}
@Test
- public void testIsAvailable_notIfAppBlocked() {
+ public void testIsAvailable_ifAppBlocked() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, mock(NotificationChannel.class), null, null);
- assertFalse(mController.isAvailable());
+ assertTrue(mController.isAvailable());
}
@Test
- public void testIsAvailable_notIfChannelBlocked() {
+ public void testIsAvailable_evenIfChannelBlocked() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
- assertFalse(mController.isAvailable());
+ assertTrue(mController.isAvailable());
}
@Test
@@ -137,11 +138,10 @@ public class ImportancePreferenceControllerTest {
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
- Preference pref = new RestrictedListPreference(mContext, null);
+ Preference pref = new ImportancePreference(mContext, null);
mController.updateState(pref);
assertFalse(pref.isEnabled());
- assertFalse(TextUtils.isEmpty(pref.getSummary()));
}
@Test
@@ -154,11 +154,10 @@ public class ImportancePreferenceControllerTest {
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
- Preference pref = new RestrictedListPreference(mContext, null);
+ Preference pref = new ImportancePreference(mContext, null);
mController.updateState(pref);
assertFalse(pref.isEnabled());
- assertFalse(TextUtils.isEmpty(pref.getSummary()));
}
@Test
@@ -167,11 +166,12 @@ public class ImportancePreferenceControllerTest {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
- Preference pref = new RestrictedListPreference(mContext, null);
+ ImportancePreference pref = mock(ImportancePreference.class);
mController.updateState(pref);
- assertTrue(pref.isEnabled());
- assertFalse(TextUtils.isEmpty(pref.getSummary()));
+ verify(pref, times(1)).setConfigurable(anyBoolean());
+ verify(pref, times(1)).setBlockable(anyBoolean());
+ verify(pref, times(1)).setImportance(IMPORTANCE_HIGH);
}
@Test
@@ -181,13 +181,12 @@ public class ImportancePreferenceControllerTest {
channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
- RestrictedListPreference pref = new RestrictedListPreference(mContext, null);
+ ImportancePreference pref = new ImportancePreference(mContext, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
- pref.setValue(String.valueOf(IMPORTANCE_HIGH));
- mController.onPreferenceChange(pref, pref.getValue());
+ mController.onPreferenceChange(pref, IMPORTANCE_HIGH);
assertEquals(IMPORTANCE_HIGH, channel.getImportance());
assertNotNull(channel.getSound());
@@ -200,13 +199,12 @@ public class ImportancePreferenceControllerTest {
channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
- RestrictedListPreference pref = new RestrictedListPreference(mContext, null);
+ ImportancePreference pref = new ImportancePreference(mContext, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
- pref.setValue(String.valueOf(IMPORTANCE_LOW));
- mController.onPreferenceChange(pref, pref.getValue());
+ mController.onPreferenceChange(pref, IMPORTANCE_LOW);
assertEquals(IMPORTANCE_LOW, channel.getImportance());
assertNull(channel.getSound());
diff --git a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java
new file mode 100644
index 00000000000..eebfbd1bda1
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.LayerDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+
+import com.android.settings.R;
+import com.android.settingslib.RestrictedLockUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+@RunWith(RobolectricTestRunner.class)
+public class ImportancePreferenceTest {
+
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ }
+
+ private GradientDrawable getBackground(ImageButton button) {
+ return (GradientDrawable) ((LayerDrawable) button.getDrawable())
+ .findDrawableByLayerId(R.id.back);
+ }
+
+ @Test
+ public void createNewPreference_shouldSetLayout() {
+ final ImportancePreference preference = new ImportancePreference(mContext);
+ assertThat(preference.getLayoutResource()).isEqualTo(
+ R.layout.notif_importance_preference);
+ }
+
+ @Test
+ public void onBindViewHolder_hideBlockNonBlockable() {
+ final ImportancePreference preference = new ImportancePreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+
+ preference.setBlockable(false);
+ preference.setConfigurable(true);
+ preference.setImportance(IMPORTANCE_DEFAULT);
+ preference.onBindViewHolder(holder);
+
+ assertThat(holder.itemView.findViewById(R.id.block).getVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_hideNonSelectedNonConfigurable() {
+ final ImportancePreference preference = new ImportancePreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+
+ preference.setBlockable(true);
+ preference.setConfigurable(false);
+ preference.setImportance(IMPORTANCE_DEFAULT);
+ preference.onBindViewHolder(holder);
+
+ assertThat(holder.itemView.findViewById(R.id.block).getVisibility()).isEqualTo(View.GONE);
+ assertThat(holder.itemView.findViewById(R.id.silence).getVisibility()).isEqualTo(View.GONE);
+ assertThat(holder.itemView.findViewById(R.id.alert).getVisibility())
+ .isEqualTo(View.VISIBLE);
+
+ // other button
+ preference.setImportance(IMPORTANCE_LOW);
+ holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+ preference.onBindViewHolder(holder);
+
+ assertThat(holder.itemView.findViewById(R.id.block).getVisibility()).isEqualTo(View.GONE);
+ assertThat(holder.itemView.findViewById(R.id.silence).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(holder.itemView.findViewById(R.id.alert).getVisibility())
+ .isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_selectButton() {
+ final ImportancePreference preference = new ImportancePreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+
+ preference.setBlockable(true);
+ preference.setConfigurable(true);
+ preference.setImportance(IMPORTANCE_DEFAULT);
+
+ ImageButton blockButton = (ImageButton) holder.findViewById(R.id.block_icon);
+ ImageButton silenceButton = (ImageButton) holder.findViewById(R.id.silence_icon);
+ ImageButton alertButton = (ImageButton) holder.findViewById(R.id.alert_icon);
+
+ preference.onBindViewHolder(holder);
+
+ // selected has full color background. others are transparent
+ assertThat(getBackground(alertButton).getColor().getColors()[0]).isNotEqualTo(
+ Color.TRANSPARENT);
+ assertThat(getBackground(silenceButton).getColor().getColors()[0]).isEqualTo(
+ Color.TRANSPARENT);
+ assertThat(getBackground(blockButton).getColor().getColors()[0]).isEqualTo(
+ Color.TRANSPARENT);
+ }
+
+ @Test
+ public void onClick_changesUICallsListener() {
+ final ImportancePreference preference = spy(new ImportancePreference(mContext));
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+
+ preference.setBlockable(true);
+ preference.setConfigurable(true);
+ preference.setImportance(IMPORTANCE_DEFAULT);
+ preference.onBindViewHolder(holder);
+
+ ImageButton blockButton = (ImageButton) holder.findViewById(R.id.block_icon);
+ ImageButton silenceButton = (ImageButton) holder.findViewById(R.id.silence_icon);
+ ImageButton alertButton = (ImageButton) holder.findViewById(R.id.alert_icon);
+
+ silenceButton.callOnClick();
+
+ // selected has full color background. others are transparent
+ assertThat(getBackground(silenceButton).getColor().getColors()[0]).isNotEqualTo(
+ Color.TRANSPARENT);
+ assertThat(getBackground(alertButton).getColor().getColors()[0]).isEqualTo(
+ Color.TRANSPARENT);
+ assertThat(getBackground(blockButton).getColor().getColors()[0]).isEqualTo(
+ Color.TRANSPARENT);
+
+ verify(preference, times(1)).callChangeListener(IMPORTANCE_LOW);
+ }
+
+ @Test
+ public void onBindViewHolder_allButtonsVisible() {
+ final ImportancePreference preference = new ImportancePreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.notif_importance_preference, null));
+
+ preference.setBlockable(true);
+ preference.setConfigurable(true);
+ preference.onBindViewHolder(holder);
+
+ assertThat(holder.itemView.findViewById(R.id.block).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(holder.itemView.findViewById(R.id.silence).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(holder.itemView.findViewById(R.id.alert).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/MinImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/MinImportancePreferenceControllerTest.java
new file mode 100644
index 00000000000..28058a409ef
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/MinImportancePreferenceControllerTest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.UserManager;
+
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+@RunWith(RobolectricTestRunner.class)
+public class MinImportancePreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationSettingsBase.ImportanceListener mImportanceListener;
+ @Mock
+ private UserManager mUm;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+
+ private MinImportancePreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+ shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
+ mContext = RuntimeEnvironment.application;
+ mController = spy(new MinImportancePreferenceController(
+ mContext, mImportanceListener, mBackend));
+ }
+
+ @Test
+ public void testNoCrashIfNoOnResume() {
+ mController.isAvailable();
+ mController.updateState(mock(Preference.class));
+ }
+
+ @Test
+ public void testIsAvailable_notIfNull() {
+ mController.onResume(null, null, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_ifAppBlocked() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.banned = true;
+ mController.onResume(appRow, mock(NotificationChannel.class), null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notIfChannelBlocked() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable_notForDefaultChannel() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
+ public void testIsAvailable() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void testUpdateState_disabledByAdmin() {
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
+ RestrictedLockUtils.EnforcedAdmin.class));
+
+ Preference pref = new RestrictedSwitchPreference(mContext, null);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_notConfigurable() {
+ String lockedId = "locked";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.lockedChannelId = lockedId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(lockedId);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+
+ Preference pref = new RestrictedSwitchPreference(mContext, null);
+ mController.updateState(pref);
+
+ assertFalse(pref.isEnabled());
+ }
+
+ @Test
+ public void testUpdateState_min() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_MIN);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
+ mController.updateState(pref);
+
+ assertTrue(pref.isChecked());
+ }
+
+ @Test
+ public void testUpdateState_low() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
+ mController.onResume(appRow, channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
+ mController.updateState(pref);
+
+ assertFalse(pref.isChecked());
+ }
+
+ @Test
+ public void onPreferenceChange() {
+ NotificationChannel channel =
+ new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
+ mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
+
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext, null);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
+ mController.displayPreference(mScreen);
+ mController.updateState(pref);
+
+ mController.onPreferenceChange(pref, true);
+
+ assertEquals(IMPORTANCE_MIN, channel.getImportance());
+ verify(mImportanceListener, times(1)).onImportanceChanged();
+ }
+}