1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.dialer.notification; 18 19 import android.app.Notification; 20 import android.app.NotificationManager; 21 import android.content.Context; 22 import android.service.notification.StatusBarNotification; 23 import android.support.annotation.NonNull; 24 import android.support.annotation.Nullable; 25 import android.support.v4.os.BuildCompat; 26 import android.text.TextUtils; 27 import android.util.Pair; 28 import com.android.dialer.common.Assert; 29 import com.android.dialer.common.LogUtil; 30 31 /** 32 * Wrapper around the notification manager APIs. The wrapper ensures that channels are set and that 33 * notifications are limited to 10 per group. 34 */ 35 public final class DialerNotificationManager { 36 public static void notify(@NonNull Context context, int id, @NonNull Notification notification) { 37 Assert.isNotNull(context); 38 Assert.isNotNull(notification); 39 throw Assert.createUnsupportedOperationFailException("all notifications must have tags"); 40 } 41 42 public static void notify( 43 @NonNull Context context, @NonNull String tag, int id, @NonNull Notification notification) { 44 Assert.isNotNull(context); 45 Assert.isNotNull(notification); 46 Assert.checkArgument(!TextUtils.isEmpty(tag)); 47 48 if (BuildCompat.isAtLeastO()) { 49 Assert.checkArgument(!TextUtils.isEmpty(notification.getChannelId())); 50 } 51 52 getNotificationManager(context).notify(tag, id, notification); 53 NotificationThrottler.throttle(context, notification); 54 } 55 56 public static void cancel(@NonNull Context context, int id) { 57 Assert.isNotNull(context); 58 throw Assert.createUnsupportedOperationFailException( 59 "notification IDs are not unique across the app, a tag must be specified"); 60 } 61 62 public static void cancel(@NonNull Context context, @NonNull String tag, int id) { 63 Assert.isNotNull(context); 64 Assert.checkArgument(!TextUtils.isEmpty(tag)); 65 66 NotificationManager notificationManager = getNotificationManager(context); 67 StatusBarNotification[] notifications = notificationManager.getActiveNotifications(); 68 69 String groupKey = findGroupKey(notifications, tag, id); 70 if (!TextUtils.isEmpty(groupKey)) { 71 Pair<StatusBarNotification, Integer> groupSummaryAndCount = 72 getGroupSummaryAndCount(notifications, groupKey); 73 if (groupSummaryAndCount.first != null && groupSummaryAndCount.second <= 1) { 74 LogUtil.i( 75 "DialerNotificationManager.cancel", 76 "last notification in group (%s) removed, also removing group summary", 77 groupKey); 78 notificationManager.cancel( 79 groupSummaryAndCount.first.getTag(), groupSummaryAndCount.first.getId()); 80 } 81 } 82 83 notificationManager.cancel(tag, id); 84 } 85 86 public static StatusBarNotification[] getActiveNotifications(@NonNull Context context) { 87 Assert.isNotNull(context); 88 return getNotificationManager(context).getActiveNotifications(); 89 } 90 91 @Nullable 92 private static String findGroupKey( 93 @NonNull StatusBarNotification[] notifications, @NonNull String tag, int id) { 94 for (StatusBarNotification notification : notifications) { 95 if (TextUtils.equals(tag, notification.getTag()) && id == notification.getId()) { 96 return notification.getNotification().getGroup(); 97 } 98 } 99 return null; 100 } 101 102 @NonNull 103 private static Pair<StatusBarNotification, Integer> getGroupSummaryAndCount( 104 @NonNull StatusBarNotification[] notifications, @NonNull String groupKey) { 105 StatusBarNotification groupSummaryNotification = null; 106 int groupCount = 0; 107 for (StatusBarNotification notification : notifications) { 108 if (TextUtils.equals(groupKey, notification.getNotification().getGroup())) { 109 if ((notification.getNotification().flags & Notification.FLAG_GROUP_SUMMARY) != 0) { 110 groupSummaryNotification = notification; 111 } else { 112 groupCount++; 113 } 114 } 115 } 116 return new Pair<>(groupSummaryNotification, groupCount); 117 } 118 119 @NonNull 120 private static NotificationManager getNotificationManager(@NonNull Context context) { 121 return context.getSystemService(NotificationManager.class); 122 } 123 124 private DialerNotificationManager() {} 125 } 126