Implement the disambig dialog for favorite contacts.

Bug: 36841782,77760800
Test: DisambigDialogTest
PiperOrigin-RevId: 192354880
Change-Id: Ie7e9f0e3994d871ce6c90e4028131204ccb0a32a
diff --git a/java/com/android/dialer/speeddial/DisambigDialog.java b/java/com/android/dialer/speeddial/DisambigDialog.java
index 1ee26f5..2a82002 100644
--- a/java/com/android/dialer/speeddial/DisambigDialog.java
+++ b/java/com/android/dialer/speeddial/DisambigDialog.java
@@ -17,59 +17,47 @@
 package com.android.dialer.speeddial;
 
 import android.app.Dialog;
-import android.content.ContentResolver;
-import android.content.res.Resources;
-import android.database.Cursor;
 import android.os.Bundle;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
 import android.support.v4.app.DialogFragment;
 import android.support.v4.app.FragmentManager;
 import android.support.v7.app.AlertDialog;
-import android.text.TextUtils;
 import android.util.ArraySet;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 import com.android.dialer.callintent.CallInitiationType;
 import com.android.dialer.callintent.CallIntentBuilder;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.common.concurrent.DialerExecutor.Worker;
-import com.android.dialer.duo.DuoComponent;
 import com.android.dialer.precall.PreCall;
