am 7d0a8e5e: am 5e80e79d: Send a new notification for non-HUN notifications

* commit '7d0a8e5ec2054287ce3790f0618be514a34b13da':
  Send a new notification for non-HUN notifications
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index 458f950..4fd9b96 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -647,7 +647,7 @@
             if (mStatusBarNotifier == null) {
                 // The In Call UI has crashed but the notification still stayed up. We should not
                 // come to this stage.
-                StatusBarNotifier.clearInCallNotification(context);
+                StatusBarNotifier.clearAllCallNotifications(context);
             }
             return;
         }
@@ -671,7 +671,7 @@
         // By the time we receive this intent, we could be shut down and call list
         // could be null.  Bail in those cases.
         if (mCallList == null) {
-            StatusBarNotifier.clearInCallNotification(context);
+            StatusBarNotifier.clearAllCallNotifications(context);
             return;
         }
 
@@ -689,7 +689,7 @@
         // By the time we receive this intent, we could be shut down and call list
         // could be null.  Bail in those cases.
         if (mCallList == null) {
-            StatusBarNotifier.clearInCallNotification(context);
+            StatusBarNotifier.clearAllCallNotifications(context);
             return;
         }
 
@@ -703,7 +703,7 @@
         Log.d(this, " acceptUpgradeRequest videoState " + videoState);
         // Bail if we have been shut down and the call list is null.
         if (mCallList == null) {
-            StatusBarNotifier.clearInCallNotification(context);
+            StatusBarNotifier.clearAllCallNotifications(context);
             Log.e(this, " acceptUpgradeRequest mCallList is empty so returning");
             return;
         }
@@ -720,7 +720,7 @@
         Log.d(this, " declineUpgradeRequest");
         // Bail if we have been shut down and the call list is null.
         if (mCallList == null) {
-            StatusBarNotifier.clearInCallNotification(context);
+            StatusBarNotifier.clearAllCallNotifications(context);
             Log.e(this, " declineUpgradeRequest mCallList is empty so returning");
             return;
         }
diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
index 195d5c6..8df4520 100644
--- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java
+++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
@@ -27,8 +27,6 @@
 import android.graphics.BitmapFactory;
 import android.graphics.drawable.BitmapDrawable;
 import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
 import android.telecom.Call.Details;
 import android.telecom.PhoneAccount;
 import android.text.BidiFormatter;
