Update Dialer to V10 RC16

This release was created following the instructions at:
go/dialer-aosp-release

Subsequent dialer releases will follow as O bugs are
fixed, until we reach our final RC.

Version: 10
Candidate: RC16
Branch: dialer-android_release_branch/153304843.1
dialer-android/dialer-android_20170416.00/dialer-android_20170416.00_RC16

This release contains the following bug fixes since RC00:
Bug: 37324705 35304403 36067503 35304446 33203808 37280992
37346084 35766990 37481880 37424493 36470282 37347691
37519015 37168472 35805360 37545472 27704934 36515614
35766990 37577470 34739750 35801628 36788693 35264204
36708536 37628370 36904650 37314436 37642171 37530847
37637799 37666625 37548549 37648036 37636412 37323529
37630507 35919141 37198343 37548572 36178218 37640315
37663896 37720467 37275944 37710497 31634477 37744796
37348506 37744796 37568534 37672424 34872683 34873026
37681461 34873295 37748373 37526812 37618638 37663896
37536088 37727455 37165687 36651204 36900708 37323529
36902926 37256480 37328353 37432034 37436952 34093562
37720889 37321935 37780300 37781115 37755902 36588206
34258266 37290464 37698062 37618638 37473004 37432034
37918676 37870494 37722091

Test: make, on device
Change-Id: I99e1a484ccd578c1f8a13e7a6a4b4952f0791297
diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java
index a6a81c6..4fb402c 100644
--- a/java/com/android/incallui/StatusBarNotifier.java
+++ b/java/com/android/incallui/StatusBarNotifier.java
@@ -97,9 +97,12 @@
   // 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 = R.id.notification_ongoing_call;
+  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 = R.id.notification_incoming_call;
+  private static final int NOTIFICATION_INCOMING_CALL = 2;
+  // Notification for incoming calls in the case where there is already an active call.
+  // This is non-interruptive, but otherwise behaves the same as NOTIFICATION_INCOMING_CALL
+  private static final int NOTIFICATION_INCOMING_CALL_QUIET = 3;
 
   private static final int PENDING_INTENT_REQUEST_CODE_NON_FULL_SCREEN = 0;
   private static final int PENDING_INTENT_REQUEST_CODE_FULL_SCREEN = 1;
@@ -144,8 +147,7 @@
 
     NotificationManager notificationManager =
         backupContext.getSystemService(NotificationManager.class);
-    notificationManager.cancel(NOTIFICATION_IN_CALL);
-    notificationManager.cancel(NOTIFICATION_INCOMING_CALL);
+    notificationManager.cancel(R.id.notification_ongoing_call);
   }
 
   private static int getWorkStringFromPersonalString(int resId) {
@@ -224,7 +226,7 @@
     }
     if (mCurrentNotification != NOTIFICATION_NONE) {
       LogUtil.i("StatusBarNotifier.cancelNotification", "cancel");
-      mNotificationManager.cancel(mCurrentNotification);
+      mNotificationManager.cancel(R.id.notification_ongoing_call);
     }
     mCurrentNotification = NOTIFICATION_NONE;
   }
@@ -311,7 +313,11 @@
     if (callState == DialerCall.State.INCOMING
         || callState == DialerCall.State.CALL_WAITING
         || isVideoUpgradeRequest) {
-      notificationType = NOTIFICATION_INCOMING_CALL;
+      boolean alreadyActive =
+          callList.getActiveOrBackgroundCall() != null
+              && InCallPresenter.getInstance().isShowingInCallUi();
+      notificationType =
+          alreadyActive ? NOTIFICATION_INCOMING_CALL_QUIET : NOTIFICATION_INCOMING_CALL;
     } else {
       notificationType = NOTIFICATION_IN_CALL;
     }
@@ -340,7 +346,6 @@
         .setColor(mContext.getResources().getColor(R.color.dialer_theme_color, mContext.getTheme()))
         // Hide work call state for the lock screen notification
         .setContentTitle(getContentString(call, ContactsUtils.USER_TYPE_CURRENT));
