Merge changes I7d2748cf,I70496c00,Ia455a18d

* changes:
  Combine voicemail uri and duration for NUI media player
  Set total duration for NUI voicemail media player seekbar
  Added URI for selecting distinct phone numbers from AnnotatedCallLog.
diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java b/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java
index 68298e3..825e84f 100644
--- a/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java
+++ b/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java
@@ -38,6 +38,7 @@
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
 import java.util.ArrayList;
+import java.util.Arrays;
 
 /** {@link ContentProvider} for the annotated call log. */
 public class AnnotatedCallLogContentProvider extends ContentProvider {
@@ -51,7 +52,8 @@
 
   private static final int ANNOTATED_CALL_LOG_TABLE_CODE = 1;
   private static final int ANNOTATED_CALL_LOG_TABLE_ID_CODE = 2;
-  private static final int COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE = 3;
+  private static final int ANNOTATED_CALL_LOG_TABLE_DISTINCT_NUMBER_CODE = 3;
+  private static final int COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE = 4;
 
   private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 
@@ -64,6 +66,10 @@
         ANNOTATED_CALL_LOG_TABLE_ID_CODE);
     uriMatcher.addURI(
         AnnotatedCallLogContract.AUTHORITY,
+        AnnotatedCallLog.DISTINCT_PHONE_NUMBERS,
+        ANNOTATED_CALL_LOG_TABLE_DISTINCT_NUMBER_CODE);
+    uriMatcher.addURI(
+        AnnotatedCallLogContract.AUTHORITY,
         CoalescedAnnotatedCallLog.TABLE,
         COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE);
   }
@@ -101,8 +107,6 @@
     switch (match) {
       case ANNOTATED_CALL_LOG_TABLE_ID_CODE:
         queryBuilder.appendWhere(AnnotatedCallLog._ID + "=" + ContentUris.parseId(uri));
-        // fall through
-      case ANNOTATED_CALL_LOG_TABLE_CODE:
         Cursor cursor =
             queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
         if (cursor != null) {
@@ -112,6 +116,31 @@
           LogUtil.w("AnnotatedCallLogContentProvider.query", "cursor was null");
         }
         return cursor;
+      case ANNOTATED_CALL_LOG_TABLE_CODE:
+        cursor =
+            queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
+        if (cursor != null) {
+          cursor.setNotificationUri(
+              getContext().getContentResolver(), AnnotatedCallLog.CONTENT_URI);
+        } else {
+          LogUtil.w("AnnotatedCallLogContentProvider.query", "cursor was null");
+        }
+        return cursor;
+      case ANNOTATED_CALL_LOG_TABLE_DISTINCT_NUMBER_CODE:
+        Assert.checkArgument(
+            Arrays.equals(projection, new String[] {AnnotatedCallLog.NUMBER}),
+            "only NUMBER supported for projection for distinct phone number query, got: %s",
+            Arrays.toString(projection));
+        queryBuilder.setDistinct(true);
+        cursor =
+            queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
+        if (cursor != null) {
+          cursor.setNotificationUri(
+              getContext().getContentResolver(), AnnotatedCallLog.CONTENT_URI);
+        } else {
+          LogUtil.w("AnnotatedCallLogContentProvider.query", "cursor was null");
+        }
+        return cursor;
       case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE:
         Assert.checkArgument(
             projection == CoalescedAnnotatedCallLog.ALL_COLUMNS,
@@ -170,6 +199,8 @@
           values.put(AnnotatedCallLog._ID, idFromUri);
         }
         break;
+      case ANNOTATED_CALL_LOG_TABLE_DISTINCT_NUMBER_CODE:
+        throw new UnsupportedOperationException();
       case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE:
         throw new UnsupportedOperationException("coalesced call log does not support inserting");
       default:
@@ -206,6 +237,8 @@
         Assert.checkArgument(id != -1, "error parsing id from uri %s", uri);
         selection = getSelectionWithId(id);
         break;
+      case ANNOTATED_CALL_LOG_TABLE_DISTINCT_NUMBER_CODE:
+        throw new UnsupportedOperationException();
       case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE:
         throw new UnsupportedOperationException("coalesced call log does not support deleting");
       default:
@@ -244,8 +277,10 @@
             selectionArgs == null, "Do not specify selection args when updating by ID");
         selection = getSelectionWithId(ContentUris.parseId(uri));
         break;
+      case ANNOTATED_CALL_LOG_TABLE_DISTINCT_NUMBER_CODE:
+        throw new UnsupportedOperationException();
       case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE:
-        throw new UnsupportedOperationException("coalesced call log does not support updating");
+        throw new UnsupportedOperationException();
       default:
         throw new IllegalArgumentException("Unknown uri: " + uri);
     }
@@ -287,6 +322,8 @@
           case ANNOTATED_CALL_LOG_TABLE_ID_CODE:
             // These are allowed values, continue.
             break;
+          case ANNOTATED_CALL_LOG_TABLE_DISTINCT_NUMBER_CODE:
+            throw new UnsupportedOperationException();
           case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE:
             throw new UnsupportedOperationException(
                 "coalesced call log does not support applyBatch");