-import java.util.ArrayList;
-import java.util.Arrays;
+import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
+import java.util.List;
 import java.util.Set;
 
 /** Disambiguation dialog for favorite contacts in {@link SpeedDialFragment}. */
 public class DisambigDialog extends DialogFragment {
 
-  @VisibleForTesting public static final String DISAMBIG_DIALOG_TAG = "disambig_dialog";
-
-  @SuppressWarnings("unused")
-  private static final String DISAMBIG_DIALOG_WORKER_TAG = "disambig_dialog_worker";
-
   private final Set<String> phoneNumbers = new ArraySet<>();
-  private LinearLayout container;
 
-  @SuppressWarnings("unused")
-  private String lookupKey;
+  @VisibleForTesting public List<Channel> channels;
+  @VisibleForTesting public LinearLayout container;
 
   /** Show a disambiguation dialog for a starred contact without a favorite communication avenue. */
-  public static DisambigDialog show(String lookupKey, FragmentManager manager) {
+  public static DisambigDialog show(List<Channel> channels, FragmentManager manager) {
     DisambigDialog dialog = new DisambigDialog();
-    dialog.lookupKey = lookupKey;
-    dialog.show(manager, DISAMBIG_DIALOG_TAG);
+    dialog.channels = channels;
+    dialog.show(manager, null);
     return dialog;
   }
 
   @Override
   public Dialog onCreateDialog(Bundle savedInstanceState) {
     LayoutInflater inflater = getActivity().getLayoutInflater();
+    // TODO(calderwoodra): set max height of the scrollview. Might need to override onMeasure.
     View view = inflater.inflate(R.layout.disambig_dialog_layout, null, false);
     container = view.findViewById(R.id.communication_avenue_container);
+    insertOptions(container.findViewById(R.id.communication_avenue_container), channels);
     return new AlertDialog.Builder(getActivity()).setView(view).create();
   }
 
@@ -90,135 +78,68 @@
    *   <li>Clickable voice option
    * </ul>
    */
-  @SuppressWarnings("unused")
-  private void insertOptions(Cursor cursor) {
-    if (!cursorIsValid(cursor)) {
-      dismiss();
-      return;
-    }
-
-    do {
-      String number = cursor.getString(LookupContactInfoWorker.NUMBER_INDEX);
-      // TODO(calderwoodra): improve this to include fuzzy matching
-      if (phoneNumbers.add(number)) {
-        insertOption(
-            number,
-            getLabel(getContext().getResources(), cursor),
-            isVideoReachable(cursor, number));
+  private void insertOptions(LinearLayout container, List<Channel> channels) {
+    for (Channel channel : channels) {
+      // TODO(calderwoodra): use fuzzy number matcher
+      if (phoneNumbers.add(channel.number())) {
+        insertHeader(container, channel.number(), channel.label());
       }
-    } while (cursor.moveToNext());
-    cursor.close();
-    // TODO(calderwoodra): set max height of the scrollview. Might need to override onMeasure.
+      insertOption(container, channel);
+    }
   }
 
-  /** Returns true if the given number is ViLTE reachable or Duo reachable. */
-  private boolean isVideoReachable(Cursor cursor, String number) {
-    boolean isVideoReachable = cursor.getInt(LookupContactInfoWorker.PHONE_PRESENCE_INDEX) == 1;
-    if (!isVideoReachable) {
-      isVideoReachable = DuoComponent.get(getContext()).getDuo().isReachable(getContext(), number);
-    }
-    return isVideoReachable;
+  private void insertHeader(LinearLayout container, String number, String phoneType) {
+    View view =
+        getActivity()
+            .getLayoutInflater()
+            .inflate(R.layout.disambig_option_header_layout, container, false);
+    ((TextView) view.findViewById(R.id.disambig_header_phone_type)).setText(phoneType);
+    ((TextView) view.findViewById(R.id.disambig_header_phone_number)).setText(number);
+    container.addView(view);
   }
 
   /** Inserts a group of options for a specific phone number. */
-  private void insertOption(String number, String phoneType, boolean isVideoReachable) {
+  private void insertOption(LinearLayout container, Channel channel) {
     View view =
         getActivity()
             .getLayoutInflater()
             .inflate(R.layout.disambig_option_layout, container, false);
-    ((TextView) view.findViewById(R.id.phone_type)).setText(phoneType);
-    ((TextView) view.findViewById(R.id.phone_number)).setText(number);
-
-    if (isVideoReachable) {
-      View videoOption = view.findViewById(R.id.video_call_container);
-      videoOption.setOnClickListener(v -> onVideoOptionClicked(number));
-      videoOption.setVisibility(View.VISIBLE);
+    if (channel.isVideoTechnology()) {
+      View videoOption = view.findViewById(R.id.option_container);
+      videoOption.setOnClickListener(v -> onVideoOptionClicked(channel));
+      videoOption.setContentDescription(
+          getActivity().getString(R.string.disambig_option_video_call));
+      ((ImageView) view.findViewById(R.id.disambig_option_image))
+          .setImageResource(R.drawable.quantum_ic_videocam_vd_theme_24);
+      ((TextView) view.findViewById(R.id.disambig_option_text))
+          .setText(R.string.disambig_option_video_call);
+    } else {
+      View voiceOption = view.findViewById(R.id.option_container);
+      voiceOption.setOnClickListener(v -> onVoiceOptionClicked(channel));
+      voiceOption.setContentDescription(
+          getActivity().getString(R.string.disambig_option_voice_call));
+      ((ImageView) view.findViewById(R.id.disambig_option_image))
+          .setImageResource(R.drawable.quantum_ic_phone_vd_theme_24);
+      ((TextView) view.findViewById(R.id.disambig_option_text))
+          .setText(R.string.disambig_option_voice_call);
     }
-    View voiceOption = view.findViewById(R.id.voice_call_container);
-    voiceOption.setOnClickListener(v -> onVoiceOptionClicked(number));
     container.addView(view);
   }
 
-  private void onVideoOptionClicked(String number) {
+  private void onVideoOptionClicked(Channel channel) {
     // TODO(calderwoodra): save this option if remember is checked
     // TODO(calderwoodra): place a duo call if possible
     PreCall.start(
         getContext(),
-        new CallIntentBuilder(number, CallInitiationType.Type.SPEED_DIAL).setIsVideoCall(true));
+        new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL)
+            .setIsVideoCall(true));
+    dismiss();
   }
 
-  private void onVoiceOptionClicked(String number) {
+  private void onVoiceOptionClicked(Channel channel) {
     // TODO(calderwoodra): save this option if remember is checked
-    PreCall.start(getContext(), new CallIntentBuilder(number, CallInitiationType.Type.SPEED_DIAL));
-  }
-
-  // TODO(calderwoodra): handle CNAP and cequint types.
-  // TODO(calderwoodra): unify this into a utility method with CallLogAdapter#getNumberType
-  private static String getLabel(Resources resources, Cursor cursor) {
-    int numberType = cursor.getInt(LookupContactInfoWorker.PHONE_TYPE_INDEX);
-    String numberLabel = cursor.getString(LookupContactInfoWorker.PHONE_LABEL_INDEX);
-
-    // Returns empty label instead of "custom" if the custom label is empty.
-    if (numberType == Phone.TYPE_CUSTOM && TextUtils.isEmpty(numberLabel)) {
-      return "";
-    }
-    return (String) Phone.getTypeLabel(resources, numberType, numberLabel);
-  }
-
-  // Checks if the cursor is valid and logs an error if there are any issues.
-  private static boolean cursorIsValid(Cursor cursor) {
-    if (cursor == null) {
-      LogUtil.e("DisambigDialog.insertOptions", "cursor null.");
-      return false;
-    } else if (cursor.isClosed()) {
-      LogUtil.e("DisambigDialog.insertOptions", "cursor closed.");
-      cursor.close();
-      return false;
-    } else if (!cursor.moveToFirst()) {
-      LogUtil.e("DisambigDialog.insertOptions", "cursor empty.");
-      cursor.close();
-      return false;
-    }
-    return true;
-  }
-
-  private static class LookupContactInfoWorker implements Worker<String, Cursor> {
-
-    static final int NUMBER_INDEX = 0;
-    static final int PHONE_TYPE_INDEX = 1;
-    static final int PHONE_LABEL_INDEX = 2;
-    static final int PHONE_PRESENCE_INDEX = 3;
-
-    private static final String[] projection =
-        new String[] {Phone.NUMBER, Phone.TYPE, Phone.LABEL, Phone.CARRIER_PRESENCE};
-    private final ContentResolver resolver;
-
-    LookupContactInfoWorker(ContentResolver resolver) {
-      this.resolver = resolver;
-    }
-
-    @Nullable
-    @Override
-    public Cursor doInBackground(@Nullable String lookupKey) throws Throwable {
-      if (TextUtils.isEmpty(lookupKey)) {
-        LogUtil.e("LookupConctactInfoWorker.doInBackground", "contact id unsest.");
-        return null;
-      }
-      return resolver.query(
-          Phone.CONTENT_URI, projection, Phone.LOOKUP_KEY + " = ?", new String[] {lookupKey}, null);
-    }
-  }
-
-  @VisibleForTesting
-  public static String[] getProjectionForTesting() {
-    ArrayList<String> projection =
-        new ArrayList<>(Arrays.asList(LookupContactInfoWorker.projection));
-    projection.add(Phone.LOOKUP_KEY);
-    return projection.toArray(new String[projection.size()]);
-  }
-
-  @VisibleForTesting
-  public LinearLayout getContainer() {
-    return container;
+    PreCall.start(
+        getContext(), new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL));
+    dismiss();
   }
 }
diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java
index d1f195b..3cf6cb9 100644
--- a/java/com/android/dialer/speeddial/SpeedDialFragment.java
+++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java
@@ -120,7 +120,7 @@
 
     @Override
     public void onAmbiguousContactClicked(List<Channel> channels) {
-      // TODO(calderwoodra): implement the disambig dialog with channels
+      DisambigDialog.show(channels, getChildFragmentManager());
     }
 
     @Override
diff --git a/java/com/android/dialer/speeddial/res/layout/disambig_option_header_layout.xml b/java/com/android/dialer/speeddial/res/layout/disambig_option_header_layout.xml
new file mode 100644
index 0000000..d331a0a
--- /dev/null
+++ b/java/com/android/dialer/speeddial/res/layout/disambig_option_header_layout.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2017 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~      http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/disambig_header_container"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginBottom="8dp"
+    android:minHeight="56dp"
+    android:gravity="center_vertical"
+    android:paddingStart="24dp"
+    android:paddingEnd="24dp">
+
+  <TextView
+      android:id="@+id/disambig_header_phone_type"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      style="@style/PrimaryText"/>
+
+  <TextView
+      android:id="@+id/disambig_header_phone_number"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      style="@style/SecondaryText"/>
+</LinearLayout>
diff --git a/java/com/android/dialer/speeddial/res/layout/disambig_option_layout.xml b/java/com/android/dialer/speeddial/res/layout/disambig_option_layout.xml
index 097ac40..62f6ab5 100644
--- a/java/com/android/dialer/speeddial/res/layout/disambig_option_layout.xml
+++ b/java/com/android/dialer/speeddial/res/layout/disambig_option_layout.xml
@@ -15,89 +15,27 @@
  ~ limitations under the License
  -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/disambig_option_container"
-    android:orientation="vertical"
+    android:id="@+id/option_container"
+    android:orientation="horizontal"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:paddingStart="24dp"
+    android:paddingEnd="24dp"
     android:minHeight="56dp"
-    android:layout_marginBottom="8dp">
+    android:background="?android:attr/selectableItemBackground">
 
-  <LinearLayout
-      android:orientation="vertical"
-      android:layout_width="match_parent"
+  <ImageView
+      android:id="@+id/disambig_option_image"
+      android:layout_width="24dp"
+      android:layout_height="24dp"
+      android:layout_gravity="center_vertical"
+      android:tint="@color/dialer_secondary_text_color"/>
+
+  <TextView
+      android:id="@+id/disambig_option_text"
+      android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      android:minHeight="56dp"
-      android:gravity="center_vertical"
-      android:paddingStart="24dp"
-      android:paddingEnd="24dp">
-
-    <TextView
-        android:id="@+id/phone_type"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        style="@style/PrimaryText"/>
-
-    <TextView
-        android:id="@+id/phone_number"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        style="@style/SecondaryText"/>
-  </LinearLayout>
-
-  <LinearLayout
-      android:id="@+id/video_call_container"
-      android:orientation="horizontal"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:paddingStart="24dp"
-      android:paddingEnd="24dp"
-      android:minHeight="56dp"
-      android:background="?android:attr/selectableItemBackground"
-      android:visibility="gone"
-      android:contentDescription="@string/disambig_option_video_call">
-
-    <ImageView
-        android:layout_width="24dp"
-        android:layout_height="24dp"
-        android:layout_gravity="center_vertical"
-        android:tint="@color/dialer_secondary_text_color"
-        android:src="@drawable/quantum_ic_videocam_vd_theme_24"/>
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="12dp"
-        android:layout_gravity="center_vertical"
-        android:text="@string/disambig_option_video_call"
-        style="@style/PrimaryText"/>
-  </LinearLayout>
-
-  <LinearLayout
-      android:id="@+id/voice_call_container"
-      android:orientation="horizontal"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:paddingStart="24dp"
-      android:paddingEnd="24dp"
-      android:minHeight="56dp"
-      android:background="?android:attr/selectableItemBackground"
-      android:contentDescription="@string/disambig_option_voice_call">
-
-    <ImageView
-        android:id="@+id/disambig_option_icon"
-        android:layout_width="24dp"
-        android:layout_height="24dp"
-        android:layout_gravity="center_vertical"
-        android:tint="@color/dialer_secondary_text_color"
-        android:src="@drawable/quantum_ic_phone_vd_theme_24"/>
-
-    <TextView
-        android:id="@+id/disambig_option_text"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="12dp"
-        android:layout_gravity="center_vertical"
-        android:text="@string/disambig_option_voice_call"
-        style="@style/PrimaryText"/>
-  </LinearLayout>
+      android:layout_marginStart="12dp"
+      android:layout_gravity="center_vertical"
+      style="@style/PrimaryText"/>
 </LinearLayout>
\ No newline at end of file
diff --git a/java/com/android/dialer/speeddial/res/layout/favorite_item_layout.xml b/java/com/android/dialer/speeddial/res/layout/favorite_item_layout.xml
index b4af686..d4fa07d 100644
--- a/java/com/android/dialer/speeddial/res/layout/favorite_item_layout.xml
+++ b/java/com/android/dialer/speeddial/res/layout/favorite_item_layout.xml
@@ -32,8 +32,7 @@
     <com.android.dialer.speeddial.SquareImageView
         android:id="@+id/avatar"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:clickable="false"/>
+        android:layout_height="match_parent"/>
 
     <FrameLayout
         android:id="@+id/video_call_container"
@@ -59,6 +58,8 @@
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal"
+      android:layout_marginStart="4dp"
+      android:layout_marginEnd="4dp"
       style="@style/PrimaryText"/>
 
   <TextView
@@ -66,5 +67,7 @@
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal"
+      android:layout_marginStart="4dp"
+      android:layout_marginEnd="4dp"
       style="@style/SecondaryText"/>
 </LinearLayout>
\ No newline at end of file
diff --git a/java/com/android/dialer/speeddial/res/layout/fragment_speed_dial.xml b/java/com/android/dialer/speeddial/res/layout/fragment_speed_dial.xml
index 9f2dec9..67ef877 100644
--- a/java/com/android/dialer/speeddial/res/layout/fragment_speed_dial.xml
+++ b/java/com/android/dialer/speeddial/res/layout/fragment_speed_dial.xml
@@ -19,8 +19,6 @@
     android:id="@+id/speed_dial_recycler_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:paddingStart="16dp"
-    android:paddingEnd="16dp"
     android:clipToPadding="false"
     android:background="@color/background_dialer_light"
     android:paddingBottom="@dimen/floating_action_button_list_bottom_padding"/>
diff --git a/java/com/android/dialer/speeddial/res/layout/speed_dial_header_layout.xml b/java/com/android/dialer/speeddial/res/layout/speed_dial_header_layout.xml
index 0a84b41..15c00e4 100644
--- a/java/com/android/dialer/speeddial/res/layout/speed_dial_header_layout.xml
+++ b/java/com/android/dialer/speeddial/res/layout/speed_dial_header_layout.xml
@@ -17,6 +17,8 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:layout_marginStart="16dp"
+    android:layout_marginEnd="16dp"
     android:minHeight="@dimen/dialer_list_item_min_height">
 
   <TextView
diff --git a/java/com/android/dialer/speeddial/res/layout/suggestion_row_layout.xml b/java/com/android/dialer/speeddial/res/layout/suggestion_row_layout.xml
index 4281700..ff95b59 100644
--- a/java/com/android/dialer/speeddial/res/layout/suggestion_row_layout.xml
+++ b/java/com/android/dialer/speeddial/res/layout/suggestion_row_layout.xml
@@ -18,22 +18,24 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="72dp">
+    android:minHeight="72dp"
+    android:background="?android:attr/selectableItemBackground">
 
   <QuickContactBadge
       android:id="@+id/avatar"
       android:layout_width="48dp"
       android:layout_height="48dp"
-      android:layout_centerVertical="true"/>
+      android:layout_centerVertical="true"
+      android:layout_marginStart="16dp"/>
 
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
-      android:layout_marginStart="56dp"
       android:layout_centerVertical="true"
-      android:layout_alignParentStart="true"
-      android:layout_toStartOf="@+id/overflow">
+      android:layout_toEndOf="@+id/avatar"
+      android:layout_toStartOf="@+id/overflow"
+      android:layout_marginStart="8dp">
 
     <TextView
         android:id="@+id/name"