-    setColorized(publicBuilder);
     setNotificationWhen(call, callState, publicBuilder);
 
     // Builder for the notification shown when the device is unlocked or the user has set their
@@ -356,17 +361,37 @@
     if (accountHandle == null) {
       accountHandle = getAnyPhoneAccount();
     }
-    if (notificationType == NOTIFICATION_INCOMING_CALL) {
-      NotificationChannelManager.applyChannel(
-          builder, mContext, Channel.INCOMING_CALL, accountHandle);
-      configureFullScreenIntent(
-          builder, createLaunchPendingIntent(true /* isFullScreen */), callList, call);
-      // Set the notification category and bump the priority for incoming calls
-      builder.setCategory(Notification.CATEGORY_CALL);
-      builder.setPriority(Notification.PRIORITY_MAX);
-    } else {
-      NotificationChannelManager.applyChannel(
-          builder, mContext, Channel.ONGOING_CALL, accountHandle);
+
+    LogUtil.i("StatusBarNotifier.buildAndSendNotification", "notificationType=" + notificationType);
+    switch (notificationType) {
+      case NOTIFICATION_INCOMING_CALL:
+        NotificationChannelManager.applyChannel(
+            builder, mContext, Channel.INCOMING_CALL, accountHandle);
+        configureFullScreenIntent(builder, createLaunchPendingIntent(true /* isFullScreen */));
+        // Set the notification category and bump the priority for incoming calls
+        builder.setCategory(Notification.CATEGORY_CALL);
+        // This will be ignored on O+ and handled by the channel
+        //noinspection deprecation
+        builder.setPriority(Notification.PRIORITY_MAX);
+        if (mCurrentNotification != NOTIFICATION_INCOMING_CALL) {
+          LogUtil.i(
+              "StatusBarNotifier.buildAndSendNotification",
+              "Canceling old notification so this one can be noisy");
+          // Moving from a non-interuptive notification (or none) to a noisy one. Cancel the old
+          // notification (if there is one) so the fullScreenIntent or HUN will show
+          mNotificationManager.cancel(R.id.notification_ongoing_call);
+        }
+        break;
+      case NOTIFICATION_INCOMING_CALL_QUIET:
+        NotificationChannelManager.applyChannel(
+            builder, mContext, Channel.ONGOING_CALL, accountHandle);
+        break;
+      case NOTIFICATION_IN_CALL:
+        setColorized(publicBuilder);
+        setColorized(builder);
+        NotificationChannelManager.applyChannel(
+            builder, mContext, Channel.ONGOING_CALL, accountHandle);
+        break;
     }
 
     // Set the content
@@ -376,7 +401,6 @@
     builder.setLargeIcon(largeIcon);
     builder.setColor(
         mContext.getResources().getColor(R.color.dialer_theme_color, mContext.getTheme()));
-    setColorized(builder);
 
     if (isVideoUpgradeRequest) {
       builder.setUsesChronometer(false);
@@ -406,19 +430,13 @@
       LogUtil.v("StatusBarNotifier.buildAndSendNotification", "playing call waiting tone");
       mDialerRingtoneManager.playCallWaitingTone();
     }
-    if (mCurrentNotification != notificationType && mCurrentNotification != NOTIFICATION_NONE) {
-      LogUtil.i(
-          "StatusBarNotifier.buildAndSendNotification",
-          "previous notification already showing - cancelling " + mCurrentNotification);
-      mNotificationManager.cancel(mCurrentNotification);
-    }
 
     LogUtil.i(
         "StatusBarNotifier.buildAndSendNotification",
         "displaying notification for " + notificationType);
 
     try {
-      mNotificationManager.notify(notificationType, notification);
+      mNotificationManager.notify(R.id.notification_ongoing_call, notification);
     } catch (RuntimeException e) {
       // TODO(b/34744003): Move the memory stats into silent feedback PSD.
       ActivityManager activityManager = mContext.getSystemService(ActivityManager.class);
@@ -681,7 +699,11 @@
       EnrichedCallManager manager = EnrichedCallComponent.get(mContext).getEnrichedCallManager();
       Session session = null;
       if (call.getNumber() != null) {
-        session = manager.getSession(call.getUniqueCallId(), call.getNumber());
+        session =
+            manager.getSession(
+                call.getUniqueCallId(),
+                call.getNumber(),
+                manager.createIncomingCallComposerFilter());
       }
 
       if (call.isSpam()) {
@@ -844,8 +866,7 @@
     builder.addAction(
         new Notification.Action.Builder(
                 Icon.createWithResource(mContext, R.drawable.ic_call_end_white_24dp),
-                getActionText(
-                    R.string.notification_action_end_call, R.color.notification_action_end_call),
+                mContext.getText(R.string.notification_action_end_call),
                 hangupPendingIntent)
             .build());
   }
@@ -897,8 +918,7 @@
   }
 
   /** Adds fullscreen intent to the builder. */
-  private void configureFullScreenIntent(
-      Notification.Builder builder, PendingIntent intent, CallList callList, DialerCall call) {
+  private void configureFullScreenIntent(Notification.Builder builder, PendingIntent intent) {
     // Ok, we actually want to launch the incoming call
     // UI at this point (in addition to simply posting a notification
     // to the status bar).  Setting fullScreenIntent will cause
@@ -906,51 +926,15 @@
     // current foreground activity is marked as "immersive".
     LogUtil.d("StatusBarNotifier.configureFullScreenIntent", "setting fullScreenIntent: " + intent);
     builder.setFullScreenIntent(intent, true);
-
-    // Ugly hack alert:
-    //
-    // The NotificationManager has the (undocumented) behavior
-    // that it will *ignore* the fullScreenIntent field if you
-    // post a new Notification that matches the ID of one that's
-    // already active.  Unfortunately this is exactly what happens
-    // when you get an incoming call-waiting call:  the
-    // "ongoing call" notification is already visible, so the
-    // InCallScreen won't get launched in this case!
-    // (The result: if you bail out of the in-call UI while on a
-    // call and then get a call-waiting call, the incoming call UI
-    // won't come up automatically.)
-    //
-    // The workaround is to just notice this exact case (this is a
-    // call-waiting call *and* the InCallScreen is not in the
-    // foreground) and manually cancel the in-call notification
-    // before (re)posting it.
-    //
-    // TODO: there should be a cleaner way of avoiding this
-    // problem (see discussion in bug 3184149.)
-
-    // If a call is onhold during an incoming call, the call actually comes in as
-    // INCOMING.  For that case *and* traditional call-waiting, we want to
-    // cancel the notification.
-    boolean isCallWaiting =
-        (call.getState() == DialerCall.State.CALL_WAITING
-            || (call.getState() == DialerCall.State.INCOMING
-                && callList.getBackgroundCall() != null));
-
-    if (isCallWaiting) {
-      LogUtil.i(
-          "StatusBarNotifier.configureFullScreenIntent",
-          "updateInCallNotification: call-waiting! force relaunch...");
-      // Cancel the IN_CALL_NOTIFICATION immediately before
-      // (re)posting it; this seems to force the
-      // NotificationManager to launch the fullScreenIntent.
-      mNotificationManager.cancel(NOTIFICATION_IN_CALL);
-    }
   }
 
   private Notification.Builder getNotificationBuilder() {
     final Notification.Builder builder = new Notification.Builder(mContext);
     builder.setOngoing(true);
     builder.setOnlyAlertOnce(true);
+    // This will be ignored on O+ and handled by the channel
+    //noinspection deprecation
+    builder.setPriority(Notification.PRIORITY_HIGH);
 
     return builder;
   }