@@ -48,13 +46,18 @@
 public class StatusBarNotifier implements InCallPresenter.InCallStateListener,
         CallList.CallUpdateListener {
 
-    // notification types
-    private static final int IN_CALL_NOTIFICATION = 1;
+    // Notification types
+    // Indicates that no notification is currently showing.
+    private static final int NOTIFICATION_NONE = 0;
+    // Notification for an active call. This is non-interruptive, but cannot be dismissed.
+    private static final int NOTIFICATION_IN_CALL = 1;
+    // Notification for incoming calls. This is interruptive and will show up as a HUN.
+    private static final int NOTIFICATION_INCOMING_CALL = 2;
 
     private final Context mContext;
     private final ContactInfoCache mContactInfoCache;
     private final NotificationManager mNotificationManager;
-    private boolean mIsShowingNotification = false;
+    private int mCurrentNotification = NOTIFICATION_NONE;
     private int mCallState = Call.State.INVALID;
     private int mSavedIcon = 0;
     private int mSavedContent = 0;
@@ -65,11 +68,11 @@
 
     public StatusBarNotifier(Context context, ContactInfoCache contactInfoCache) {
         Preconditions.checkNotNull(context);
-
         mContext = context;
         mContactInfoCache = contactInfoCache;
         mNotificationManager =
                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        mCurrentNotification = NOTIFICATION_NONE;
     }
 
     /**
@@ -111,21 +114,26 @@
      * Take down the in-call notification.
      * @see #updateInCallNotification(InCallState,CallList)
      */
-    private void cancelInCall() {
-        if (mIsShowingNotification) {
+    private void cancelNotification() {
+        if (mCurrentNotification != NOTIFICATION_NONE) {
             Log.d(this, "cancelInCall()...");
-            mNotificationManager.cancel(IN_CALL_NOTIFICATION);
+            mNotificationManager.cancel(mCurrentNotification);
         }
-        mIsShowingNotification = false;
+        mCurrentNotification = NOTIFICATION_NONE;
     }
 
-    /* package */ static void clearInCallNotification(Context backupContext) {
+    /**
+     * Should only be called from a irrecoverable state where it is necessary to dismiss all
+     * notifications.
+     */
+    static void clearAllCallNotifications(Context backupContext) {
         Log.i(StatusBarNotifier.class.getSimpleName(),
                 "Something terrible happened. Clear all InCall notifications");
 
         NotificationManager notificationManager =
                 (NotificationManager) backupContext.getSystemService(Context.NOTIFICATION_SERVICE);
-        notificationManager.cancel(IN_CALL_NOTIFICATION);
+        notificationManager.cancel(NOTIFICATION_IN_CALL);
+        notificationManager.cancel(NOTIFICATION_INCOMING_CALL);
     }
 
     /**
@@ -142,7 +150,7 @@
         if (call != null) {
             showNotification(call);
         } else {
-            cancelInCall();
+            cancelNotification();
         }
     }
 
@@ -201,7 +209,17 @@
         final int contentResId = getContentString(call);
         final String contentTitle = getContentTitle(contactInfo, call);
 
-        if (!checkForChangeAndSaveData(iconResId, contentResId, largeIcon, contentTitle, state)) {
+        final int notificationType;
+        if ((state == Call.State.INCOMING
+                || state == Call.State.CALL_WAITING) &&
+                        !InCallPresenter.getInstance().isShowingInCallUi()) {
+            notificationType = NOTIFICATION_INCOMING_CALL;
+        } else {
+            notificationType = NOTIFICATION_IN_CALL;
+        }
+
+        if (!checkForChangeAndSaveData(iconResId, contentResId, largeIcon, contentTitle, state,
+                notificationType)) {
             return;
         }
 
@@ -219,8 +237,7 @@
         builder.setContentIntent(inCallPendingIntent);
 
         // Set the intent as a full screen intent as well if a call is incoming
-        if ((state == Call.State.INCOMING || state == Call.State.CALL_WAITING) &&
-                !InCallPresenter.getInstance().isShowingInCallUi()) {
+        if (notificationType == NOTIFICATION_INCOMING_CALL) {
             configureFullScreenIntent(builder, inCallPendingIntent, call);
             // Set the notification category for incoming calls
             builder.setCategory(Notification.CATEGORY_CALL);
@@ -249,9 +266,14 @@
          * Fire off the notification
          */
         Notification notification = builder.build();
-        Log.d(this, "Notifying IN_CALL_NOTIFICATION: " + notification);
-        mNotificationManager.notify(IN_CALL_NOTIFICATION, notification);
-        mIsShowingNotification = true;
+        if (mCurrentNotification != notificationType) {
+            Log.i(this, "Previous notification already showing - cancelling "
+                    + mCurrentNotification);
+            mNotificationManager.cancel(mCurrentNotification);
+        }
+        Log.i(this, "Displaying notification for " + notificationType);
+        mNotificationManager.notify(notificationType, notification);
+        mCurrentNotification = notificationType;
     }
 
     private void createIncomingCallNotification(
@@ -285,7 +307,7 @@
      * we do not issue a new notification for the exact same data.
      */
     private boolean checkForChangeAndSaveData(int icon, int content, Bitmap largeIcon,
-            String contentTitle, int state) {
+            String contentTitle, int state, int notificationType) {
 
         // The two are different:
         // if new title is not null, it should be different from saved version OR
@@ -299,9 +321,12 @@
                 (mCallState != state) || (mSavedLargeIcon != largeIcon) ||
                 contentTitleChanged;
 
-        // If we aren't showing a notification right now, definitely start showing one.
-        if (!mIsShowingNotification) {
-            Log.d(this, "Showing notification for first time.");
+        // If we aren't showing a notification right now or the notification type is changing,
+        // definitely do an update.
+        if (mCurrentNotification != notificationType) {
+            if (mCurrentNotification == NOTIFICATION_NONE) {
+                Log.d(this, "Showing notification for first time.");
+            }
             retval = true;
         }
 
@@ -439,7 +464,7 @@
     }
 
     private void addAnswerAction(Notification.Builder builder) {
-        Log.i(this, "Will show \"answer\" action in the incoming call Notification");
+        Log.d(this, "Will show \"answer\" action in the incoming call Notification");
 
         PendingIntent answerVoicePendingIntent = createNotificationPendingIntent(
                 mContext, ACTION_ANSWER_VOICE_INCOMING_CALL);
@@ -449,7 +474,7 @@
     }
 
     private void addDismissAction(Notification.Builder builder) {
-        Log.i(this, "Will show \"dismiss\" action in the incoming call Notification");
+        Log.d(this, "Will show \"dismiss\" action in the incoming call Notification");
 
         PendingIntent declinePendingIntent =
                 createNotificationPendingIntent(mContext, ACTION_DECLINE_INCOMING_CALL);
@@ -459,7 +484,7 @@
     }
 
     private void addHangupAction(Notification.Builder builder) {
-        Log.i(this, "Will show \"hang-up\" action in the ongoing active call Notification");
+        Log.d(this, "Will show \"hang-up\" action in the ongoing active call Notification");
 
         PendingIntent hangupPendingIntent =
                 createNotificationPendingIntent(mContext, ACTION_HANG_UP_ONGOING_CALL);
@@ -479,7 +504,7 @@
     }
 
     private void addVoiceAction(Notification.Builder builder) {
-        Log.i(this, "Will show \"voice\" action in the incoming call Notification");
+        Log.d(this, "Will show \"voice\" action in the incoming call Notification");
 
         PendingIntent answerVoicePendingIntent = createNotificationPendingIntent(
                 mContext, ACTION_ANSWER_VOICE_INCOMING_CALL);
@@ -489,7 +514,7 @@
     }
 
     private void addAcceptUpgradeRequestAction(Notification.Builder builder) {
-        Log.i(this, "Will show \"accept\" action in the incoming call Notification");
+        Log.i(this, "Will show \"accept upgrade\" action in the incoming call Notification");
 
         PendingIntent acceptVideoPendingIntent = createNotificationPendingIntent(
                 mContext, ACTION_ACCEPT_VIDEO_UPGRADE_REQUEST);
@@ -498,7 +523,7 @@
     }
 
     private void addDismissUpgradeRequestAction(Notification.Builder builder) {
-        Log.i(this, "Will show \"dismiss\" action in the incoming call Notification");
+        Log.i(this, "Will show \"dismiss upgrade\" action in the incoming call Notification");
 
         PendingIntent declineVideoPendingIntent = createNotificationPendingIntent(
                 mContext, ACTION_DECLINE_VIDEO_UPGRADE_REQUEST);
@@ -552,7 +577,7 @@
             // Cancel the IN_CALL_NOTIFICATION immediately before
             // (re)posting it; this seems to force the
             // NotificationManager to launch the fullScreenIntent.
-            mNotificationManager.cancel(IN_CALL_NOTIFICATION);
+            mNotificationManager.cancel(NOTIFICATION_IN_CALL);
         }
     }