Add list of selected/excluded convos to bubble settings
* Some changes to extend AppConversationListPrefController
* When a user removes something from the selected or
excluded list that resets the channel setting
Bug: 148619540
Test: make -j40 RunSettingsRoboTests ROBOTEST_FILTER="Bubble"
Change-Id: I7a9ed7b70208dbdefca6c3c09d34d55c65f06408
diff --git a/res/drawable/ic_delete_x.xml b/res/drawable/ic_delete_x.xml
new file mode 100644
index 0000000..345daf0
--- /dev/null
+++ b/res/drawable/ic_delete_x.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+<path
+ android:fillColor="#FF000000"
+ android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
+</vector>
diff --git a/res/layout/bubble_conversation_remove_button.xml b/res/layout/bubble_conversation_remove_button.xml
new file mode 100644
index 0000000..6ec48dc
--- /dev/null
+++ b/res/layout/bubble_conversation_remove_button.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<ImageButton
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/button"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:scaleType="centerInside"
+ android:tint="?android:attr/textColorSecondary"
+ android:src="@drawable/ic_delete_x"/>
\ No newline at end of file
diff --git a/res/xml/app_bubble_notification_settings.xml b/res/xml/app_bubble_notification_settings.xml
index 3f52ad3..976d9f0 100644
--- a/res/xml/app_bubble_notification_settings.xml
+++ b/res/xml/app_bubble_notification_settings.xml
@@ -27,4 +27,12 @@
android:title="@string/notification_bubbles_title"
settings:allowDividerBelow="false"/>
+ <!-- Selected or excluded conversations get added here -->
+ <PreferenceCategory
+ android:title="@string/bubble_app_setting_selected_conversation_title"
+ android:key="bubble_conversations"
+ android:visibility="gone"
+ settings:allowDividerAbove="false"
+ settings:allowDividerBelow="false" />
+
</PreferenceScreen>
diff --git a/src/com/android/settings/notification/AppBubbleListPreferenceController.java b/src/com/android/settings/notification/AppBubbleListPreferenceController.java
new file mode 100644
index 0000000..457a61c
--- /dev/null
+++ b/src/com/android/settings/notification/AppBubbleListPreferenceController.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2020 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_ALLOW_BUBBLE;
+import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
+import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
+import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
+
+import android.annotation.Nullable;
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.content.Context;
+import android.content.pm.ShortcutInfo;
+import android.graphics.drawable.Drawable;
+import android.service.notification.ConversationChannelWrapper;
+import android.view.View;
+import android.widget.ImageView;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+import com.android.settings.notification.app.AppConversationListPreferenceController;
+import com.android.settingslib.RestrictedLockUtils;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Displays a list of conversations that have either been selected or excluded from bubbling.
+ */
+public class AppBubbleListPreferenceController extends AppConversationListPreferenceController {
+
+ private static final String KEY = "bubble_conversations";
+
+ public AppBubbleListPreferenceController(Context context, NotificationBackend backend) {
+ super(context, backend);
+ }
+
+ @Override
+ public void onResume(NotificationBackend.AppRow appRow,
+ @Nullable NotificationChannel channel, @Nullable NotificationChannelGroup group,
+ Drawable conversationDrawable,
+ ShortcutInfo conversationInfo,
+ RestrictedLockUtils.EnforcedAdmin admin) {
+ super.onResume(appRow, channel, group, conversationDrawable, conversationInfo, admin);
+ // In case something changed in the foreground (e.g. via bubble button on notification)
+ loadConversationsAndPopulate();
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+ if (mAppRow.bubblePreference == BUBBLE_PREFERENCE_NONE) {
+ return false;
+ }
+ return true;
+ }
+
+ @VisibleForTesting
+ @Override
+ public List<ConversationChannelWrapper> filterAndSortConversations(
+ List<ConversationChannelWrapper> conversations) {
+ return conversations.stream()
+ .sorted(mConversationComparator)
+ .filter((c) -> {
+ if (mAppRow.bubblePreference == BUBBLE_PREFERENCE_SELECTED) {
+ return c.getNotificationChannel().canBubble();
+ } else if (mAppRow.bubblePreference == BUBBLE_PREFERENCE_ALL) {
+ return c.getNotificationChannel().getAllowBubbles() == 0;
+ }
+ return false;
+ })
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ protected int getTitleResId() {
+ // TODO: possible to left align like mocks?
+ return mAppRow.bubblePreference == BUBBLE_PREFERENCE_SELECTED
+ ? R.string.bubble_app_setting_selected_conversation_title
+ : R.string.bubble_app_setting_excluded_conversation_title;
+ }
+
+ @VisibleForTesting
+ @Override
+ public Preference createConversationPref(final ConversationChannelWrapper conversation) {
+ final ConversationPreference pref = new ConversationPreference(mContext);
+ populateConversationPreference(conversation, pref);
+ pref.setOnClickListener((v) -> {
+ conversation.getNotificationChannel().setAllowBubbles(DEFAULT_ALLOW_BUBBLE);
+ mBackend.updateChannel(mAppRow.pkg, mAppRow.uid, conversation.getNotificationChannel());
+ mPreference.removePreference(pref);
+ if (mPreference.getPreferenceCount() == 0) {
+ mPreference.setVisible(false);
+ }
+ });
+ return pref;
+ }
+
+ /** Simple preference with a 'x' button at the end. */
+ @VisibleForTesting
+ public static class ConversationPreference extends Preference implements View.OnClickListener {
+
+ View.OnClickListener mOnClickListener;
+
+ ConversationPreference(Context context) {
+ super(context);
+ setWidgetLayoutResource(R.layout.bubble_conversation_remove_button);
+ }
+
+ @Override
+ public void onBindViewHolder(final PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ ImageView view = holder.itemView.findViewById(R.id.button);
+ view.setOnClickListener(mOnClickListener);
+ }
+
+ public void setOnClickListener(View.OnClickListener listener) {
+ mOnClickListener = listener;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (mOnClickListener != null) {
+ mOnClickListener.onClick(v);
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/app/AppBubbleNotificationSettings.java b/src/com/android/settings/notification/app/AppBubbleNotificationSettings.java
index 5026a26..b1b126e 100644
--- a/src/com/android/settings/notification/app/AppBubbleNotificationSettings.java
+++ b/src/com/android/settings/notification/app/AppBubbleNotificationSettings.java
@@ -22,6 +22,7 @@
import android.util.Log;
import com.android.settings.R;
+import com.android.settings.notification.AppBubbleListPreferenceController;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -56,18 +57,20 @@
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
- mControllers = getPreferenceControllers(context, this);
+ mControllers = getPreferenceControllers(context, this, mDependentFieldListener);
return new ArrayList<>(mControllers);
}
protected static List<NotificationPreferenceController> getPreferenceControllers(
- Context context, AppBubbleNotificationSettings fragment) {
+ Context context, AppBubbleNotificationSettings fragment,
+ DependentFieldListener listener) {
List<NotificationPreferenceController> controllers = new ArrayList<>();
controllers.add(new HeaderPreferenceController(context, fragment));
controllers.add(new BubblePreferenceController(context, fragment != null
? fragment.getChildFragmentManager()
: null,
- new NotificationBackend(), true /* isAppPage */));
+ new NotificationBackend(), true /* isAppPage */, listener));
+ controllers.add(new AppBubbleListPreferenceController(context, new NotificationBackend()));
return controllers;
}
@@ -114,7 +117,7 @@
public List<AbstractPreferenceController> createPreferenceControllers(Context
context) {
return new ArrayList<>(AppBubbleNotificationSettings.getPreferenceControllers(
- context, null));
+ context, null, null));
}
};
}
diff --git a/src/com/android/settings/notification/app/AppConversationListPreferenceController.java b/src/com/android/settings/notification/app/AppConversationListPreferenceController.java
index bea0157..2fcd2b2 100644
--- a/src/com/android/settings/notification/app/AppConversationListPreferenceController.java
+++ b/src/com/android/settings/notification/app/AppConversationListPreferenceController.java
@@ -19,6 +19,7 @@
import android.app.NotificationChannel;
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -33,6 +34,7 @@
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.notification.NotificationBackend;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -42,8 +44,8 @@
private static final String KEY = "conversations";
public static final String ARG_FROM_SETTINGS = "fromSettings";
- private List<ConversationChannelWrapper> mConversations;
- private PreferenceCategory mPreference;
+ protected List<ConversationChannelWrapper> mConversations = new ArrayList<>();
+ protected PreferenceCategory mPreference;
private boolean mHasSentMsg;
public AppConversationListPreferenceController(Context context, NotificationBackend backend) {
@@ -75,13 +77,23 @@
@Override
public void updateState(Preference preference) {
mPreference = (PreferenceCategory) preference;
+ loadConversationsAndPopulate();
+ }
+
+ protected void loadConversationsAndPopulate() {
+ if (mAppRow == null) {
+ return;
+ }
// Load channel settings
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... unused) {
mHasSentMsg = mBackend.hasSentMessage(mAppRow.pkg, mAppRow.uid);
- mConversations = mBackend.getConversations(mAppRow.pkg, mAppRow.uid).getList();
- Collections.sort(mConversations, mConversationComparator);
+ ParceledListSlice<ConversationChannelWrapper> list =
+ mBackend.getConversations(mAppRow.pkg, mAppRow.uid);
+ if (list != null) {
+ mConversations = filterAndSortConversations(list.getList());
+ }
return null;
}
@@ -95,11 +107,22 @@
}.execute();
}
+ protected List<ConversationChannelWrapper> filterAndSortConversations(
+ List<ConversationChannelWrapper> conversations) {
+ Collections.sort(conversations, mConversationComparator);
+ return conversations;
+ }
+
+ protected int getTitleResId() {
+ return R.string.conversations_category_title;
+ }
+
private void populateList() {
+ if (mPreference == null) {
+ return;
+ }
// TODO: if preference has children, compare with newly loaded list
mPreference.removeAll();
- mPreference.setTitle(R.string.conversations_category_title);
-
if (mConversations.isEmpty()) {
if (mHasSentMsg) {
mPreference.setVisible(true);
@@ -112,6 +135,7 @@
}
} else {
mPreference.setVisible(true);
+ mPreference.setTitle(getTitleResId());
populateConversations();
}
}
@@ -127,6 +151,12 @@
protected Preference createConversationPref(final ConversationChannelWrapper conversation) {
Preference pref = new Preference(mContext);
+ populateConversationPreference(conversation, pref);
+ return pref;
+ }
+
+ protected void populateConversationPreference(final ConversationChannelWrapper conversation,
+ final Preference pref) {
ShortcutInfo si = conversation.getShortcutInfo();
pref.setTitle(si != null
@@ -157,7 +187,6 @@
.setTitleText(pref.getTitle())
.setSourceMetricsCategory(SettingsEnums.NOTIFICATION_APP_NOTIFICATION)
.toIntent());
- return pref;
}
protected Comparator<ConversationChannelWrapper> mConversationComparator =
diff --git a/src/com/android/settings/notification/app/BubblePreferenceController.java b/src/com/android/settings/notification/app/BubblePreferenceController.java
index 02d6d99..0ca2095 100644
--- a/src/com/android/settings/notification/app/BubblePreferenceController.java
+++ b/src/com/android/settings/notification/app/BubblePreferenceController.java
@@ -49,12 +49,15 @@
private boolean mIsAppPage;
private boolean mHasSentInvalidMsg;
private int mNumConversations;
+ private NotificationSettings.DependentFieldListener mListener;
public BubblePreferenceController(Context context, @Nullable FragmentManager fragmentManager,
- NotificationBackend backend, boolean isAppPage) {
+ NotificationBackend backend, boolean isAppPage,
+ @Nullable NotificationSettings.DependentFieldListener listener) {
super(context, backend);
mFragmentManager = fragmentManager;
mIsAppPage = isAppPage;
+ mListener = listener;
}
@Override
@@ -128,6 +131,9 @@
mBackend.setAllowBubbles(mAppRow.pkg, mAppRow.uid, value);
}
}
+ if (mListener != null) {
+ mListener.onFieldValueChanged();
+ }
}
return true;
}
diff --git a/src/com/android/settings/notification/app/ConversationNotificationSettings.java b/src/com/android/settings/notification/app/ConversationNotificationSettings.java
index 9ee4a2c..902c81c 100644
--- a/src/com/android/settings/notification/app/ConversationNotificationSettings.java
+++ b/src/com/android/settings/notification/app/ConversationNotificationSettings.java
@@ -92,7 +92,7 @@
mControllers.add(new BadgePreferenceController(context, mBackend));
mControllers.add(new NotificationsOffPreferenceController(context));
mControllers.add(new BubblePreferenceController(context, getChildFragmentManager(),
- mBackend, false /* isAppPage */));
+ mBackend, false /* isAppPage */, null /* dependentFieldListener */));
mControllers.add(new ConversationDemotePreferenceController(context, this, mBackend));
mControllers.add(new BubbleCategoryPreferenceController(context));
mControllers.add(new BubbleLinkPreferenceController(context));
diff --git a/tests/robotests/src/com/android/settings/notification/app/AppBubbleListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/AppBubbleListPreferenceControllerTest.java
new file mode 100644
index 0000000..d176827
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/app/AppBubbleListPreferenceControllerTest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2020 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.app;
+
+import static android.app.NotificationChannel.DEFAULT_ALLOW_BUBBLE;
+import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
+import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
+import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+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.content.pm.ParceledListSlice;
+import android.content.pm.ShortcutInfo;
+import android.os.UserManager;
+import android.service.notification.ConversationChannelWrapper;
+
+import androidx.preference.PreferenceCategory;
+
+import com.android.settings.notification.AppBubbleListPreferenceController;
+import com.android.settings.notification.NotificationBackend;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+@RunWith(RobolectricTestRunner.class)
+public class AppBubbleListPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock
+ private NotificationBackend mBackend;
+ @Mock
+ private NotificationManager mNm;
+ @Mock
+ private UserManager mUm;
+
+ private AppBubbleListPreferenceController mController;
+ private ParceledListSlice<ConversationChannelWrapper> mConvoList;
+
+ @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;
+
+ List<ConversationChannelWrapper> convoList = new ArrayList<>();
+ convoList.add(getConvo(-1, "default"));
+ convoList.add(getConvo(1, "selected"));
+ convoList.add(getConvo(0, "excluded"));
+ mConvoList = new ParceledListSlice<>(convoList);
+ when(mBackend.getConversations(anyString(), anyInt())).thenReturn(mConvoList);
+ mController = new AppBubbleListPreferenceController(mContext, mBackend);
+ }
+
+ ConversationChannelWrapper getConvo(int bubbleChannelPref, String channelId) {
+ ConversationChannelWrapper ccw = new ConversationChannelWrapper();
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(channelId);
+ when(channel.getAllowBubbles()).thenReturn(bubbleChannelPref);
+ when(channel.canBubble()).thenReturn(bubbleChannelPref == 1);
+ ccw.setNotificationChannel(channel);
+ ccw.setPkg("pkg");
+ ccw.setUid(1);
+ ccw.setShortcutInfo(mock(ShortcutInfo.class));
+ return ccw;
+ }
+
+ @Test
+ public void isAvailable_BUBBLE_PREFERENCE_NONE_false() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.bubblePreference = BUBBLE_PREFERENCE_NONE;
+ mController.onResume(appRow, null, null, null, null, null);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_BUBBLE_PREFERENCE_SELECTED_true() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
+ mController.onResume(appRow, null, null, null, null, null);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_BUBBLE_PREFERENCE_ALL_true() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
+ mController.onResume(appRow, null, null, null, null, null);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void filterAndSortConversations_BUBBLE_PREFERENCE_SELECTED_filtersAllowedBubbles() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
+ mController.onResume(appRow, null, null, null, null, null);
+
+ List<ConversationChannelWrapper> result =
+ mController.filterAndSortConversations(mConvoList.getList());
+ assertThat(result.size()).isEqualTo(1);
+ assertThat(result.get(0).getNotificationChannel().getId())
+ .isEqualTo("selected");
+ }
+
+ @Test
+ public void filterAndSortConversations_BUBBLE_PREFERENCE_ALL_filtersExcludedBubbles() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
+ mController.onResume(appRow, null, null, null, null, null);
+
+ List<ConversationChannelWrapper> result =
+ mController.filterAndSortConversations(mConvoList.getList());
+ assertThat(result.size()).isEqualTo(1);
+ assertThat(result.get(0).getNotificationChannel().getId())
+ .isEqualTo("excluded");
+ }
+
+ @Test
+ public void clickConversationPref_updatesChannel() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
+ appRow.pkg = "PKG";
+ mController.onResume(appRow, null, null, null, null, null);
+ mController.mPreference = new PreferenceCategory(mContext);
+
+ ConversationChannelWrapper ccw = mConvoList.getList().get(0);
+ AppBubbleListPreferenceController.ConversationPreference pref =
+ (AppBubbleListPreferenceController.ConversationPreference)
+ mController.createConversationPref(ccw);
+ pref.onClick(null);
+
+ verify(ccw.getNotificationChannel()).setAllowBubbles(DEFAULT_ALLOW_BUBBLE);
+ verify(mBackend).updateChannel(anyString(), anyInt(), any(NotificationChannel.class));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java
index 0cf6dc6..685bca9 100644
--- a/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java
@@ -80,6 +80,8 @@
private PreferenceScreen mScreen;
@Mock
private FragmentManager mFragmentManager;
+ @Mock
+ private NotificationSettings.DependentFieldListener mListener;
private BubblePreferenceController mController;
private BubblePreferenceController mAppPageController;
@@ -93,9 +95,9 @@
mContext = RuntimeEnvironment.application;
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
mController = spy(new BubblePreferenceController(mContext, mFragmentManager, mBackend,
- false /* isAppPage */));
+ false /* isAppPage */, mListener));
mAppPageController = spy(new BubblePreferenceController(mContext, mFragmentManager,
- mBackend, true /* isAppPage */));
+ mBackend, true /* isAppPage */, mListener));
}
@Test
@@ -106,7 +108,7 @@
}
@Test
- public void testIsAvailable_notIfAppBlocked() {
+ public void isAvailable_notIfAppBlocked() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
@@ -115,7 +117,7 @@
}
@Test
- public void testIsAvailable_notIfChannelBlocked() {
+ public void isAvailable_notIfChannelBlocked() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
@@ -125,7 +127,7 @@
}
@Test
- public void testIsAvailable_channel_yesIfAppOff() {
+ public void isAvailable_channel_yesIfAppOff() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.bubblePreference = BUBBLE_PREFERENCE_NONE;
@@ -137,7 +139,7 @@
}
@Test
- public void testIsNotAvailable_ifOffGlobally_app() {
+ public void isNotAvailable_ifOffGlobally_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mController.onResume(appRow, null, null, null, null, null);
Settings.Global.putInt(mContext.getContentResolver(),
@@ -147,7 +149,7 @@
}
@Test
- public void testIsAvailable_notIfOffGlobally_channel() {
+ public void isAvailable_notIfOffGlobally_channel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
@@ -159,7 +161,7 @@
}
@Test
- public void testIsAvailable_app_evenIfOffGlobally() {
+ public void isAvailable_app_evenIfOffGlobally() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mAppPageController.onResume(appRow, null, null, null, null, null);
Settings.Global.putInt(mContext.getContentResolver(),
@@ -169,7 +171,7 @@
}
@Test
- public void testIsAvailable_app() {
+ public void isAvailable_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mController.onResume(appRow, null, null, null, null, null);
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
@@ -178,7 +180,7 @@
}
@Test
- public void testIsAvailable_defaultChannel() {
+ public void isAvailable_defaultChannel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
NotificationChannel channel = mock(NotificationChannel.class);
@@ -191,7 +193,7 @@
}
@Test
- public void testIsAvailable_channel() {
+ public void isAvailable_channel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
NotificationChannel channel = mock(NotificationChannel.class);
@@ -203,7 +205,7 @@
}
@Test
- public void testUpdateState_disabledByAdmin() {
+ public void updateState_disabledByAdmin() {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(new NotificationBackend.AppRow(), channel, null,
@@ -216,7 +218,7 @@
}
@Test
- public void testUpdateState_app_disabledByAdmin() {
+ public void updateState_app_disabledByAdmin() {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mAppPageController.onResume(new NotificationBackend.AppRow(), channel, null,
@@ -229,7 +231,7 @@
}
@Test
- public void testUpdateState_channel_channelNotBlockable() {
+ public void updateState_channel_channelNotBlockable() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
@@ -243,7 +245,7 @@
}
@Test
- public void testUpdateState_channel() {
+ public void updateState_channel() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
@@ -263,7 +265,7 @@
}
@Test
- public void testUpdateState_app() {
+ public void updateState_app() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.label = "App!";
@@ -288,7 +290,7 @@
}
@Test
- public void testUpdateState_app_offGlobally() {
+ public void updateState_app_offGlobally() {
Settings.Global.putInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
@@ -302,7 +304,7 @@
}
@Test
- public void testOnPreferenceChange_on_channel() {
+ public void onPreferenceChange_on_channel() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
@@ -321,7 +323,7 @@
}
@Test
- public void testOnPreferenceChange_off_channel() {
+ public void onPreferenceChange_off_channel() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
@@ -341,7 +343,7 @@
@Test
- public void testOnPreferenceChange_app_all() {
+ public void onPreferenceChange_app_all() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.bubblePreference = BUBBLE_PREFERENCE_NONE;
@@ -379,7 +381,7 @@
}
@Test
- public void testOnPreferenceChange_app_selected() {
+ public void onPreferenceChange_app_selected() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
@@ -397,7 +399,7 @@
}
@Test
- public void testOnPreferenceChange_app_none() {
+ public void onPreferenceChange_app_none() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
@@ -413,4 +415,17 @@
assertEquals(BUBBLE_PREFERENCE_NONE, appRow.bubblePreference);
verify(mBackend, times(1)).setAllowBubbles(any(), anyInt(), eq(BUBBLE_PREFERENCE_NONE));
}
+
+ @Test
+ public void onPreferenceChange_dependentFieldListenerCalled() {
+ Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
+ mAppPageController.onResume(appRow, null, null, null, null, null);
+
+ BubblePreference pref = new BubblePreference(mContext);
+ mAppPageController.onPreferenceChange(pref, BUBBLE_PREFERENCE_NONE);
+
+ verify(mListener, times(1)).onFieldValueChanged();
+ }
}