diff --git a/res/layout/phone_disambig_item.xml b/res/layout/phone_disambig_item.xml
new file mode 100755
index 0000000..a31d08d
--- /dev/null
+++ b/res/layout/phone_disambig_item.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingLeft="30dip"
+    android:paddingRight="30dip"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:gravity="center_vertical">
+
+    <TextView
+        android:id="@android:id/text1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textStyle="bold"
+        android:textAppearance="?android:attr/textAppearanceMedium" />
+
+    <TextView
+        android:id="@android:id/text2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="-4dip"
+        android:textAppearance="?android:attr/textAppearanceSmall" />
+
+</LinearLayout>
diff --git a/res/layout/set_primary_checkbox.xml b/res/layout/set_primary_checkbox.xml
new file mode 100644
index 0000000..8f28ec7
--- /dev/null
+++ b/res/layout/set_primary_checkbox.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingLeft="14dip"
+    android:paddingRight="15dip"
+    android:orientation="vertical">
+
+    <CheckBox
+        android:id="@+id/setPrimary"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:focusable="true"
+        android:clickable="true"
+        android:text="@string/make_primary"/>
+</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1346d0d..86c36c4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -178,4 +178,12 @@
         <xliff:g id="date">%2$s</xliff:g>
     </string>
 
+    <!-- Title for the sms disambiguation dialog -->
+    <string name="sms_disambig_title">Choose number</string>
+
+    <!-- Title for the call disambiguation dialog -->
+    <string name="call_disambig_title">Choose number</string>
+
+    <!-- Message next to disamgiguation dialog check box -->
+    <string name="make_primary">Remember this choice</string>
 </resources>
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index f2119e0..7154a12 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -58,7 +58,7 @@
 
 import com.android.contacts.common.CallUtil;
 import com.android.contacts.common.activity.TransactionSafeActivity;
-import com.android.contacts.interactions.PhoneNumberInteraction;
+import com.android.dialer.interactions.PhoneNumberInteraction;
 import com.android.contacts.list.ContactListFilterController;
 import com.android.contacts.list.ContactListFilterController.ContactListFilterListener;
 import com.android.contacts.list.ContactListItemView;
