Home | History | Annotate | Download | only in notification
      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