mobile/android/base/NotificationHandler.java

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 package org.mozilla.gecko;
     8 import org.mozilla.gecko.gfx.BitmapUtils;
    10 import android.app.Notification;
    11 import android.app.NotificationManager;
    12 import android.app.PendingIntent;
    13 import android.content.Context;
    14 import android.net.Uri;
    15 import android.util.Log;
    17 import java.util.concurrent.ConcurrentHashMap;
    19 public class NotificationHandler {
    20     private final ConcurrentHashMap<Integer, Notification>
    21             mNotifications = new ConcurrentHashMap<Integer, Notification>();
    22     private final Context mContext;
    23     private final NotificationManager mNotificationManager;
    25     /**
    26      * Notification associated with this service's foreground state.
    27      *
    28      * {@link android.app.Service#startForeground(int, android.app.Notification)}
    29      * associates the foreground with exactly one notification from the service.
    30      * To keep Fennec alive during downloads (and to make sure it can be killed
    31      * once downloads are complete), we make sure that the foreground is always
    32      * associated with an active progress notification if and only if at least
    33      * one download is in progress.
    34      */
    35     private Notification mForegroundNotification;
    36     private int mForegroundNotificationId;
    38     public NotificationHandler(Context context) {
    39         mContext = context;
    40         mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    41     }
    43     /**
    44      * Adds a notification.
    45      *
    46      * @param notificationID the unique ID of the notification
    47      * @param aImageUrl      URL of the image to use
    48      * @param aAlertTitle    title of the notification
    49      * @param aAlertText     text of the notification
    50      * @param contentIntent  Intent used when the notification is clicked
    51      * @param clearIntent    Intent used when the notification is removed
    52      */
    53     public void add(int notificationID, String aImageUrl, String aAlertTitle,
    54                     String aAlertText, PendingIntent contentIntent) {
    55         // Remove the old notification with the same ID, if any
    56         remove(notificationID);
    58         Uri imageUri = Uri.parse(aImageUrl);
    59         int icon = BitmapUtils.getResource(imageUri, R.drawable.ic_status_logo);
    60         final AlertNotification notification = new AlertNotification(mContext, notificationID,
    61                 icon, aAlertTitle, aAlertText, System.currentTimeMillis(), imageUri);
    63         notification.setLatestEventInfo(mContext, aAlertTitle, aAlertText, contentIntent);
    65         mNotificationManager.notify(notificationID, notification);
    66         mNotifications.put(notificationID, notification);
    67     }
    69     /**
    70      * Adds a notification.
    71      *
    72      * @param id             the unique ID of the notification
    73      * @param aNotification  the Notification to add
    74      */
    75     public void add(int id, Notification notification) {
    76         mNotificationManager.notify(id, notification);
    77         mNotifications.put(id, notification);
    79         if (mForegroundNotification == null && isOngoing(notification)) {
    80             setForegroundNotification(id, notification);
    81         }
    82     }
    84     /**
    85      * Updates a notification.
    86      *
    87      * @param notificationID ID of existing notification
    88      * @param aProgress      progress of item being updated
    89      * @param aProgressMax   max progress of item being updated
    90      * @param aAlertText     text of the notification
    91      */
    92     public void update(int notificationID, long aProgress, long aProgressMax, String aAlertText) {
    93         final Notification notification = mNotifications.get(notificationID);
    94         if (notification == null) {
    95             return;
    96         }
    98         if (notification instanceof AlertNotification) {
    99             AlertNotification alert = (AlertNotification)notification;
   100             alert.updateProgress(aAlertText, aProgress, aProgressMax);
   101         }
   103         if (mForegroundNotification == null && isOngoing(notification)) {
   104             setForegroundNotification(notificationID, notification);
   105         }
   106     }
   108     /**
   109      * Removes a notification.
   110      *
   111      * @param notificationID ID of existing notification
   112      */
   113     public void remove(int notificationID) {
   114         final Notification notification = mNotifications.remove(notificationID);
   115         if (notification != null) {
   116             updateForegroundNotification(notificationID, notification);
   117         }
   118         mNotificationManager.cancel(notificationID);
   119     }
   121     /**
   122      * Determines whether the service is done.
   123      *
   124      * The service is considered finished when all notifications have been
   125      * removed.
   126      *
   127      * @return whether all notifications have been removed
   128      */
   129     public boolean isDone() {
   130         return mNotifications.isEmpty();
   131     }
   133     /**
   134      * Determines whether a notification should hold a foreground service to keep Gecko alive
   135      *
   136      * @param notificationID the id of the notification to check
   137      * @return               whether the notification is ongoing
   138      */
   139     public boolean isOngoing(int notificationID) {
   140         final Notification notification = mNotifications.get(notificationID);
   141         return isOngoing(notification);
   142     }
   144     /**
   145      * Determines whether a notification should hold a foreground service to keep Gecko alive
   146      *
   147      * @param notification   the notification to check
   148      * @return               whether the notification is ongoing
   149      */
   150     public boolean isOngoing(Notification notification) {
   151         if (notification != null && (isProgressStyle(notification) || ((notification.flags & Notification.FLAG_ONGOING_EVENT) > 0))) {
   152             return true;
   153         }
   154         return false;
   155     }
   157     /**
   158      * Helper method to determines whether a notification is an AlertNotification that is showing progress
   159      * This method will be deprecated when AlertNotifications are removed (bug 893289). 
   160      *
   161      * @param notification   the notification to check
   162      * @return               whether the notification is an AlertNotification showing progress.
   163      */
   164     private boolean isProgressStyle(Notification notification) {
   165         if (notification != null && notification instanceof AlertNotification) {
   166             return ((AlertNotification)notification).isProgressStyle();
   167         }
   168         return false;
   169     }
   171     protected void setForegroundNotification(int id, Notification notification) {
   172         mForegroundNotificationId = id;
   173         mForegroundNotification = notification;
   174     }
   176     private void updateForegroundNotification(int oldId, Notification oldNotification) {
   177         if (mForegroundNotificationId == oldId) {
   178             // If we're removing the notification associated with the
   179             // foreground, we need to pick another active notification to act
   180             // as the foreground notification.
   181             Notification foregroundNotification = null;
   182             int foregroundId = 0;
   183             for (final Integer id : mNotifications.keySet()) {
   184                 final Notification notification = mNotifications.get(id);
   185                 if (isOngoing(notification)) {
   186                     foregroundNotification = notification;
   187                     foregroundId = id;
   188                     break;
   189                 }
   190             }
   191             setForegroundNotification(foregroundId, foregroundNotification);
   192         }
   193     }
   194 }

mercurial