diff --git a/src/com/android/dialer/interactions/PhoneNumberInteraction.java b/src/com/android/dialer/interactions/PhoneNumberInteraction.java
new file mode 100644
index 0000000..cb19a18
--- /dev/null
+++ b/src/com/android/dialer/interactions/PhoneNumberInteraction.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2010 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.interactions;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.CursorLoader;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.Intent;
+import android.content.Loader;
+import android.content.Loader.OnLoadCompleteListener;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+import com.android.contacts.common.CallUtil;
+import com.android.contacts.common.Collapser;
+import com.android.contacts.common.Collapser.Collapsible;
+import com.android.contacts.common.MoreContactUtils;
+import com.android.contacts.common.activity.TransactionSafeActivity;
+import com.android.contacts.common.util.ContactDisplayUtils;
+import com.android.dialer.R;
+import com.android.dialer.contact.ContactUpdateService;
+import com.google.common.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Initiates phone calls or a text message. If there are multiple candidates, this class shows a
+ * dialog to pick one. Creating one of these interactions should be done through the static
+ * factory methods.
+ *
+ * Note that this class initiates not only usual *phone* calls but also *SIP* calls.
+ *
+ * TODO: clean up code and documents since it is quite confusing to use "phone numbers" or
+ *        "phone calls" here while they can be SIP addresses or SIP calls (See also issue 5039627).
+ */
+public class PhoneNumberInteraction implements OnLoadCompleteListener<Cursor> {
+    private static final String TAG = PhoneNumberInteraction.class.getSimpleName();
+
+    /**
+     * A model object for capturing a phone number for a given contact.
+     */
+    @VisibleForTesting
+    /* package */ static class PhoneItem implements Parcelable, Collapsible<PhoneItem> {
+        long id;
+        String phoneNumber;
+        String accountType;
+        String dataSet;
+        long type;
+        String label;
+        /** {@link Phone#CONTENT_ITEM_TYPE} or {@link SipAddress#CONTENT_ITEM_TYPE}. */
+        String mimeType;
+
+        public PhoneItem() {
+        }
+
+        private PhoneItem(Parcel in) {
+            this.id          = in.readLong();
+            this.phoneNumber = in.readString();
+            this.accountType = in.readString();
+            this.dataSet     = in.readString();
+            this.type        = in.readLong();
+            this.label       = in.readString();
+            this.mimeType    = in.readString();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeLong(id);
+            dest.writeString(phoneNumber);
+            dest.writeString(accountType);
+            dest.writeString(dataSet);
+            dest.writeLong(type);
+            dest.writeString(label);
+            dest.writeString(mimeType);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public boolean collapseWith(PhoneItem phoneItem) {
+            if (!shouldCollapseWith(phoneItem)) {
+                return false;
+            }
+            // Just keep the number and id we already have.
+            return true;
+        }
+
+        @Override
+        public boolean shouldCollapseWith(PhoneItem phoneItem) {
+            return MoreContactUtils.shouldCollapse(Phone.CONTENT_ITEM_TYPE, phoneNumber,
+                    Phone.CONTENT_ITEM_TYPE, phoneItem.phoneNumber);
+        }
+
+        @Override
+        public String toString() {
+            return phoneNumber;
+        }
+
+        public static final Parcelable.Creator<PhoneItem> CREATOR
+                = new Parcelable.Creator<PhoneItem>() {
+            @Override
+            public PhoneItem createFromParcel(Parcel in) {
+                return new PhoneItem(in);
+            }
+
+            @Override
+            public PhoneItem[] newArray(int size) {
+                return new PhoneItem[size];
+            }
+        };
+    }
+
+    /**
+     * A list adapter that populates the list of contact's phone numbers.
+     */
+    private static class PhoneItemAdapter extends ArrayAdapter<PhoneItem> {
+        private final int mInteractionType;
+
+        public PhoneItemAdapter(Context context, List<PhoneItem> list,
+                int interactionType) {
+            super(context, R.layout.phone_disambig_item, android.R.id.text2, list);
+            mInteractionType = interactionType;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final View view = super.getView(position, convertView, parent);
+
+            final PhoneItem item = getItem(position);
+            final TextView typeView = (TextView) view.findViewById(android.R.id.text1);
+            CharSequence value = ContactDisplayUtils.getLabelForCallOrSms((int) item.type,
+                    item.label, mInteractionType, getContext());
+
+            typeView.setText(value);
+            return view;
+        }
+    }
+
+    /**
+     * {@link DialogFragment} used for displaying a dialog with a list of phone numbers of which
+     * one will be chosen to make a call or initiate an sms message.
+     *
+     * It is recommended to use
+     * {@link PhoneNumberInteraction#startInteractionForPhoneCall(TransactionSafeActivity, Uri)} or
+     * {@link PhoneNumberInteraction#startInteractionForTextMessage(TransactionSafeActivity, Uri)}
+     * instead of directly using this class, as those methods handle one or multiple data cases
+     * appropriately.
+     */
+    /* Made public to let the system reach this class */
+    public static class PhoneDisambiguationDialogFragment extends DialogFragment
+            implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
+
+        private static final String ARG_PHONE_LIST = "phoneList";
+        private static final String ARG_INTERACTION_TYPE = "interactionType";
+        private static final String ARG_CALL_ORIGIN = "callOrigin";
+
+        private int mInteractionType;
+        private ListAdapter mPhonesAdapter;
+        private List<PhoneItem> mPhoneList;
+        private String mCallOrigin;
+
+        public static void show(FragmentManager fragmentManager,
+                ArrayList<PhoneItem> phoneList, int interactionType,
+                String callOrigin) {
+            PhoneDisambiguationDialogFragment fragment = new PhoneDisambiguationDialogFragment();
+            Bundle bundle = new Bundle();
+            bundle.putParcelableArrayList(ARG_PHONE_LIST, phoneList);
+            bundle.putSerializable(ARG_INTERACTION_TYPE, interactionType);
+            bundle.putString(ARG_CALL_ORIGIN, callOrigin);
+            fragment.setArguments(bundle);
+            fragment.show(fragmentManager, TAG);
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            final Activity activity = getActivity();
+            mPhoneList = getArguments().getParcelableArrayList(ARG_PHONE_LIST);
+            mInteractionType = getArguments().getInt(ARG_INTERACTION_TYPE);
+            mCallOrigin = getArguments().getString(ARG_CALL_ORIGIN);
+
+            mPhonesAdapter = new PhoneItemAdapter(activity, mPhoneList, mInteractionType);
+            final LayoutInflater inflater = activity.getLayoutInflater();
+            final View setPrimaryView = inflater.inflate(R.layout.set_primary_checkbox, null);
+            return new AlertDialog.Builder(activity)
+                    .setAdapter(mPhonesAdapter, this)
+                    .setTitle(mInteractionType == ContactDisplayUtils.INTERACTION_SMS
+                            ? R.string.sms_disambig_title : R.string.call_disambig_title)
+                    .setView(setPrimaryView)
+                    .create();
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            final Activity activity = getActivity();
+            if (activity == null) return;
+            final AlertDialog alertDialog = (AlertDialog)dialog;
+            if (mPhoneList.size() > which && which >= 0) {
+                final PhoneItem phoneItem = mPhoneList.get(which);
+                final CheckBox checkBox = (CheckBox)alertDialog.findViewById(R.id.setPrimary);
+                if (checkBox.isChecked()) {
+                    // Request to mark the data as primary in the background.
+                    final Intent serviceIntent = ContactUpdateService.createSetSuperPrimaryIntent(
+                            activity, phoneItem.id);
+                    activity.startService(serviceIntent);
+                }
+
+                PhoneNumberInteraction.performAction(activity, phoneItem.phoneNumber,
+                        mInteractionType, mCallOrigin);
+            } else {
+                dialog.dismiss();
+            }
+        }
+    }
+
+    private static final String[] PHONE_NUMBER_PROJECTION = new String[] {
+            Phone._ID,
+            Phone.NUMBER,
+            Phone.IS_SUPER_PRIMARY,
+            RawContacts.ACCOUNT_TYPE,
+            RawContacts.DATA_SET,
+            Phone.TYPE,
+            Phone.LABEL,
+            Phone.MIMETYPE
+    };
+
+    private static final String PHONE_NUMBER_SELECTION =
+            Data.MIMETYPE + " IN ('"
+                + Phone.CONTENT_ITEM_TYPE + "', "
+                + "'" + SipAddress.CONTENT_ITEM_TYPE + "') AND "
+                + Data.DATA1 + " NOT NULL";
+
+    private final Context mContext;
+    private final OnDismissListener mDismissListener;
+    private final int mInteractionType;
+
+    private final String mCallOrigin;
+
+    private CursorLoader mLoader;
+
+    /**
+     * Constructs a new {@link PhoneNumberInteraction}. The constructor takes in a {@link Context}
+     * instead of a {@link TransactionSafeActivity} for testing purposes to verify the functionality
+     * of this class. However, all factory methods for creating {@link PhoneNumberInteraction}s
+     * require a {@link TransactionSafeActivity} (i.e. see {@link #startInteractionForPhoneCall}).
+     */
+    @VisibleForTesting
+    /* package */ PhoneNumberInteraction(Context context, int interactionType,
+            DialogInterface.OnDismissListener dismissListener) {
+        this(context, interactionType, dismissListener, null);
+    }
+
+    private PhoneNumberInteraction(Context context, int interactionType,
+            DialogInterface.OnDismissListener dismissListener, String callOrigin) {
+        mContext = context;
+        mInteractionType = interactionType;
+        mDismissListener = dismissListener;
+        mCallOrigin = callOrigin;
+    }
+
+    private void performAction(String phoneNumber) {
+        PhoneNumberInteraction.performAction(mContext, phoneNumber, mInteractionType, mCallOrigin);
+    }
+
+    private static void performAction(
+            Context context, String phoneNumber, int interactionType,
+            String callOrigin) {
+        Intent intent;
+        switch (interactionType) {
+            case ContactDisplayUtils.INTERACTION_SMS:
+                intent = new Intent(
+                        Intent.ACTION_SENDTO, Uri.fromParts("sms", phoneNumber, null));
+                break;
+            default:
+                intent = CallUtil.getCallIntent(phoneNumber, callOrigin);
+                break;
+        }
+        context.startActivity(intent);
+    }
+
+    /**
+     * Initiates the interaction. This may result in a phone call or sms message started
+     * or a disambiguation dialog to determine which phone number should be used.
+     */
+    @VisibleForTesting
+    /* package */ void startInteraction(Uri uri) {
+        if (mLoader != null) {
+            mLoader.reset();
+        }
+
+        final Uri queryUri;
+        final String inputUriAsString = uri.toString();
+        if (inputUriAsString.startsWith(Contacts.CONTENT_URI.toString())) {
+            if (!inputUriAsString.endsWith(Contacts.Data.CONTENT_DIRECTORY)) {
+                queryUri = Uri.withAppendedPath(uri, Contacts.Data.CONTENT_DIRECTORY);
+            } else {
+                queryUri = uri;
+            }
+        } else if (inputUriAsString.startsWith(Data.CONTENT_URI.toString())) {
+            queryUri = uri;
+        } else {
+            throw new UnsupportedOperationException(
+                    "Input Uri must be contact Uri or data Uri (input: \"" + uri + "\")");
+        }
+
+        mLoader = new CursorLoader(mContext,
+                queryUri,
+                PHONE_NUMBER_PROJECTION,
+                PHONE_NUMBER_SELECTION,
+                null,
+                null);
+        mLoader.registerListener(0, this);
+        mLoader.startLoading();
+    }
+
+    @Override
+    public void onLoadComplete(Loader<Cursor> loader, Cursor cursor) {
+        if (cursor == null || !isSafeToCommitTransactions()) {
+            onDismiss();
+            return;
+        }
+
+        ArrayList<PhoneItem> phoneList = new ArrayList<PhoneItem>();
+        String primaryPhone = null;
+        try {
+            while (cursor.moveToNext()) {
+                if (cursor.getInt(cursor.getColumnIndex(Phone.IS_SUPER_PRIMARY)) != 0) {
+                    // Found super primary, call it.
+                    primaryPhone = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
+                    break;
+                }
+
+                PhoneItem item = new PhoneItem();
+                item.id = cursor.getLong(cursor.getColumnIndex(Data._ID));
+                item.phoneNumber = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
+                item.accountType =
+                        cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_TYPE));
+                item.dataSet = cursor.getString(cursor.getColumnIndex(RawContacts.DATA_SET));
+                item.type = cursor.getInt(cursor.getColumnIndex(Phone.TYPE));
+                item.label = cursor.getString(cursor.getColumnIndex(Phone.LABEL));
+                item.mimeType = cursor.getString(cursor.getColumnIndex(Phone.MIMETYPE));
+
+                phoneList.add(item);
+            }
+        } finally {
+            cursor.close();
+        }
+
+        if (primaryPhone != null) {
+            performAction(primaryPhone);
+            onDismiss();
+            return;
+        }
+
+        Collapser.collapseList(phoneList);
+
+        if (phoneList.size() == 0) {
+            onDismiss();
+        } else if (phoneList.size() == 1) {
+            PhoneItem item = phoneList.get(0);
+            onDismiss();
+            performAction(item.phoneNumber);
+        } else {
+            // There are multiple candidates. Let the user choose one.
+            showDisambiguationDialog(phoneList);
+        }
+    }
+
+    private boolean isSafeToCommitTransactions() {
+        return mContext instanceof TransactionSafeActivity ?
+                ((TransactionSafeActivity) mContext).isSafeToCommitTransactions() : true;
+    }
+
+    private void onDismiss() {
+        if (mDismissListener != null) {
+            mDismissListener.onDismiss(null);
+        }
+    }
+
+    /**
+     * Start call action using given contact Uri. If there are multiple candidates for the phone
+     * call, dialog is automatically shown and the user is asked to choose one.
+     *
+     * @param activity that is calling this interaction. This must be of type
+     * {@link TransactionSafeActivity} because we need to check on the activity state after the
+     * phone numbers have been queried for.
+     * @param uri contact Uri (built from {@link Contacts#CONTENT_URI}) or data Uri
+     * (built from {@link Data#CONTENT_URI}). Contact Uri may show the disambiguation dialog while
+     * data Uri won't.
+     */
+    public static void startInteractionForPhoneCall(TransactionSafeActivity activity, Uri uri) {
+        (new PhoneNumberInteraction(activity, ContactDisplayUtils.INTERACTION_CALL, null))
+                .startInteraction(uri);
+    }
+
+    /**
+     * @param activity that is calling this interaction. This must be of type
+     * {@link TransactionSafeActivity} because we need to check on the activity state after the
+     * phone numbers have been queried for.
+     * @param callOrigin If non null, {@link PhoneConstants#EXTRA_CALL_ORIGIN} will be
+     * appended to the Intent initiating phone call. See comments in Phone package (PhoneApp)
+     * for more detail.
+     */
+    public static void startInteractionForPhoneCall(TransactionSafeActivity activity, Uri uri,
+            String callOrigin) {
+        (new PhoneNumberInteraction(activity, ContactDisplayUtils.INTERACTION_CALL, null, callOrigin))
+                .startInteraction(uri);
+    }
+
+    /**
+     * Start text messaging (a.k.a SMS) action using given contact Uri. If there are multiple
+     * candidates for the phone call, dialog is automatically shown and the user is asked to choose
+     * one.
+     *
+     * @param activity that is calling this interaction. This must be of type
+     * {@link TransactionSafeActivity} because we need to check on the activity state after the
+     * phone numbers have been queried for.
+     * @param uri contact Uri (built from {@link Contacts#CONTENT_URI}) or data Uri
+     * (built from {@link Data#CONTENT_URI}). Contact Uri may show the disambiguation dialog while
+     * data Uri won't.
+     */
+    public static void startInteractionForTextMessage(TransactionSafeActivity activity, Uri uri) {
+        (new PhoneNumberInteraction(activity, ContactDisplayUtils.INTERACTION_SMS, null))
+                .startInteraction(uri);
+    }
+
+    @VisibleForTesting
+    /* package */ CursorLoader getLoader() {
+        return mLoader;
+    }
+
+    @VisibleForTesting
+    /* package */ void showDisambiguationDialog(ArrayList<PhoneItem> phoneList) {
+        PhoneDisambiguationDialogFragment.show(((Activity)mContext).getFragmentManager(),
+                phoneList, mInteractionType, mCallOrigin);
+    }
+}
diff --git a/tests/src/com/android/dialer/interactions/PhoneNumberInteractionTest.java b/tests/src/com/android/dialer/interactions/PhoneNumberInteractionTest.java
new file mode 100644
index 0000000..f86675e
--- /dev/null
+++ b/tests/src/com/android/dialer/interactions/PhoneNumberInteractionTest.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2010 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.interactions;
+
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.contacts.common.test.mocks.ContactsMockContext;
+import com.android.contacts.common.test.mocks.MockContentProvider;
+import com.android.contacts.common.test.mocks.MockContentProvider.Query;
+import com.android.contacts.common.util.ContactDisplayUtils;
+import com.android.dialer.interactions.PhoneNumberInteraction.PhoneItem;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link com.android.contacts.common.interactions.PhoneNumberInteraction}.
+ *
+ * Running all tests:
+ *
+ *   runtest contacts
+ * or
+ *   adb shell am instrument \
+ *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
+ */
+@SmallTest
+public class PhoneNumberInteractionTest extends InstrumentationTestCase {
+
+    static {
+        // AsyncTask class needs to be initialized on the main thread.
+        AsyncTask.init();
+    }
+
+    private final static class TestPhoneNumberInteraction extends PhoneNumberInteraction {
+        private ArrayList<PhoneItem> mPhoneList;
+
+        public TestPhoneNumberInteraction(Context context, int interactionType,
+                OnDismissListener dismissListener) {
+            super(context, interactionType, dismissListener);
+        }
+
+        @Override
+        void showDisambiguationDialog(ArrayList<PhoneItem> phoneList) {
+            this.mPhoneList = phoneList;
+        }
+    }
+
+    private ContactsMockContext mContext;
+    private MockContentProvider mContactsProvider;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = new ContactsMockContext(getInstrumentation().getTargetContext());
+        mContactsProvider = mContext.getContactsProvider();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mContactsProvider.verify();
+        super.tearDown();
+    }
+
+    public void testSendSmsWhenOnlyOneNumberAvailable() {
+        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
+        expectQuery(contactUri)
+                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null,
+                        Phone.CONTENT_ITEM_TYPE);
+
+        TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
+                mContext, ContactDisplayUtils.INTERACTION_SMS, null);
+
+        interaction.startInteraction(contactUri);
+        interaction.getLoader().waitForLoader();
+
+        Intent intent = mContext.getIntentForStartActivity();
+        assertNotNull(intent);
+
+        assertEquals(Intent.ACTION_SENDTO, intent.getAction());
+        assertEquals("sms:123", intent.getDataString());
+    }
+
+    public void testSendSmsWhenDataIdIsProvided() {
+        Uri dataUri = ContentUris.withAppendedId(Data.CONTENT_URI, 1);
+        expectQuery(dataUri, true /* isDataUri */ )
+                .returnRow(1, "987", 0, null, null, Phone.TYPE_HOME, null,
+                        Phone.CONTENT_ITEM_TYPE);
+
+        TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
+                mContext, ContactDisplayUtils.INTERACTION_SMS, null);
+
+        interaction.startInteraction(dataUri);
+        interaction.getLoader().waitForLoader();
+
+        Intent intent = mContext.getIntentForStartActivity();
+        assertNotNull(intent);
+
+        assertEquals(Intent.ACTION_SENDTO, intent.getAction());
+        assertEquals("sms:987", intent.getDataString());
+    }
+
+    public void testSendSmsWhenThereIsPrimaryNumber() {
+        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
+        expectQuery(contactUri)
+                .returnRow(
+                        1, "123", 0, null, null, Phone.TYPE_HOME, null, Phone.CONTENT_ITEM_TYPE)
+                .returnRow(
+                        2, "456", 1, null, null, Phone.TYPE_HOME, null, Phone.CONTENT_ITEM_TYPE);
+
+        TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
+                mContext, ContactDisplayUtils.INTERACTION_SMS, null);
+
+        interaction.startInteraction(contactUri);
+        interaction.getLoader().waitForLoader();
+
+        Intent intent = mContext.getIntentForStartActivity();
+        assertNotNull(intent);
+
+        assertEquals(Intent.ACTION_SENDTO, intent.getAction());
+        assertEquals("sms:456", intent.getDataString());
+    }
+
+    public void testShouldCollapseWith() {
+        PhoneNumberInteraction.PhoneItem phoneItem1 = new PhoneNumberInteraction.PhoneItem();
+        PhoneNumberInteraction.PhoneItem phoneItem2 = new PhoneNumberInteraction.PhoneItem();
+
+        phoneItem1.phoneNumber = "123";
+        phoneItem2.phoneNumber = "123";
+
+        assertTrue(phoneItem1.shouldCollapseWith(phoneItem2));
+
+        phoneItem1.phoneNumber = "123";
+        phoneItem2.phoneNumber = "456";
+
+        assertFalse(phoneItem1.shouldCollapseWith(phoneItem2));
+
+        phoneItem1.phoneNumber = "123#,123";
+        phoneItem2.phoneNumber = "123#,456";
+
+        assertFalse(phoneItem1.shouldCollapseWith(phoneItem2));
+    }
+
+    public void testCallNumberWhenThereAreDuplicates() {
+        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
+        expectQuery(contactUri)
+                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null,
+                        Phone.CONTENT_ITEM_TYPE)
+                .returnRow(2, "123", 0, null, null, Phone.TYPE_WORK, null,
+                        Phone.CONTENT_ITEM_TYPE);
+
+        TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
+                mContext, ContactDisplayUtils.INTERACTION_CALL, null);
+
+        interaction.startInteraction(contactUri);
+        interaction.getLoader().waitForLoader();
+
+        Intent intent = mContext.getIntentForStartActivity();
+        assertNotNull(intent);
+
+        assertEquals(Intent.ACTION_CALL_PRIVILEGED, intent.getAction());
+        assertEquals("tel:123", intent.getDataString());
+    }
+
+    public void testCallWithSip() {
+        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
+        expectQuery(contactUri)
+                .returnRow(1, "example@example.com", 0, null, null, Phone.TYPE_HOME, null,
+                        SipAddress.CONTENT_ITEM_TYPE);
+        TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
+                mContext, ContactDisplayUtils.INTERACTION_CALL, null);
+
+        interaction.startInteraction(contactUri);
+        interaction.getLoader().waitForLoader();
+
+        Intent intent = mContext.getIntentForStartActivity();
+        assertNotNull(intent);
+
+        assertEquals(Intent.ACTION_CALL_PRIVILEGED, intent.getAction());
+        assertEquals("sip:example%40example.com", intent.getDataString());
+    }
+
+    public void testShowDisambigDialogForCalling() {
+        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
+        expectQuery(contactUri)
+                .returnRow(1, "123", 0, "account", null, Phone.TYPE_HOME, "label",
+                        Phone.CONTENT_ITEM_TYPE)
+                .returnRow(2, "456", 0, null, null, Phone.TYPE_WORK, null,
+                        Phone.CONTENT_ITEM_TYPE);
+
+        TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
+                mContext, ContactDisplayUtils.INTERACTION_CALL, null);
+
+        interaction.startInteraction(contactUri);
+        interaction.getLoader().waitForLoader();
+
+        List<PhoneItem> items = interaction.mPhoneList;
+        assertNotNull(items);
+        assertEquals(2, items.size());
+
+        PhoneItem item = items.get(0);
+        assertEquals(1, item.id);
+        assertEquals("123", item.phoneNumber);
+        assertEquals("account", item.accountType);
+        assertEquals(Phone.TYPE_HOME, item.type);
+        assertEquals("label", item.label);
+    }
+
+    private Query expectQuery(Uri contactUri) {
+        return expectQuery(contactUri, false);
+    }
+
+    private Query expectQuery(Uri uri, boolean isDataUri) {
+        final Uri dataUri;
+        if (isDataUri) {
+            dataUri = uri;
+        } else {
+            dataUri = Uri.withAppendedPath(uri, Contacts.Data.CONTENT_DIRECTORY);
+        }
+        return mContactsProvider
+                .expectQuery(dataUri)
+                .withProjection(
+                        Phone._ID,
+                        Phone.NUMBER,
+                        Phone.IS_SUPER_PRIMARY,
+                        RawContacts.ACCOUNT_TYPE,
+                        RawContacts.DATA_SET,
+                        Phone.TYPE,
+                        Phone.LABEL,
+                        Phone.MIMETYPE)
+                .withSelection("mimetype IN ('vnd.android.cursor.item/phone_v2',"
+                        + " 'vnd.android.cursor.item/sip_address') AND data1 NOT NULL");
+    }
+}
