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
This commit is contained in:
Mady Mellor
2020-04-17 11:24:50 -07:00
parent dcc79e9942
commit a27918494f
10 changed files with 472 additions and 35 deletions

View File

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

View File

@@ -80,6 +80,8 @@ public class BubblePreferenceControllerTest {
private PreferenceScreen mScreen;
@Mock
private FragmentManager mFragmentManager;
@Mock
private NotificationSettings.DependentFieldListener mListener;
private BubblePreferenceController mController;
private BubblePreferenceController mAppPageController;
@@ -93,9 +95,9 @@ public class BubblePreferenceControllerTest {
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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
}
@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 @@ public class BubblePreferenceControllerTest {
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();
}
}