Added context menu for favorite contacts in new speed dial.

Bug: 36841782,77761023
Test: WIP
PiperOrigin-RevId: 192556602
Change-Id: I50c0baef7ef6c8ae533545567ec797283a9a870f
diff --git a/java/com/android/dialer/speeddial/ContextMenu.java b/java/com/android/dialer/speeddial/ContextMenu.java
new file mode 100644
index 0000000..a7fa655
--- /dev/null
+++ b/java/com/android/dialer/speeddial/ContextMenu.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package com.android.dialer.speeddial;
+
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import com.android.dialer.speeddial.loader.SpeedDialUiItem;
+
+/** Floating menu which presents contact options available to the contact. */
+public class ContextMenu extends LinearLayout {
+
+  private SpeedDialUiItem speedDialUiItem;
+  private ContextMenuItemListener listener;
+
+  public ContextMenu(Context context, @Nullable AttributeSet attrs) {
+    super(context, attrs);
+  }
+
+  @Override
+  protected void onFinishInflate() {
+    super.onFinishInflate();
+    findViewById(R.id.voice_call_container)
+        .setOnClickListener(v -> listener.placeVoiceCall(speedDialUiItem));
+    findViewById(R.id.video_call_container)
+        .setOnClickListener(v -> listener.placeVideoCall(speedDialUiItem));
+    findViewById(R.id.send_message_container)
+        .setOnClickListener(v -> listener.openSmsConversation(speedDialUiItem));
+    findViewById(R.id.remove_container)
+        .setOnClickListener(v -> listener.removeFavoriteContact(speedDialUiItem));
+    findViewById(R.id.contact_info_container)
+        .setOnClickListener(v -> listener.openContactInfo(speedDialUiItem));
+  }
+
+  /** Shows the menu and updates the menu's position w.r.t. the view it's related to. */
+  public void showMenu(
+      View parentLayout,
+      View childLayout,
+      SpeedDialUiItem speedDialUiItem,
+      ContextMenuItemListener listener) {
+    this.speedDialUiItem = speedDialUiItem;
+    this.listener = listener;
+
+    int[] childLocation = new int[2];
+    int[] parentLocation = new int[2];
+    childLayout.getLocationOnScreen(childLocation);
+    parentLayout.getLocationOnScreen(parentLocation);
+
+    setX((float) (childLocation[0] + .5 * childLayout.getWidth() - .5 * getWidth()));
+    setY(childLocation[1] - parentLocation[1] + childLayout.getHeight());
+
+    // TODO(calderwoodra): a11y
+    // TODO(calderwoodra): animate this similar to the bubble menu
+    setVisibility(View.VISIBLE);
+  }
+
+  /** Returns true if the view was hidden. */
+  public void hideMenu() {
+    this.speedDialUiItem = null;
+    this.listener = null;
+    if (getVisibility() == View.VISIBLE) {
+      // TODO(calderwoodra): a11y
+      // TODO(calderwoodra): animate this similar to the bubble menu
+      setVisibility(View.INVISIBLE);
+    }
+  }
+
+  /** Listener to report user clicks on menu items. */
+  public interface ContextMenuItemListener {
+
+    /** Called when the user selects "voice call" option from the context menu. */
+    void placeVoiceCall(SpeedDialUiItem speedDialUiItem);
+
+    /** Called when the user selects "video call" option from the context menu. */
+    void placeVideoCall(SpeedDialUiItem speedDialUiItem);
+
+    /** Called when the user selects "send message" from the context menu. */
+    void openSmsConversation(SpeedDialUiItem speedDialUiItem);
+
+    /** Called when the user selects "remove" from the context menu. */
+    void removeFavoriteContact(SpeedDialUiItem speedDialUiItem);
+
+    /** Called when the user selects "contact info" from the context menu. */
+    void openContactInfo(SpeedDialUiItem speedDialUiItem);
+  }
+}
diff --git a/java/com/android/dialer/speeddial/FavoritesViewHolder.java b/java/com/android/dialer/speeddial/FavoritesViewHolder.java
index 92ffb0a..4f0cf65 100644
--- a/java/com/android/dialer/speeddial/FavoritesViewHolder.java
+++ b/java/com/android/dialer/speeddial/FavoritesViewHolder.java
@@ -30,7 +30,6 @@
 import com.android.dialer.glidephotomanager.PhotoInfo;
 import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
 import com.android.dialer.speeddial.loader.SpeedDialUiItem;
