Add condition to ignore invalid packages in NotificationChannelSlice

If all displayable notification channels of package are turned off,
stop showing notification channel slice of package.

Bug: 124480122
Test: robotests
Change-Id: I3ce9ebc4cca18dac3b4b6f15c28c697b72df81e3
This commit is contained in:
Yanting Yang
2019-03-25 23:25:44 +08:00
parent 7bac003389
commit b1d846cbbd
2 changed files with 74 additions and 34 deletions

View File

@@ -176,15 +176,10 @@ public class NotificationChannelSlice implements CustomSliceable {
.setSubtitle(getSubTitle(mPackageName, mUid)) .setSubtitle(getSubTitle(mPackageName, mUid))
.setPrimaryAction(getPrimarySliceAction(icon, title, getIntent()))); .setPrimaryAction(getPrimarySliceAction(icon, title, getIntent())));
// Get rows by notification channel. // Add notification channel rows.
final List<ListBuilder.RowBuilder> rows = getNotificationChannelRows(packageInfo, icon); final List<ListBuilder.RowBuilder> rows = getNotificationChannelRows(packageInfo, icon);
for (ListBuilder.RowBuilder rowBuilder : rows) {
// Get displayable notification channel count. listBuilder.addRow(rowBuilder);
final int channelCount = Math.min(rows.size(), DEFAULT_EXPANDED_ROW_COUNT);
// According to the displayable channel count to add rows.
for (int i = 0; i < channelCount; i++) {
listBuilder.addRow(rows.get(i));
} }
return listBuilder.build(); return listBuilder.build();
@@ -279,10 +274,9 @@ public class NotificationChannelSlice implements CustomSliceable {
private List<ListBuilder.RowBuilder> getNotificationChannelRows(PackageInfo packageInfo, private List<ListBuilder.RowBuilder> getNotificationChannelRows(PackageInfo packageInfo,
IconCompat icon) { IconCompat icon) {
final List<ListBuilder.RowBuilder> notificationChannelRows = new ArrayList<>(); final List<ListBuilder.RowBuilder> notificationChannelRows = new ArrayList<>();
final List<NotificationChannel> enabledChannels = getEnabledChannels(mPackageName, mUid, final List<NotificationChannel> displayableChannels = getDisplayableChannels(mAppRow);
mAppRow);
for (NotificationChannel channel : enabledChannels) { for (NotificationChannel channel : displayableChannels) {
notificationChannelRows.add(new ListBuilder.RowBuilder() notificationChannelRows.add(new ListBuilder.RowBuilder()
.setTitle(channel.getName()) .setTitle(channel.getName())
.setSubtitle(NotificationBackend.getSentSummary( .setSubtitle(NotificationBackend.getSentSummary(
@@ -356,10 +350,9 @@ public class NotificationChannelSlice implements CustomSliceable {
title); title);
} }
private List<NotificationChannel> getEnabledChannels(String packageName, int uid, private List<NotificationChannel> getDisplayableChannels(NotificationBackend.AppRow appRow) {
NotificationBackend.AppRow appRow) {
final List<NotificationChannelGroup> channelGroupList = final List<NotificationChannelGroup> channelGroupList =
mNotificationBackend.getGroups(packageName, uid).getList(); mNotificationBackend.getGroups(appRow.pkg, appRow.uid).getList();
final List<NotificationChannel> channels = channelGroupList.stream() final List<NotificationChannel> channels = channelGroupList.stream()
.flatMap(group -> group.getChannels().stream().filter( .flatMap(group -> group.getChannels().stream().filter(
channel -> isChannelEnabled(group, channel, appRow))) channel -> isChannelEnabled(group, channel, appRow)))
@@ -376,8 +369,11 @@ public class NotificationChannelSlice implements CustomSliceable {
} }
// Sort the notification channels with notification sent count by descending. // Sort the notification channels with notification sent count by descending.
return channelStates.stream().sorted(CHANNEL_STATE_COMPARATOR).map( return channelStates.stream()
state -> state.getNotificationChannel()).collect(Collectors.toList()); .sorted(CHANNEL_STATE_COMPARATOR)
.map(state -> state.getNotificationChannel())
.limit(DEFAULT_EXPANDED_ROW_COUNT)
.collect(Collectors.toList());
} }
private PackageInfo getMaxSentNotificationsPackage(List<PackageInfo> packageInfoList) { private PackageInfo getMaxSentNotificationsPackage(List<PackageInfo> packageInfoList) {
@@ -391,10 +387,14 @@ public class NotificationChannelSlice implements CustomSliceable {
for (PackageInfo packageInfo : packageInfoList) { for (PackageInfo packageInfo : packageInfoList) {
final NotificationBackend.AppRow appRow = mNotificationBackend.loadAppRow(mContext, final NotificationBackend.AppRow appRow = mNotificationBackend.loadAppRow(mContext,
mContext.getPackageManager(), packageInfo); mContext.getPackageManager(), packageInfo);
// Ignore packages which are banned notifications or block all displayable channels.
if (appRow.banned || isAllChannelsBlocked(getDisplayableChannels(appRow))) {
continue;
}
// Get sent notification count from app. // Get sent notification count from app.
final int sentCount = appRow.sentByApp.sentCount; final int sentCount = appRow.sentByApp.sentCount;
if (!appRow.banned && sentCount >= MIN_NOTIFICATION_SENT_COUNT if (sentCount >= MIN_NOTIFICATION_SENT_COUNT && sentCount > maxSentCount) {
&& sentCount > maxSentCount) {
maxSentCount = sentCount; maxSentCount = sentCount;
maxSentCountPackage = packageInfo; maxSentCountPackage = packageInfo;
mAppRow = appRow; mAppRow = appRow;
@@ -404,6 +404,15 @@ public class NotificationChannelSlice implements CustomSliceable {
return maxSentCountPackage; return maxSentCountPackage;
} }
private boolean isAllChannelsBlocked(List<NotificationChannel> channels) {
for (NotificationChannel channel : channels) {
if (channel.getImportance() != IMPORTANCE_NONE) {
return false;
}
}
return true;
}
protected CharSequence getSubTitle(String packageName, int uid) { protected CharSequence getSubTitle(String packageName, int uid) {
final int channelCount = mNotificationBackend.getChannelCount(packageName, uid); final int channelCount = mNotificationBackend.getChannelCount(packageName, uid);

View File

@@ -16,6 +16,7 @@
package com.android.settings.homepage.contextualcards.slices; package com.android.settings.homepage.contextualcards.slices;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.slice.Slice.HINT_LIST_ITEM; import static android.app.slice.Slice.HINT_LIST_ITEM;
import static android.app.slice.SliceItem.FORMAT_SLICE; import static android.app.slice.SliceItem.FORMAT_SLICE;
@@ -116,7 +117,8 @@ public class NotificationChannelSliceTest {
public void getSlice_hasSuggestedApp_shouldHaveNotificationChannelTitle() { public void getSlice_hasSuggestedApp_shouldHaveNotificationChannelTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED); ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */); mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -130,7 +132,8 @@ public class NotificationChannelSliceTest {
public void getSlice_hasSuggestedApp_shouldSortByNotificationSentCount() { public void getSlice_hasSuggestedApp_shouldSortByNotificationSentCount() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED); ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */); mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -157,7 +160,8 @@ public class NotificationChannelSliceTest {
public void getSlice_noRecentlyInstalledApp_shouldHaveNoSuggestedAppTitle() { public void getSlice_noRecentlyInstalledApp_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(false /* isRecentlyInstalled */, addMockPackageToPackageManager(false /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED); ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */); mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -169,7 +173,8 @@ public class NotificationChannelSliceTest {
public void getSlice_noMultiChannelApp_shouldHaveNoSuggestedAppTitle() { public void getSlice_noMultiChannelApp_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED); ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(1 /* channelCount */, NOTIFICATION_COUNT, false /* banned */); mockNotificationBackend(1 /* channelCount */, NOTIFICATION_COUNT, false /* banned */,
false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -178,10 +183,12 @@ public class NotificationChannelSliceTest {
} }
@Test @Test
@Config(shadows = ShadowRestrictedLockUtilsInternal.class)
public void getSlice_insufficientNotificationSentCount_shouldHaveNoSuggestedAppTitle() { public void getSlice_insufficientNotificationSentCount_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED); ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(CHANNEL_COUNT, 1 /* notificationCount */, false /* banned */); mockNotificationBackend(CHANNEL_COUNT, 1 /* notificationCount */, false /* banned */,
false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -192,7 +199,8 @@ public class NotificationChannelSliceTest {
@Test @Test
public void getSlice_isSystemApp_shouldHaveNoSuggestedAppTitle() { public void getSlice_isSystemApp_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_SYSTEM); addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_SYSTEM);
mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */); mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -204,7 +212,8 @@ public class NotificationChannelSliceTest {
public void getSlice_isNotificationBanned_shouldHaveNoSuggestedAppTitle() { public void getSlice_isNotificationBanned_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED); ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, true /* banned */); mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, true /* banned */,
false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -218,7 +227,7 @@ public class NotificationChannelSliceTest {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED); ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(NotificationChannelSlice.DEFAULT_EXPANDED_ROW_COUNT * 2, mockNotificationBackend(NotificationChannelSlice.DEFAULT_EXPANDED_ROW_COUNT * 2,
NOTIFICATION_COUNT, false /* banned */); NOTIFICATION_COUNT, false /* banned */, false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -234,7 +243,8 @@ public class NotificationChannelSliceTest {
public void getSlice_channelCountIsLessThanDefaultRows_subTitleShouldNotHaveTapToManagerAll() { public void getSlice_channelCountIsLessThanDefaultRows_subTitleShouldNotHaveTapToManagerAll() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED); ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(CHANNEL_COUNT - 1, NOTIFICATION_COUNT, false /* banned */); mockNotificationBackend(CHANNEL_COUNT - 1, NOTIFICATION_COUNT, false /* banned */,
false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -249,7 +259,8 @@ public class NotificationChannelSliceTest {
public void getSlice_channelCountIsEqualToDefaultRows_subTitleShouldNotHaveTapToManagerAll() { public void getSlice_channelCountIsEqualToDefaultRows_subTitleShouldNotHaveTapToManagerAll() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED); ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */); mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -263,7 +274,8 @@ public class NotificationChannelSliceTest {
public void getSlice_channelCountIsMoreThanDefaultRows_subTitleShouldHaveTapToManagerAll() { public void getSlice_channelCountIsMoreThanDefaultRows_subTitleShouldHaveTapToManagerAll() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED); ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(CHANNEL_COUNT + 1, NOTIFICATION_COUNT, false /* banned */); mockNotificationBackend(CHANNEL_COUNT + 1, NOTIFICATION_COUNT, false /* banned */,
false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice(); final Slice slice = mNotificationChannelSlice.getSlice();
@@ -273,6 +285,20 @@ public class NotificationChannelSliceTest {
CHANNEL_COUNT + 1)); CHANNEL_COUNT + 1));
} }
@Test
@Config(shadows = ShadowRestrictedLockUtilsInternal.class)
public void getSlice_isAllDisplayableChannelBlocked_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
true /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.no_suggested_app));
}
private void addMockPackageToPackageManager(boolean isRecentlyInstalled, int flags) { private void addMockPackageToPackageManager(boolean isRecentlyInstalled, int flags) {
final ApplicationInfo applicationInfo = new ApplicationInfo(); final ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.name = APP_LABEL; applicationInfo.name = APP_LABEL;
@@ -294,8 +320,10 @@ public class NotificationChannelSliceTest {
return System.currentTimeMillis(); return System.currentTimeMillis();
} }
private void mockNotificationBackend(int channelCount, int notificationCount, boolean banned) { private void mockNotificationBackend(int channelCount, int notificationCount, boolean banned,
final List<NotificationChannel> channels = buildNotificationChannel(channelCount); boolean isChannelBlocked) {
final List<NotificationChannel> channels = buildNotificationChannel(channelCount,
isChannelBlocked);
final AppRow appRow = buildAppRow(channelCount, notificationCount, banned); final AppRow appRow = buildAppRow(channelCount, notificationCount, banned);
doReturn(buildNotificationChannelGroups(channels)).when(mNotificationBackend).getGroups( doReturn(buildNotificationChannelGroups(channels)).when(mNotificationBackend).getGroups(
@@ -308,6 +336,8 @@ public class NotificationChannelSliceTest {
private AppRow buildAppRow(int channelCount, int sentCount, boolean banned) { private AppRow buildAppRow(int channelCount, int sentCount, boolean banned) {
final AppRow appRow = new AppRow(); final AppRow appRow = new AppRow();
appRow.pkg = PACKAGE_NAME;
appRow.uid = UID;
appRow.banned = banned; appRow.banned = banned;
appRow.channelCount = channelCount; appRow.channelCount = channelCount;
appRow.sentByApp = new NotificationsSentState(); appRow.sentByApp = new NotificationsSentState();
@@ -317,11 +347,12 @@ public class NotificationChannelSliceTest {
return appRow; return appRow;
} }
private List<NotificationChannel> buildNotificationChannel(int channelCount) { private List<NotificationChannel> buildNotificationChannel(int channelCount,
boolean isChannelBlock) {
final List<NotificationChannel> channels = new ArrayList<>(); final List<NotificationChannel> channels = new ArrayList<>();
for (int i = 0; i < channelCount; i++) { for (int i = 0; i < channelCount; i++) {
channels.add(new NotificationChannel(CHANNEL_NAME_PREFIX + i, CHANNEL_NAME_PREFIX + i, channels.add(new NotificationChannel(CHANNEL_NAME_PREFIX + i, CHANNEL_NAME_PREFIX + i,
IMPORTANCE_NONE)); isChannelBlock ? IMPORTANCE_NONE : IMPORTANCE_LOW));
} }
return channels; return channels;