diff --git a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
index 4f26f0c..c9b463e 100644
--- a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
+++ b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
@@ -211,18 +211,23 @@
   public static final class AnnotatedCallLog implements CommonColumns {
 
     public static final String TABLE = "AnnotatedCallLog";
+    public static final String DISTINCT_PHONE_NUMBERS = "DistinctPhoneNumbers";
 
     /** The content URI for this table. */
     public static final Uri CONTENT_URI =
         Uri.withAppendedPath(AnnotatedCallLogContract.CONTENT_URI, TABLE);
 
+    /** Content URI for selecting the distinct phone numbers from the AnnotatedCallLog. */
+    public static final Uri DISTINCT_NUMBERS_CONTENT_URI =
+        Uri.withAppendedPath(AnnotatedCallLogContract.CONTENT_URI, DISTINCT_PHONE_NUMBERS);
+
     /** The MIME type of a {@link android.content.ContentProvider#getType(Uri)} single entry. */
     public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/annotated_call_log";
 
     /**
      * See {@link android.provider.CallLog.Calls#DURATION}.
      *
-     * <p>TYPE: INTEGER (int)
+     * <p>TYPE: INTEGER (long)
      */
     public static final String DURATION = "duration";
 
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayerView.java b/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayerView.java
index 1e56a81..4629ce2 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayerView.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayerView.java
@@ -32,11 +32,13 @@
 import android.view.View;
 import android.widget.Button;
 import android.widget.LinearLayout;
+import android.widget.TextView;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.common.concurrent.DialerExecutor.SuccessListener;
 import com.android.dialer.common.concurrent.DialerExecutor.Worker;
 import com.android.dialer.common.concurrent.DialerExecutorComponent;
+import com.android.dialer.voicemail.model.VoicemailEntry;
 
 /**
  * The view of the media player that is visible when a {@link NewVoicemailViewHolder} is expanded.
@@ -46,6 +48,7 @@
   private Button playButton;
   private Button speakerButton;
   private Button deleteButton;
+  private TextView totalDurationView;
   private Uri voicemailUri;
   private FragmentManager fragmentManager;
   private MediaPlayer mediaPlayer;
@@ -62,14 +65,15 @@
   protected void onFinishInflate() {
     super.onFinishInflate();
     LogUtil.enterBlock("NewVoicemailMediaPlayer.onFinishInflate");
-    initializeMediaPlayerButtons();
+    initializeMediaPlayerButtonsAndViews();
     setupListenersForMediaPlayerButtons();
   }
 
-  private void initializeMediaPlayerButtons() {
+  private void initializeMediaPlayerButtonsAndViews() {
     playButton = findViewById(R.id.playButton);
     speakerButton = findViewById(R.id.speakerButton);
     deleteButton = findViewById(R.id.deleteButton);
+    totalDurationView = findViewById(R.id.playback_seek_total_duration);
   }
 
   private void setupListenersForMediaPlayerButtons() {
@@ -171,7 +175,7 @@
         }
       };
 
-  @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+  @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
   OnCompletionListener onCompletionListener =
       new OnCompletionListener() {
 
@@ -197,7 +201,7 @@
         }
       };
 
-  @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+  @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
   OnErrorListener onErrorListener =
       new OnErrorListener() {
         @Override
@@ -210,12 +214,18 @@
         }
       };
 
-  public void setVoicemailUri(Uri voicemailUri) {
-    Assert.isNotNull(voicemailUri);
-    this.voicemailUri = voicemailUri;
+  void setFragmentManager(FragmentManager fragmentManager) {
+    this.fragmentManager = fragmentManager;
   }
 
-  public void setFragmentManager(FragmentManager fragmentManager) {
-    this.fragmentManager = fragmentManager;
+  void setVoicemailEntryValues(VoicemailEntry voicemailEntry) {
+    Assert.isNotNull(voicemailEntry);
+    Uri uri = Uri.parse(voicemailEntry.voicemailUri());
+    Assert.isNotNull(uri);
+    Assert.isNotNull(totalDurationView);
+
+    voicemailUri = uri;
+    totalDurationView.setText(
+        VoicemailEntryText.getVoicemailDuration(getContext(), voicemailEntry));
   }
 }
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
index 078a029..f8de01f 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
@@ -79,7 +79,7 @@
 
     itemView.setOnClickListener(this);
     setPhoto(voicemailEntry);
-    mediaPlayerView.setVoicemailUri(Uri.parse(voicemailEntry.voicemailUri()));
+    mediaPlayerView.setVoicemailEntryValues(voicemailEntry);
     mediaPlayerView.setFragmentManager(fragmentManager);
   }
 
diff --git a/java/com/android/dialer/voicemail/listui/VoicemailEntryText.java b/java/com/android/dialer/voicemail/listui/VoicemailEntryText.java
index f592201..d73d1f0 100644
--- a/java/com/android/dialer/voicemail/listui/VoicemailEntryText.java
+++ b/java/com/android/dialer/voicemail/listui/VoicemailEntryText.java
@@ -91,7 +91,7 @@
     return secondaryText.toString();
   }
 
-  private static String getVoicemailDuration(Context context, VoicemailEntry voicemailEntry) {
+  static String getVoicemailDuration(Context context, VoicemailEntry voicemailEntry) {
     long minutes = TimeUnit.SECONDS.toMinutes(voicemailEntry.duration());
     long seconds = voicemailEntry.duration() - TimeUnit.MINUTES.toSeconds(minutes);
 
diff --git a/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_media_player_layout.xml b/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_media_player_layout.xml
index a21b6aa..e8e5600 100644
--- a/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_media_player_layout.xml
+++ b/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_media_player_layout.xml
@@ -55,13 +55,11 @@
         android:max="0"
         android:progress="0"/>
 
-    <!-- TODO(uabdullah): Remove android:text and replace with real value when binding -->
     <TextView
         android:id="@+id/playback_seek_total_duration"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:importantForAccessibility="no"
-        android:text="03:00"
         android:textSize="@dimen/voicemail_duration_size"/>
   </LinearLayout>