-import java.util.ArrayList;
 import java.util.List;
 
 /** ViewHolder for starred/favorite contacts in {@link SpeedDialFragment}. */
@@ -44,10 +43,7 @@
   private final TextView phoneType;
   private final FrameLayout videoCallIcon;
 
-  private boolean hasDefaultNumber;
-  private boolean isVideoCall;
-  private String number;
-  private List<Channel> channels;
+  private SpeedDialUiItem speedDialUiItem;
 
   public FavoritesViewHolder(View view, FavoriteContactsListener listener) {
     super(view);
@@ -62,20 +58,15 @@
   }
 
   public void bind(Context context, SpeedDialUiItem speedDialUiItem) {
+    this.speedDialUiItem = Assert.isNotNull(speedDialUiItem);
     Assert.checkArgument(speedDialUiItem.isStarred());
 
     nameView.setText(speedDialUiItem.name());
-    hasDefaultNumber = speedDialUiItem.defaultChannel() != null;
-    if (hasDefaultNumber) {
-      channels = new ArrayList<>();
-      isVideoCall = speedDialUiItem.defaultChannel().isVideoTechnology();
-      number = speedDialUiItem.defaultChannel().number();
+    if (speedDialUiItem.defaultChannel() != null) {
       phoneType.setText(speedDialUiItem.defaultChannel().label());
-      videoCallIcon.setVisibility(isVideoCall ? View.VISIBLE : View.GONE);
+      videoCallIcon.setVisibility(
+          speedDialUiItem.defaultChannel().isVideoTechnology() ? View.VISIBLE : View.GONE);
     } else {
-      channels = speedDialUiItem.channels();
-      isVideoCall = false;
-      number = null;
       phoneType.setText("");
       videoCallIcon.setVisibility(View.GONE);
     }
@@ -96,17 +87,18 @@
 
   @Override
   public void onClick(View v) {
-    if (hasDefaultNumber) {
-      listener.onClick(number, isVideoCall);
+    if (speedDialUiItem.defaultChannel() != null) {
+      listener.onClick(speedDialUiItem.defaultChannel());
     } else {
-      listener.onAmbiguousContactClicked(channels);
+      listener.onAmbiguousContactClicked(speedDialUiItem.channels());
     }
   }
 
   @Override
-  public boolean onLongClick(View v) {
+  public boolean onLongClick(View view) {
     // TODO(calderwoodra): implement drag and drop logic
-    listener.onLongClick(number);
+    // TODO(calderwoodra): add bounce/sin wave scale animation
+    listener.onLongClick(photoView, speedDialUiItem);
     return true;
   }
 
@@ -117,9 +109,9 @@
     void onAmbiguousContactClicked(List<Channel> channels);
 
     /** Called when the user clicks on a favorite contact. */
-    void onClick(String number, boolean isVideoCall);
+    void onClick(Channel channel);
 
     /** Called when the user long clicks on a favorite contact. */
-    void onLongClick(String number);
+    void onLongClick(View view, SpeedDialUiItem speedDialUiItem);
   }
 }
diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java
index aca4886..d323b1b 100644
--- a/java/com/android/dialer/speeddial/SpeedDialFragment.java
+++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java
@@ -24,11 +24,14 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
 import com.android.dialer.callintent.CallInitiationType;
 import com.android.dialer.callintent.CallIntentBuilder;
+import com.android.dialer.common.LogUtil;
 import com.android.dialer.common.concurrent.DialerExecutorComponent;
 import com.android.dialer.common.concurrent.SupportUiListener;
 import com.android.dialer.precall.PreCall;
+import com.android.dialer.speeddial.ContextMenu.ContextMenuItemListener;
 import com.android.dialer.speeddial.FavoritesViewHolder.FavoriteContactsListener;
 import com.android.dialer.speeddial.HeaderViewHolder.SpeedDialHeaderListener;
 import com.android.dialer.speeddial.SuggestionViewHolder.SuggestedContactsListener;
@@ -54,7 +57,11 @@
   private final FavoriteContactsListener favoritesListener = new SpeedDialFavoritesListener();
   private final SuggestedContactsListener suggestedListener = new SpeedDialSuggestedListener();
 
+  private View rootLayout;
+  private ContextMenu contextMenu;
+  private FrameLayout contextMenuBackground;
   private SpeedDialAdapter adapter;
+  private ContextMenuItemListener contextMenuItemListener;
   private SupportUiListener<ImmutableList<SpeedDialUiItem>> speedDialLoaderListener;
 
   public static SpeedDialFragment newInstance() {
@@ -65,18 +72,28 @@
   @Override
   public View onCreateView(
       LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-    View view = inflater.inflate(R.layout.fragment_speed_dial, container, false);
-    RecyclerView recyclerView = view.findViewById(R.id.speed_dial_recycler_view);
+    LogUtil.enterBlock("SpeedDialFragment.onCreateView");
+    rootLayout = inflater.inflate(R.layout.fragment_speed_dial, container, false);
+    RecyclerView recyclerView = rootLayout.findViewById(R.id.speed_dial_recycler_view);
 
     adapter =
         new SpeedDialAdapter(getContext(), favoritesListener, suggestedListener, headerListener);
     recyclerView.setLayoutManager(adapter.getLayoutManager(getContext()));
     recyclerView.setAdapter(adapter);
 
+    contextMenu = rootLayout.findViewById(R.id.favorite_contact_context_menu);
+    contextMenuBackground = rootLayout.findViewById(R.id.context_menu_background);
+    contextMenuBackground.setOnClickListener(
+        v -> {
+          contextMenu.hideMenu();
+          contextMenuBackground.setVisibility(View.GONE);
+        });
+    contextMenuItemListener = new SpeedDialContextMenuItemListener();
+
     speedDialLoaderListener =
         DialerExecutorComponent.get(getContext())
             .createUiListener(getChildFragmentManager(), "speed_dial_loader_listener");
-    return view;
+    return rootLayout;
   }
 
   public boolean hasFrequents() {
@@ -107,7 +124,7 @@
     }
   }
 
-  private class SpeedDialFavoritesListener implements FavoriteContactsListener {
+  private final class SpeedDialFavoritesListener implements FavoriteContactsListener {
 
     @Override
     public void onAmbiguousContactClicked(List<Channel> channels) {
@@ -115,21 +132,22 @@
     }
 
     @Override
-    public void onClick(String number, boolean isVideoCall) {
+    public void onClick(Channel channel) {
       // TODO(calderwoodra): add logic for duo video calls
       PreCall.start(
           getContext(),
-          new CallIntentBuilder(number, CallInitiationType.Type.SPEED_DIAL)
-              .setIsVideoCall(isVideoCall));
+          new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL)
+              .setIsVideoCall(channel.isVideoTechnology()));
     }
 
     @Override
-    public void onLongClick(String number) {
-      // TODO(calderwoodra): show favorite contact floating context menu
+    public void onLongClick(View view, SpeedDialUiItem speedDialUiItem) {
+      contextMenuBackground.setVisibility(View.VISIBLE);
+      contextMenu.showMenu(rootLayout, view, speedDialUiItem, contextMenuItemListener);
     }
   }
 
-  private class SpeedDialSuggestedListener implements SuggestedContactsListener {
+  private final class SpeedDialSuggestedListener implements SuggestedContactsListener {
 
     @Override
     public void onOverFlowMenuClicked(String number) {
@@ -142,4 +160,32 @@
           getContext(), new CallIntentBuilder(number, CallInitiationType.Type.SPEED_DIAL));
     }
   }
+
+  private static final class SpeedDialContextMenuItemListener implements ContextMenuItemListener {
+
+    @Override
+    public void placeVoiceCall(SpeedDialUiItem speedDialUiItem) {
+      // TODO(calderwoodra)
+    }
+
+    @Override
+    public void placeVideoCall(SpeedDialUiItem speedDialUiItem) {
+      // TODO(calderwoodra)
+    }
+
+    @Override
+    public void openSmsConversation(SpeedDialUiItem speedDialUiItem) {
+      // TODO(calderwoodra)
+    }
+
+    @Override
+    public void removeFavoriteContact(SpeedDialUiItem speedDialUiItem) {
+      // TODO(calderwoodra)
+    }
+
+    @Override
+    public void openContactInfo(SpeedDialUiItem speedDialUiItem) {
+      // TODO(calderwoodra)
+    }
+  }
 }
diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java
index c23b67d..c80a062 100644
--- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java
+++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java
@@ -135,7 +135,9 @@
     for (SpeedDialUiItem contact : strequentContacts) {
       if (!contact.isStarred()) {
         // Add this contact as a suggestion
-        speedDialUiItems.add(contact);
+        // TODO(77754534): improve suggestions beyond just first channel
+        speedDialUiItems.add(
+            contact.toBuilder().setDefaultChannel(contact.channels().get(0)).build());
 
       } else if (speedDialUiItems.stream().noneMatch(c -> c.contactId() == contact.contactId())) {
         entriesToInsert.add(
diff --git a/java/com/android/dialer/speeddial/res/drawable/context_menu_background.xml b/java/com/android/dialer/speeddial/res/drawable/context_menu_background.xml
new file mode 100644
index 0000000..c828860
--- /dev/null
+++ b/java/com/android/dialer/speeddial/res/drawable/context_menu_background.xml
@@ -0,0 +1,26 @@
+<?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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+  <corners
+      android:bottomRightRadius="@dimen/speed_dial_context_menu_corner_radius"
+      android:topRightRadius="@dimen/speed_dial_context_menu_corner_radius"
+      android:bottomLeftRadius="@dimen/speed_dial_context_menu_corner_radius"
+      android:topLeftRadius="@dimen/speed_dial_context_menu_corner_radius"/>
+  <solid android:color="@color/background_dialer_white"/>
+  <stroke android:color="#0333" android:width="2dp"/>
+</shape>
\ No newline at end of file
diff --git a/java/com/android/dialer/speeddial/res/layout/context_menu_layout.xml b/java/com/android/dialer/speeddial/res/layout/context_menu_layout.xml
new file mode 100644
index 0000000..4fb12ff
--- /dev/null
+++ b/java/com/android/dialer/speeddial/res/layout/context_menu_layout.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2018 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
+ -->
+<com.android.dialer.speeddial.ContextMenu
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/contact_menu_container"
+    android:orientation="vertical"
+    android:layout_width="160dp"
+    android:layout_height="wrap_content"
+    android:elevation="8dp"
+    android:clipChildren="true"
+    android:clipToPadding="false">
+
+  <FrameLayout
+      android:layout_width="12dp"
+      android:layout_height="12dp"
+      android:layout_marginTop="7dp"
+      android:layout_marginBottom="-6dp"
+      android:layout_gravity="center_horizontal"
+      android:background="@color/background_dialer_white"
+      android:rotation="45"
+      android:clipChildren="false"
+      android:clipToPadding="false"/>
+
+  <LinearLayout
+      android:id="@+id/context_menu_items_container"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:orientation="vertical"
+      android:background="@drawable/context_menu_background">
+
+
+    <TextView
+        android:id="@+id/voice_call_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/contact_menu_voice_call"
+        android:drawableStart="@drawable/quantum_ic_phone_vd_theme_24"
+        style="@style/SpeedDialContextMenuItem"/>
+
+    <TextView
+        android:id="@+id/video_call_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/contact_menu_video_call"
+        android:drawableStart="@drawable/quantum_ic_videocam_vd_theme_24"
+        style="@style/SpeedDialContextMenuItem"/>
+
+    <TextView
+        android:id="@+id/send_message_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="4dp"
+        android:text="@string/contact_menu_message"
+        android:drawableStart="@drawable/quantum_ic_message_vd_theme_24"
+        style="@style/SpeedDialContextMenuItem"/>
+
+    <View
+        android:id="@+id/divider"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="@color/divider_line_color"/>
+
+    <TextView
+        android:id="@+id/remove_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingTop="4dp"
+        android:text="@string/contact_menu_remove"
+        android:drawableStart="@drawable/quantum_ic_close_vd_theme_24"
+        style="@style/SpeedDialContextMenuItem"/>
+
+    <!-- TODO(calderwoodra): Update this icon to be the contact icon. -->
+    <TextView
+        android:id="@+id/contact_info_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/contact_menu_contact_info"
+        android:drawableStart="@drawable/quantum_ic_call_vd_theme_24"
+        style="@style/SpeedDialContextMenuItem"/>
+  </LinearLayout>
+</com.android.dialer.speeddial.ContextMenu>
\ 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 67ef877..080fba5 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
@@ -14,11 +14,29 @@
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License
  -->
-<android.support.v7.widget.RecyclerView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/speed_dial_recycler_view"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/speed_dial_root"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:clipToPadding="false"
-    android:background="@color/background_dialer_light"
-    android:paddingBottom="@dimen/floating_action_button_list_bottom_padding"/>
+    android:layout_height="match_parent">
+
+  <android.support.v7.widget.RecyclerView
+      android:id="@+id/speed_dial_recycler_view"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:clipToPadding="false"
+      android:background="@color/background_dialer_light"
+      android:paddingBottom="@dimen/floating_action_button_list_bottom_padding"/>
+
+  <FrameLayout
+      android:id="@+id/context_menu_background"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:visibility="invisible"/>
+
+  <!-- This menu is visible when you long click on a favorite contact. -->
+  <include
+      android:id="@+id/favorite_contact_context_menu"
+      layout="@layout/context_menu_layout"
+      android:visibility="invisible"/>
+</FrameLayout>
+
diff --git a/java/com/android/dialer/speeddial/res/values/dimens.xml b/java/com/android/dialer/speeddial/res/values/dimens.xml
index 74b509b..ce2de9d 100644
--- a/java/com/android/dialer/speeddial/res/values/dimens.xml
+++ b/java/com/android/dialer/speeddial/res/values/dimens.xml
@@ -16,4 +16,19 @@
   -->
 <resources>
   <dimen name="scrollview_max_height">280dp</dimen>
+  <dimen name="speed_dial_context_menu_width">200dp</dimen>
+  <dimen name="context_menu_elevation">4dp</dimen>
+  <dimen name="speed_dial_recyclerview_horizontal_padding">16dp</dimen>
+
+  <!--
+   ~ This value expands the context menu to allow space for more text w/o being flush with the edge
+   ~ of the screen. Calculated with 2 * (speed_dial_recyclerview_horizontal_padding - 2dp)
+   -->
+  <dimen name="speed_dial_context_menu_extra_width">28dp</dimen>
+  <!--
+   ~ This value centers the context menu with the favorite item layout.
+   ~ Calculated with -1 * (speed_dial_context_menu_extra_width * 1.75)
+   -->
+  <dimen name="speed_dial_context_menu_x_offset">-24dp</dimen>
+  <dimen name="speed_dial_context_menu_corner_radius">16dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/java/com/android/dialer/speeddial/res/values/strings.xml b/java/com/android/dialer/speeddial/res/values/strings.xml
index 677f772..59a0ab5 100644
--- a/java/com/android/dialer/speeddial/res/values/strings.xml
+++ b/java/com/android/dialer/speeddial/res/values/strings.xml
@@ -40,4 +40,19 @@
 
   <!-- Title for screen prompting the user to select a contact to mark as a favorite. [CHAR LIMIT=NONE] -->
   <string name="add_favorite_activity_title">Add Favorite</string>
+
+  <!-- Text for a button that places a phone/voice call [CHAR LIMIT=15]-->
+  <string name="contact_menu_voice_call">Voice Call</string>
+
+  <!-- Text for a button that places a video call [CHAR LIMIT=15]-->
+  <string name="contact_menu_video_call">Video Call</string>
+
+  <!-- Text for a button that opens the contact in the SMS app [CHAR LIMIT=15]-->
+  <string name="contact_menu_message">Message</string>
+
+  <!-- Text for a button that removes the item from the list [CHAR LIMIT=15]-->
+  <string name="contact_menu_remove">Remove</string>
+
+  <!-- Text for a button that opens the contact's info [CHAR LIMIT=15]-->
+  <string name="contact_menu_contact_info">Contact info</string>
 </resources>
\ No newline at end of file
diff --git a/java/com/android/dialer/speeddial/res/values/styles.xml b/java/com/android/dialer/speeddial/res/values/styles.xml
new file mode 100644
index 0000000..83bbd09
--- /dev/null
+++ b/java/com/android/dialer/speeddial/res/values/styles.xml
@@ -0,0 +1,27 @@
+<?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
+  -->
+<resources>
+  <style name="SpeedDialContextMenuItem" parent="SecondaryText">
+    <item name="android:paddingStart">12dp</item>
+    <item name="android:minHeight">48dp</item>
+    <item name="android:gravity">center_vertical</item>
+    <item name="android:drawableTint">@color/secondary_text_color</item>
+    <item name="android:drawablePadding">12dp</item>
+    <item name="android:clickable">true</item>
+    <item name="android:background">?android:attr/selectableItemBackground</item>
+  </style>
+</resources>
\ No newline at end of file
diff --git a/java/com/android/dialer/theme/res/values/colors.xml b/java/com/android/dialer/theme/res/values/colors.xml
index a434874..6b98e20 100644
--- a/java/com/android/dialer/theme/res/values/colors.xml
+++ b/java/com/android/dialer/theme/res/values/colors.xml
@@ -73,4 +73,7 @@
 
   <!-- Color for bubble -->
   <color name="dialer_end_call_button_color">#BD2A2A</color>
+
+  <!-- Color for list dividers -->
+  <color name="divider_line_color">#D8D8D8</color>
 </resources>