Merge changes I0ed4fa1b,Ie03ce41e,If41868df,Iba2e9092 am: 2b52d2a3cd
am: f2805eaaba

Change-Id: Ic6071b5f880e6be6a1fdba9f1e675db5a4fcb622
diff --git a/Android.mk b/Android.mk
index 9defc7e..e9841d9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -81,6 +81,8 @@
 # We specify each package explicitly to glob resource files.
 # find . -type f -name "AndroidManifest.xml" | uniq | sort | cut -c 8- | rev | cut -c 21- | rev | sed 's/\//./g' | sed 's/$/ \\/'
 LOCAL_AAPT_FLAGS := \
+	com.android.assets.product \
+	com.android.assets.quantum \
 	com.android.bubble \
 	com.android.contacts.common \
 	com.android.dialer.about \
@@ -116,8 +118,11 @@
 	com.android.dialer.main.impl \
 	com.android.dialer.notification \
 	com.android.dialer.oem \
+	com.android.dialer.phonelookup.database \
 	com.android.dialer.phonenumberutil \
 	com.android.dialer.postcall \
+	com.android.dialer.precall.impl \
+	com.android.dialer.preferredsim.impl \
 	com.android.dialer.searchfragment.common \
 	com.android.dialer.searchfragment.cp2 \
 	com.android.dialer.searchfragment.list \
@@ -129,7 +134,7 @@
 	com.android.dialer.theme \
 	com.android.dialer.util \
 	com.android.dialer.voicemail.listui \
-        com.android.dialer.voicemail.settings \
+	com.android.dialer.voicemail.settings \
 	com.android.dialer.voicemailstatus \
 	com.android.dialer.widget \
 	com.android.incallui \
diff --git a/java/com/android/contacts/common/dialog/CallSubjectDialog.java b/java/com/android/contacts/common/dialog/CallSubjectDialog.java
index 5c2ae2f..2ba2476 100644
--- a/java/com/android/contacts/common/dialog/CallSubjectDialog.java
+++ b/java/com/android/contacts/common/dialog/CallSubjectDialog.java
@@ -50,6 +50,7 @@
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.contactphoto.ContactPhotoManager;
 import com.android.dialer.lettertile.LetterTileDrawable;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.util.ViewUtil;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
@@ -148,13 +149,12 @@
         @Override
         public void onClick(View v) {
           String subject = mCallSubjectView.getText().toString();
-          Intent intent =
+          PreCall.start(
+              CallSubjectDialog.this,
               new CallIntentBuilder(mNumber, CallInitiationType.Type.CALL_SUBJECT_DIALOG)
                   .setPhoneAccountHandle(mPhoneAccountHandle)
-                  .setCallSubject(subject)
-                  .build();
+                  .setCallSubject(subject));
 
-          getSystemService(TelecomManager.class).placeCall(intent.getData(), intent.getExtras());
           mSubjectHistory.add(subject);
           saveSubjectHistory(mSubjectHistory);
           finish();
diff --git a/java/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java b/java/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java
index 8156d97..6c6aebc 100644
--- a/java/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java
+++ b/java/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java
@@ -26,6 +26,7 @@
 import android.os.Handler;
 import android.os.ResultReceiver;
 import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -116,6 +117,12 @@
     mListener = listener;
   }
 
+  @Nullable
+  @VisibleForTesting
+  public SelectPhoneAccountListener getListener() {
+    return mListener;
+  }
+
   @Override
   public void onSaveInstanceState(Bundle outState) {
     super.onSaveInstanceState(outState);
diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java
index 089ffd3..4c26341 100644
--- a/java/com/android/dialer/app/DialtactsActivity.java
+++ b/java/com/android/dialer/app/DialtactsActivity.java
@@ -121,6 +121,7 @@
 import com.android.dialer.p13n.logging.P13nLogging;
 import com.android.dialer.performancereport.PerformanceReport;
 import com.android.dialer.postcall.PostCall;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.proguard.UsedByReflection;
 import com.android.dialer.searchfragment.list.NewSearchFragment;
 import com.android.dialer.searchfragment.list.NewSearchFragment.SearchFragmentListener;
@@ -1515,14 +1516,12 @@
       // an error message.
       phoneNumber = "";
     }
-
-    Intent intent =
+    PreCall.start(
+        this,
         new CallIntentBuilder(phoneNumber, callSpecificAppData)
             .setIsVideoCall(isVideoCall)
-            .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing())
-            .build();
+            .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing()));
 
-    DialerUtils.startActivityWithErrorToast(this, intent);
     mClearSearchOnPause = true;
   }
 
@@ -1555,6 +1554,7 @@
     if (tabIndex != mPreviouslySelectedTabIndex) {
       mFloatingActionButtonController.scaleIn();
     }
+    LogUtil.i("DialtactsActivity.onPageSelected", "tabIndex: %d", tabIndex);
     mPreviouslySelectedTabIndex = tabIndex;
     timeTabSelected = SystemClock.elapsedRealtime();
   }
@@ -1676,6 +1676,10 @@
     exitSearchUi();
   }
 
+  protected int getPreviouslySelectedTabIndex() {
+    return mPreviouslySelectedTabIndex;
+  }
+
   /** Popup menu accessible from the search bar */
   protected class OptionsPopupMenu extends PopupMenu {
 
diff --git a/java/com/android/dialer/app/calllog/IntentProvider.java b/java/com/android/dialer/app/calllog/IntentProvider.java
index 5180651..0835d89 100644
--- a/java/com/android/dialer/app/calllog/IntentProvider.java
+++ b/java/com/android/dialer/app/calllog/IntentProvider.java
@@ -32,6 +32,7 @@
 import com.android.dialer.callintent.CallIntentBuilder;
 import com.android.dialer.dialercontact.DialerContact;
 import com.android.dialer.duo.DuoComponent;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.util.IntentUtil;
 import java.util.ArrayList;
 
@@ -53,9 +54,10 @@
     return new IntentProvider() {
       @Override
       public Intent getIntent(Context context) {
-        return new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG)
-            .setPhoneAccountHandle(accountHandle)
-            .build();
+        return PreCall.getIntent(
+            context,
+            new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG)
+                .setPhoneAccountHandle(accountHandle));
       }
     };
   }
@@ -65,9 +67,10 @@
     return new IntentProvider() {
       @Override
       public Intent getIntent(Context context) {
-        return new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG)
-            .setAllowAssistedDial(true)
-            .build();
+        return PreCall.getIntent(
+            context,
+            new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG)
+                .setAllowAssistedDial(true));
       }
     };
   }
@@ -81,10 +84,11 @@
     return new IntentProvider() {
       @Override
       public Intent getIntent(Context context) {
-        return new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG)
-            .setPhoneAccountHandle(accountHandle)
-            .setIsVideoCall(true)
-            .build();
+        return PreCall.getIntent(
+            context,
+            new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG)
+                .setPhoneAccountHandle(accountHandle)
+                .setIsVideoCall(true));
       }
     };
   }
@@ -103,8 +107,9 @@
     return new IntentProvider() {
       @Override
       public Intent getIntent(Context context) {
-        return CallIntentBuilder.forVoicemail(phoneAccountHandle, CallInitiationType.Type.CALL_LOG)
-            .build();
+        return PreCall.getIntent(
+            context,
+            CallIntentBuilder.forVoicemail(phoneAccountHandle, CallInitiationType.Type.CALL_LOG));
       }
     };
   }
diff --git a/java/com/android/dialer/app/calllog/MissedCallNotifier.java b/java/com/android/dialer/app/calllog/MissedCallNotifier.java
index 8e09cf8..dd92bb4 100644
--- a/java/com/android/dialer/app/calllog/MissedCallNotifier.java
+++ b/java/com/android/dialer/app/calllog/MissedCallNotifier.java
@@ -60,6 +60,7 @@
 import com.android.dialer.notification.NotificationManagerUtils;
 import com.android.dialer.phonenumbercache.ContactInfo;
 import com.android.dialer.phonenumberutil.PhoneNumberHelper;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.util.DialerUtils;
 import com.android.dialer.util.IntentUtil;
 import java.util.Iterator;
@@ -438,8 +439,9 @@
     cancelSingleMissedCallNotification(context, callUri);
     DialerUtils.startActivityWithErrorToast(
         context,
-        new CallIntentBuilder(number, CallInitiationType.Type.MISSED_CALL_NOTIFICATION)
-            .build()
+        PreCall.getIntent(
+                context,
+                new CallIntentBuilder(number, CallInitiationType.Type.MISSED_CALL_NOTIFICATION))
             .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
   }
 
diff --git a/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java b/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java
index 7cc6cda..be7dccd 100644
--- a/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java
+++ b/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java
@@ -31,6 +31,7 @@
 import com.android.dialer.common.PerAccountSharedPreferences;
 import com.android.dialer.logging.DialerImpression;
 import com.android.dialer.logging.Logger;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.voicemail.settings.VoicemailChangePinActivity;
 import com.android.voicemail.VoicemailClient;
 import com.android.voicemail.VoicemailComponent;
@@ -165,10 +166,10 @@
           @Override
           public void onClick(View v) {
             Logger.get(context).logImpression(DialerImpression.Type.VVM_CALL_VOICEMAIL_CLICKED);
-            context.startActivity(
+            PreCall.start(
+                context,
                 CallIntentBuilder.forVoicemail(
-                        phoneAccountHandle, CallInitiationType.Type.VOICEMAIL_ERROR_MESSAGE)
-                    .build());
+                    phoneAccountHandle, CallInitiationType.Type.VOICEMAIL_ERROR_MESSAGE));
           }
         });
   }
diff --git a/java/com/android/dialer/assisteddialing/ConcreteCreator.java b/java/com/android/dialer/assisteddialing/ConcreteCreator.java
index c3721a7..8067645 100644
--- a/java/com/android/dialer/assisteddialing/ConcreteCreator.java
+++ b/java/com/android/dialer/assisteddialing/ConcreteCreator.java
@@ -22,6 +22,7 @@
 import android.os.Build.VERSION_CODES;
 import android.preference.PreferenceManager;
 import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
 import android.support.v4.os.UserManagerCompat;
 import android.telephony.TelephonyManager;
 import com.android.dialer.assisteddialing.ui.R;
@@ -41,7 +42,7 @@
   // Floor set at N due to use of Optional.
   protected static final int BUILD_CODE_FLOOR = Build.VERSION_CODES.N;
   // Ceiling set at O because this feature will ship as part of the framework in P.
-  protected static final int BUILD_CODE_CEILING = Build.VERSION_CODES.O;
+  @VisibleForTesting public static final int BUILD_CODE_CEILING = Build.VERSION_CODES.O;
 
   /**
    * Creates a new AssistedDialingMediator
diff --git a/java/com/android/dialer/callcomposer/CallComposerActivity.java b/java/com/android/dialer/callcomposer/CallComposerActivity.java
index cd0c741..0d47c70 100644
--- a/java/com/android/dialer/callcomposer/CallComposerActivity.java
+++ b/java/com/android/dialer/callcomposer/CallComposerActivity.java
@@ -72,6 +72,7 @@
 import com.android.dialer.logging.DialerImpression;
 import com.android.dialer.logging.Logger;
 import com.android.dialer.multimedia.MultimediaData;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.protos.ProtoParsers;
 import com.android.dialer.storage.StorageComponent;
 import com.android.dialer.telecom.TelecomUtil;
@@ -479,9 +480,8 @@
   }
 
   private void placeTelecomCall() {
-    TelecomUtil.placeCall(
-        this,
-        new CallIntentBuilder(contact.getNumber(), CallInitiationType.Type.CALL_COMPOSER).build());
+    PreCall.start(
+        this, new CallIntentBuilder(contact.getNumber(), CallInitiationType.Type.CALL_COMPOSER));
     setResult(RESULT_OK);
     finish();
   }
diff --git a/java/com/android/dialer/calldetails/CallDetailsActivity.java b/java/com/android/dialer/calldetails/CallDetailsActivity.java
index 6ba31e6..7a117a3 100644
--- a/java/com/android/dialer/calldetails/CallDetailsActivity.java
+++ b/java/com/android/dialer/calldetails/CallDetailsActivity.java
@@ -50,8 +50,8 @@
 import com.android.dialer.logging.UiAction;
 import com.android.dialer.performancereport.PerformanceReport;
 import com.android.dialer.postcall.PostCall;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.protos.ProtoParsers;
-import com.android.dialer.util.DialerUtils;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -209,11 +209,10 @@
   @Override
   public void placeImsVideoCall(String phoneNumber) {
     Logger.get(this).logImpression(DialerImpression.Type.CALL_DETAILS_IMS_VIDEO_CALL_BACK);
-    DialerUtils.startActivityWithErrorToast(
+    PreCall.start(
         this,
         new CallIntentBuilder(phoneNumber, CallInitiationType.Type.CALL_DETAILS)
-            .setIsVideoCall(true)
-            .build());
+            .setIsVideoCall(true));
   }
 
   @Override
@@ -244,7 +243,7 @@
       callIntentBuilder.setAllowAssistedDial(true);
     }
 
-    DialerUtils.startActivityWithErrorToast(this, callIntentBuilder.build());
+    PreCall.start(this, callIntentBuilder);
   }
 
   @NonNull
diff --git a/java/com/android/dialer/callintent/CallIntentBuilder.java b/java/com/android/dialer/callintent/CallIntentBuilder.java
index aabeabd..ff490c2 100644
--- a/java/com/android/dialer/callintent/CallIntentBuilder.java
+++ b/java/com/android/dialer/callintent/CallIntentBuilder.java
@@ -172,6 +172,11 @@
     return outgoingCallExtras;
   }
 
+  /**
+   * @deprecated Use {@link com.android.dialer.precall.PreCall#getIntent(android.content.Context,
+   *     CallIntentBuilder)} instead.
+   */
+  @Deprecated
   public Intent build() {
     Intent intent = new Intent(Intent.ACTION_CALL, uri);
 
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
index 9ddb65d..16147f6 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
@@ -138,7 +138,7 @@
   private void setOnClickListenerForRow(CoalescedRow row) {
     itemView.setOnClickListener(
         (view) -> {
-          Intent callbackIntent = CallLogIntents.getCallBackIntent(row);
+          Intent callbackIntent = CallLogIntents.getCallBackIntent(context, row);
           if (callbackIntent != null) {
             context.startActivity(callbackIntent);
           }
diff --git a/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java b/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
index 7077d02..404c417 100644
--- a/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
+++ b/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
@@ -42,7 +42,7 @@
                 .build())
         .setPrimaryText(CallLogEntryText.buildPrimaryText(context, row))
         .setSecondaryText(CallLogEntryText.buildSecondaryTextForBottomSheet(context, row))
-        .setIntent(CallLogIntents.getCallBackIntent(row))
+        .setIntent(CallLogIntents.getCallBackIntent(context, row))
         .build();
   }
 }
diff --git a/java/com/android/dialer/calllogutils/CallLogIntents.java b/java/com/android/dialer/calllogutils/CallLogIntents.java
index 11308e6..b06fe6e 100644
--- a/java/com/android/dialer/calllogutils/CallLogIntents.java
+++ b/java/com/android/dialer/calllogutils/CallLogIntents.java
@@ -15,6 +15,7 @@
  */
 package com.android.dialer.calllogutils;
 
+import android.content.Context;
 import android.content.Intent;
 import android.provider.CallLog.Calls;
 import android.support.annotation.Nullable;
@@ -22,6 +23,7 @@
 import com.android.dialer.callintent.CallInitiationType;
 import com.android.dialer.callintent.CallIntentBuilder;
 import com.android.dialer.calllog.model.CoalescedRow;
+import com.android.dialer.precall.PreCall;
 
 /** Provides intents related to call log entries. */
 public final class CallLogIntents {
@@ -35,10 +37,9 @@
    * @return null if the provided {@code row} doesn't have a number
    */
   @Nullable
-  public static Intent getCallBackIntent(CoalescedRow row) {
+  public static Intent getCallBackIntent(Context context, CoalescedRow row) {
     // TODO(zachh): Do something with parsed values to make more dialable?
     String originalNumber = row.number().getRawInput().getNumber();
-
     // TODO(zachh): Make this more sophisticated, e.g. return null for non-dialable numbers?
     if (TextUtils.isEmpty(originalNumber)) {
       return null;
@@ -46,10 +47,11 @@
 
     // TODO(zachh): More granular logging?
     // TODO(zachh): Support assisted dialing.
-    return new CallIntentBuilder(originalNumber, CallInitiationType.Type.CALL_LOG)
-        .setPhoneAccountHandle(
-            PhoneAccountUtils.getAccount(row.phoneAccountComponentName(), row.phoneAccountId()))
-        .setIsVideoCall((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO)
-        .build();
+    return PreCall.getIntent(
+        context,
+        new CallIntentBuilder(originalNumber, CallInitiationType.Type.CALL_LOG)
+            .setPhoneAccountHandle(
+                PhoneAccountUtils.getAccount(row.phoneAccountComponentName(), row.phoneAccountId()))
+            .setIsVideoCall((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO));
   }
 }
diff --git a/java/com/android/dialer/contactactions/IntentModule.java b/java/com/android/dialer/contactactions/IntentModule.java
index 5a4870c..57eb50a 100644
--- a/java/com/android/dialer/contactactions/IntentModule.java
+++ b/java/com/android/dialer/contactactions/IntentModule.java
@@ -24,6 +24,7 @@
 import android.telecom.PhoneAccountHandle;
 import com.android.dialer.callintent.CallInitiationType.Type;
 import com.android.dialer.callintent.CallIntentBuilder;
+import com.android.dialer.precall.PreCall;
 
 /**
  * {@link ContactActionModule} useful for making easy to build modules based on starting an intent.
@@ -66,9 +67,10 @@
     // TODO(zachh): Support post-dial digits; consider using DialerPhoneNumber.
     return new IntentModule(
         context,
-        new CallIntentBuilder(number, initiationType)
-            .setPhoneAccountHandle(phoneAccountHandle)
-            .build(),
+        PreCall.getIntent(
+            context,
+            new CallIntentBuilder(number, initiationType)
+                .setPhoneAccountHandle(phoneAccountHandle)),
         R.string.call,
         R.drawable.quantum_ic_call_white_24);
   }
@@ -81,10 +83,11 @@
     // TODO(zachh): Support post-dial digits; consider using DialerPhoneNumber.
     return new IntentModule(
         context,
-        new CallIntentBuilder(number, initiationType)
-            .setPhoneAccountHandle(phoneAccountHandle)
-            .setIsVideoCall(true)
-            .build(),
+        PreCall.getIntent(
+            context,
+            new CallIntentBuilder(number, initiationType)
+                .setPhoneAccountHandle(phoneAccountHandle)
+                .setIsVideoCall(true)),
         R.string.video_call,
         R.drawable.quantum_ic_videocam_white_24);
   }
diff --git a/java/com/android/dialer/dialpadview/DialpadFragment.java b/java/com/android/dialer/dialpadview/DialpadFragment.java
index 659d120..e85b57e 100644
--- a/java/com/android/dialer/dialpadview/DialpadFragment.java
+++ b/java/com/android/dialer/dialpadview/DialpadFragment.java
@@ -83,10 +83,10 @@
 import com.android.dialer.logging.UiAction;
 import com.android.dialer.oem.MotorolaUtils;
 import com.android.dialer.performancereport.PerformanceReport;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.proguard.UsedByReflection;
 import com.android.dialer.telecom.TelecomUtil;
 import com.android.dialer.util.CallUtil;
-import com.android.dialer.util.DialerUtils;
 import com.android.dialer.util.PermissionsUtil;
 import com.android.dialer.widget.FloatingActionButtonController;
 import java.util.HashSet;
@@ -997,9 +997,8 @@
   }
 
   public void callVoicemail() {
-    DialerUtils.startActivityWithErrorToast(
-        getActivity(),
-        CallIntentBuilder.forVoicemail(null, CallInitiationType.Type.DIALPAD).build());
+    PreCall.start(
+        getContext(), CallIntentBuilder.forVoicemail(null, CallInitiationType.Type.DIALPAD));
     hideAndClearDialpad();
   }
 
@@ -1049,9 +1048,7 @@
         // Clear the digits just in case.
         clearDialpad();
       } else {
-        final Intent intent =
-            new CallIntentBuilder(number, CallInitiationType.Type.DIALPAD).build();
-        DialerUtils.startActivityWithErrorToast(getActivity(), intent);
+        PreCall.start(getContext(), new CallIntentBuilder(number, CallInitiationType.Type.DIALPAD));
         hideAndClearDialpad();
       }
     }
diff --git a/java/com/android/dialer/interactions/PhoneNumberInteraction.java b/java/com/android/dialer/interactions/PhoneNumberInteraction.java
index 255f6c3..15c6ce8 100644
--- a/java/com/android/dialer/interactions/PhoneNumberInteraction.java
+++ b/java/com/android/dialer/interactions/PhoneNumberInteraction.java
@@ -60,6 +60,7 @@
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.logging.InteractionEvent;
 import com.android.dialer.logging.Logger;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.util.DialerUtils;
 import com.android.dialer.util.PermissionsUtil;
 import com.android.dialer.util.TransactionSafeActivity;
@@ -183,10 +184,11 @@
         break;
       default:
         intent =
-            new CallIntentBuilder(phoneNumber, callSpecificAppData)
-                .setIsVideoCall(isVideoCall)
-                .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing())
-                .build();
+            PreCall.getIntent(
+                context,
+                new CallIntentBuilder(phoneNumber, callSpecificAppData)
+                    .setIsVideoCall(isVideoCall)
+                    .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing()));
         break;
     }
     DialerUtils.startActivityWithErrorToast(context, intent);
@@ -224,7 +226,7 @@
     // crash when the user tries to use such a shortcut, check for this condition and ask the user
     // for the permission.
     if (!PermissionsUtil.hasPhonePermissions(mContext)) {
-      LogUtil.i("PhoneNumberInteraction.startInteraction", "Need phone permissions: CALL_PHONE");
+      LogUtil.i("PhoneNumberInteraction.startInteraction", "Need phone permission: CALL_PHONE");
       ActivityCompat.requestPermissions(
           (Activity) mContext, new String[] {permission.CALL_PHONE}, REQUEST_CALL_PHONE);
       return;
diff --git a/java/com/android/dialer/precall/PreCall.java b/java/com/android/dialer/precall/PreCall.java
index 93fd8e9..4f021f1 100644
--- a/java/com/android/dialer/precall/PreCall.java
+++ b/java/com/android/dialer/precall/PreCall.java
@@ -21,6 +21,7 @@
 import android.support.annotation.MainThread;
 import android.support.annotation.NonNull;
 import com.android.dialer.callintent.CallIntentBuilder;
+import com.android.dialer.util.DialerUtils;
 import com.google.common.collect.ImmutableList;
 
 /** Interface to prepare a {@link CallIntentBuilder} before placing the call with telecom. */
@@ -41,4 +42,12 @@
   @NonNull
   @MainThread
   Intent buildIntent(Context context, CallIntentBuilder builder);
+
+  static Intent getIntent(Context context, CallIntentBuilder builder) {
+    return PreCallComponent.get(context).getPreCall().buildIntent(context, builder);
+  }
+
+  static void start(Context context, CallIntentBuilder builder) {
+    DialerUtils.startActivityWithErrorToast(context, getIntent(context, builder));
+  }
 }
diff --git a/java/com/android/dialer/precall/PreCallCoordinator.java b/java/com/android/dialer/precall/PreCallCoordinator.java
index b5e9e85..40b909a 100644
--- a/java/com/android/dialer/precall/PreCallCoordinator.java
+++ b/java/com/android/dialer/precall/PreCallCoordinator.java
@@ -19,6 +19,7 @@
 import android.app.Activity;
 import android.support.annotation.MainThread;
 import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
 import com.android.dialer.callintent.CallIntentBuilder;
 
 /**
@@ -27,6 +28,8 @@
  */
 public interface PreCallCoordinator {
 
+  @VisibleForTesting public String EXTRA_CALL_INTENT_BUILDER = "extra_call_intent_builder";
+
   @NonNull
   CallIntentBuilder getBuilder();
 
diff --git a/java/com/android/dialer/precall/impl/AssistedDialAction.java b/java/com/android/dialer/precall/impl/AssistedDialAction.java
new file mode 100644
index 0000000..edf97cc
--- /dev/null
+++ b/java/com/android/dialer/precall/impl/AssistedDialAction.java
@@ -0,0 +1,73 @@
+/*
+ * 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
+ */
+
+package com.android.dialer.precall.impl;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.os.Bundle;
+import android.telecom.PhoneAccount;
+import android.telephony.TelephonyManager;
+import com.android.dialer.assisteddialing.AssistedDialingMediator;
+import com.android.dialer.assisteddialing.ConcreteCreator;
+import com.android.dialer.assisteddialing.TransformationInfo;
+import com.android.dialer.callintent.CallIntentBuilder;
+import com.android.dialer.common.Assert;
+import com.android.dialer.compat.telephony.TelephonyManagerCompat;
+import com.android.dialer.precall.PreCallAction;
+import com.android.dialer.precall.PreCallCoordinator;
+import com.android.dialer.util.CallUtil;
+import java.util.Optional;
+
+/** Rewrites the call URI with country code. TODO(erfanian): use phone account for multi SIM */
+public class AssistedDialAction implements PreCallAction {
+
+  @SuppressWarnings("AndroidApiChecker") // Use of optional
+  @TargetApi(Build.VERSION_CODES.N)
+  @Override
+  public void run(PreCallCoordinator coordinator) {
+    CallIntentBuilder builder = coordinator.getBuilder();
+    if (!builder.isAssistedDialAllowed()) {
+      return;
+    }
+    AssistedDialingMediator assistedDialingMediator =
+        ConcreteCreator.createNewAssistedDialingMediator(
+            coordinator.getActivity().getSystemService(TelephonyManager.class),
+            coordinator.getActivity());
+    if (!assistedDialingMediator.isPlatformEligible()) {
+      return;
+    }
+    builder.getOutgoingCallExtras().putBoolean(TelephonyManagerCompat.ALLOW_ASSISTED_DIAL, true);
+    String phoneNumber =
+        builder.getUri().getScheme().equals(PhoneAccount.SCHEME_TEL)
+            ? builder.getUri().getSchemeSpecificPart()
+            : "";
+    Optional<TransformationInfo> transformedNumber =
+        assistedDialingMediator.attemptAssistedDial(phoneNumber);
+    if (transformedNumber.isPresent()) {
+      Bundle assistedDialingExtras = transformedNumber.get().toBundle();
+      builder.getOutgoingCallExtras().putBoolean(TelephonyManagerCompat.IS_ASSISTED_DIALED, true);
+      builder
+          .getOutgoingCallExtras()
+          .putBundle(TelephonyManagerCompat.ASSISTED_DIALING_EXTRAS, assistedDialingExtras);
+      builder.setUri(
+          CallUtil.getCallUri(Assert.isNotNull(transformedNumber.get().transformedNumber())));
+    }
+  }
+
+  @Override
+  public void onDiscard() {}
+}
diff --git a/java/com/android/dialer/precall/impl/CallingAccountSelector.java b/java/com/android/dialer/precall/impl/CallingAccountSelector.java
new file mode 100644
index 0000000..ca8798c
--- /dev/null
+++ b/java/com/android/dialer/precall/impl/CallingAccountSelector.java
@@ -0,0 +1,114 @@
+/*
+ * 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
+ */
+
+package com.android.dialer.precall.impl;
+
+import android.app.Activity;
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment;
+import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.SelectPhoneAccountListener;
+import com.android.dialer.callintent.CallIntentBuilder;
+import com.android.dialer.common.Assert;
+import com.android.dialer.precall.PreCallAction;
+import com.android.dialer.precall.PreCallCoordinator;
+import java.util.List;
+
+/** PreCallAction to select which phone account to call with. Ignored if there's only one account */
+@SuppressWarnings("MissingPermission")
+public class CallingAccountSelector implements PreCallAction {
+
+  @VisibleForTesting static final String TAG_CALLING_ACCOUNT_SELECTOR = "CallingAccountSelector";
+
+  private SelectPhoneAccountDialogFragment selectPhoneAccountDialogFragment;
+
+  private boolean isDiscarding;
+
+  @Override
+  public void run(PreCallCoordinator coordinator) {
+    CallIntentBuilder builder = coordinator.getBuilder();
+    if (builder.getPhoneAccountHandle() != null) {
+      return;
+    }
+    Activity activity = coordinator.getActivity();
+    TelecomManager telecomManager = activity.getSystemService(TelecomManager.class);
+    List<PhoneAccountHandle> accounts = telecomManager.getCallCapablePhoneAccounts();
+    if (accounts.size() <= 1) {
+      return;
+    }
+    boolean isVoicemail = builder.getUri().getScheme().equals(PhoneAccount.SCHEME_VOICEMAIL);
+
+    if (!isVoicemail) {
+      PhoneAccountHandle defaultPhoneAccount =
+          telecomManager.getDefaultOutgoingPhoneAccount(builder.getUri().getScheme());
+      if (defaultPhoneAccount != null) {
+        builder.setPhoneAccountHandle(defaultPhoneAccount);
+        return;
+      }
+    }
+
+    selectPhoneAccountDialogFragment =
+        SelectPhoneAccountDialogFragment.newInstance(
+            R.string.pre_call_select_phone_account,
+            false /* canSetDefault */, // TODO(twyen): per contact defaults
+            accounts,
+            new SelectedListener(coordinator, coordinator.startPendingAction()),
+            null /* call ID */);
+    selectPhoneAccountDialogFragment.show(
+        activity.getFragmentManager(), TAG_CALLING_ACCOUNT_SELECTOR);
+  }
+
+  @Override
+  public void onDiscard() {
+    isDiscarding = true;
+    selectPhoneAccountDialogFragment.dismiss();
+  }
+
+  private class SelectedListener extends SelectPhoneAccountListener {
+
+    private final PreCallCoordinator coordinator;
+    private final PreCallCoordinator.PendingAction listener;
+
+    public SelectedListener(
+        @NonNull PreCallCoordinator builder, @NonNull PreCallCoordinator.PendingAction listener) {
+      this.coordinator = Assert.isNotNull(builder);
+      this.listener = Assert.isNotNull(listener);
+    }
+
+    @MainThread
+    @Override
+    public void onPhoneAccountSelected(
+        PhoneAccountHandle selectedAccountHandle, boolean setDefault, @Nullable String callId) {
+      coordinator.getBuilder().setPhoneAccountHandle(selectedAccountHandle);
+      listener.finish();
+    }
+
+    @MainThread
+    @Override
+    public void onDialogDismissed(@Nullable String callId) {
+      if (isDiscarding) {
+        return;
+      }
+      coordinator.abortCall();
+      listener.finish();
+    }
+  }
+}
diff --git a/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java b/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java
index 25083ef..6302a23 100644
--- a/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java
+++ b/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java
@@ -38,8 +38,6 @@
 
   private static final String SAVED_STATE_CURRENT_ACTION = "current_action";
 
-  static final String EXTRA_CALL_INTENT_BUILDER = "extra_call_intent_builder";
-
   @NonNull private final Activity activity;
 
   private CallIntentBuilder builder;
diff --git a/java/com/android/dialer/precall/impl/PreCallImpl.java b/java/com/android/dialer/precall/impl/PreCallImpl.java
index ac9750e..21c5dc9 100644
--- a/java/com/android/dialer/precall/impl/PreCallImpl.java
+++ b/java/com/android/dialer/precall/impl/PreCallImpl.java
@@ -22,6 +22,7 @@
 import com.android.dialer.callintent.CallIntentBuilder;
 import com.android.dialer.precall.PreCall;
 import com.android.dialer.precall.PreCallAction;
+import com.android.dialer.precall.PreCallCoordinator;
 import com.google.common.collect.ImmutableList;
 import javax.inject.Inject;
 
@@ -33,14 +34,14 @@
 
   @Override
   public ImmutableList<PreCallAction> getActions() {
-    return ImmutableList.of();
+    return ImmutableList.of(new CallingAccountSelector(), new AssistedDialAction());
   }
 
   @NonNull
   @Override
   public Intent buildIntent(Context context, CallIntentBuilder builder) {
     Intent intent = new Intent(context, PreCallActivity.class);
-    intent.putExtra(PreCallCoordinatorImpl.EXTRA_CALL_INTENT_BUILDER, builder);
+    intent.putExtra(PreCallCoordinator.EXTRA_CALL_INTENT_BUILDER, builder);
     return intent;
   }
 }
diff --git a/java/com/android/dialer/precall/impl/res/values/strings.xml b/java/com/android/dialer/precall/impl/res/values/strings.xml
new file mode 100644
index 0000000..8943946
--- /dev/null
+++ b/java/com/android/dialer/precall/impl/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?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>
+  <!-- Title of the dialog to select which SIM to call with before making a call, if the device has
+  multiple SIMs [CHAR LIMIT=40]-->
+  <string name="pre_call_select_phone_account">Call with</string>
+
+</resources>
\ No newline at end of file
diff --git a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java
index c0a6700..e797a03 100644
--- a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java
+++ b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java
@@ -58,6 +58,7 @@
 import com.android.dialer.enrichedcall.EnrichedCallManager.CapabilitiesListener;
 import com.android.dialer.logging.DialerImpression;
 import com.android.dialer.logging.Logger;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.searchfragment.common.RowClickListener;
 import com.android.dialer.searchfragment.common.SearchCursor;
 import com.android.dialer.searchfragment.cp2.SearchContactsCursorLoader;
@@ -483,12 +484,11 @@
             .setCharactersInSearchString(query == null ? 0 : query.length())
             .setAllowAssistedDialing(allowAssistedDial)
             .build();
-    Intent intent =
+    PreCall.start(
+        getContext(),
         new CallIntentBuilder(phoneNumber, callSpecificAppData)
             .setIsVideoCall(isVideoCall)
-            .setAllowAssistedDial(allowAssistedDial)
-            .build();
-    DialerUtils.startActivityWithErrorToast(getActivity(), intent);
+            .setAllowAssistedDial(allowAssistedDial));
     FragmentUtils.getParentUnsafe(this, SearchFragmentListener.class).onCallPlaced();
   }
 
diff --git a/java/com/android/dialer/searchfragment/list/SearchActionViewHolder.java b/java/com/android/dialer/searchfragment/list/SearchActionViewHolder.java
index 62e5c72..b557a82 100644
--- a/java/com/android/dialer/searchfragment/list/SearchActionViewHolder.java
+++ b/java/com/android/dialer/searchfragment/list/SearchActionViewHolder.java
@@ -31,6 +31,7 @@
 import com.android.dialer.common.Assert;
 import com.android.dialer.logging.DialerImpression;
 import com.android.dialer.logging.Logger;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.util.DialerUtils;
 import com.android.dialer.util.IntentUtil;
 import java.lang.annotation.Retention;
@@ -128,8 +129,8 @@
                 .setPositionOfSelectedSearchResult(position)
                 .setCharactersInSearchString(query.length())
                 .build();
-        intent = new CallIntentBuilder(query, callSpecificAppData).setIsVideoCall(true).build();
-        DialerUtils.startActivityWithErrorToast(context, intent);
+        PreCall.start(
+            context, new CallIntentBuilder(query, callSpecificAppData).setIsVideoCall(true));
         break;
 
       case Action.SEND_SMS:
diff --git a/java/com/android/dialer/searchfragment/list/SearchAdapter.java b/java/com/android/dialer/searchfragment/list/SearchAdapter.java
index dc78953..cc090ac 100644
--- a/java/com/android/dialer/searchfragment/list/SearchAdapter.java
+++ b/java/com/android/dialer/searchfragment/list/SearchAdapter.java
@@ -17,6 +17,7 @@
 package com.android.dialer.searchfragment.list;
 
 import android.content.Context;
+import android.database.Cursor;
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.RecyclerView.ViewHolder;
@@ -26,12 +27,15 @@
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import com.android.dialer.common.Assert;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.searchfragment.common.Projections;
 import com.android.dialer.searchfragment.common.RowClickListener;
 import com.android.dialer.searchfragment.common.SearchCursor;
 import com.android.dialer.searchfragment.cp2.SearchContactViewHolder;
 import com.android.dialer.searchfragment.list.SearchCursorManager.RowType;
 import com.android.dialer.searchfragment.nearbyplaces.NearbyPlaceViewHolder;
 import com.android.dialer.searchfragment.remote.RemoteContactViewHolder;
+import com.android.dialer.searchfragment.remote.RemoteDirectoriesCursorLoader;
 import java.util.List;
 
 /** RecyclerView adapter for {@link NewSearchFragment}. */
@@ -99,6 +103,23 @@
     } else if (holder instanceof NearbyPlaceViewHolder) {
       ((NearbyPlaceViewHolder) holder).bind(searchCursorManager.getCursor(position), query);
     } else if (holder instanceof RemoteContactViewHolder) {
+      Cursor cursor = searchCursorManager.getCursor(position);
+      // Temporary logging to identify cause of a bug:
+      if (cursor.getString(Projections.PHONE_NUMBER) == null) {
+        LogUtil.e(
+            "SearchAdapter.onBindViewHolder", "cursor class: %s", cursor.getClass().getName());
+        LogUtil.e("SearchAdapter.onBindViewHolder", "position: %d", position);
+        LogUtil.e(
+            "SearchAdapter.onBindViewHolder",
+            "query length: %s",
+            query == null ? "null" : query.length());
+        logDirectories();
+        LogUtil.e(
+            "SearchAdapter.onBindViewHolder",
+            "directory id: %d",
+            ((SearchCursor) cursor).getDirectoryId());
+        throw new IllegalStateException("Null phone number reading remote contact");
+      }
       ((RemoteContactViewHolder) holder).bind(searchCursorManager.getCursor(position), query);
     } else if (holder instanceof HeaderViewHolder) {
       String header =
@@ -114,6 +135,21 @@
     }
   }
 
+  private void logDirectories() {
+    try (Cursor directories = new RemoteDirectoriesCursorLoader(context).loadInBackground()) {
+      if (directories.moveToFirst()) {
+        do {
+          LogUtil.e(
+              "SearchAdapter.logDirectories",
+              "directory: %s",
+              RemoteDirectoriesCursorLoader.readDirectory(directories));
+        } while (directories.moveToNext());
+      } else {
+        LogUtil.e("SearchAdapter.logDirectories", "no directories found");
+      }
+    }
+  }
+
   public void setContactsCursor(SearchCursor cursor) {
     if (searchCursorManager.setContactsCursor(cursor)) {
       // Since this is a new contacts cursor, we need to reapply the filter.
diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java b/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java
index 2e1fd5e..f15b236 100644
--- a/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java
+++ b/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java
@@ -29,11 +29,11 @@
 import com.android.dialer.callintent.CallIntentBuilder;
 import com.android.dialer.contactphoto.ContactPhotoManager;
 import com.android.dialer.lettertile.LetterTileDrawable;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.searchfragment.common.Projections;
 import com.android.dialer.searchfragment.common.QueryBoldingUtil;
 import com.android.dialer.searchfragment.common.R;
 import com.android.dialer.searchfragment.common.SearchCursor;
-import com.android.dialer.telecom.TelecomUtil;
 
 /** ViewHolder for a nearby place row. */
 public final class NearbyPlaceViewHolder extends RecyclerView.ViewHolder
@@ -93,7 +93,6 @@
 
   @Override
   public void onClick(View v) {
-    TelecomUtil.placeCall(
-        context, new CallIntentBuilder(number, CallInitiationType.Type.REGULAR_SEARCH).build());
+    PreCall.start(context, new CallIntentBuilder(number, CallInitiationType.Type.REGULAR_SEARCH));
   }
 }
diff --git a/java/com/android/dialer/searchfragment/remote/RemoteContactViewHolder.java b/java/com/android/dialer/searchfragment/remote/RemoteContactViewHolder.java
index 339855f..9d36900 100644
--- a/java/com/android/dialer/searchfragment/remote/RemoteContactViewHolder.java
+++ b/java/com/android/dialer/searchfragment/remote/RemoteContactViewHolder.java
@@ -32,11 +32,11 @@
 import com.android.dialer.callintent.CallIntentBuilder;
 import com.android.dialer.contactphoto.ContactPhotoManager;
 import com.android.dialer.lettertile.LetterTileDrawable;
+import com.android.dialer.precall.PreCall;
 import com.android.dialer.searchfragment.common.Projections;
 import com.android.dialer.searchfragment.common.QueryBoldingUtil;
 import com.android.dialer.searchfragment.common.R;
 import com.android.dialer.searchfragment.common.SearchCursor;
-import com.android.dialer.telecom.TelecomUtil;
 
 /** ViewHolder for a nearby place row. */
 public final class RemoteContactViewHolder extends RecyclerView.ViewHolder
@@ -132,7 +132,6 @@
 
   @Override
   public void onClick(View v) {
-    TelecomUtil.placeCall(
-        context, new CallIntentBuilder(number, CallInitiationType.Type.REGULAR_SEARCH).build());
+    PreCall.start(context, new CallIntentBuilder(number, CallInitiationType.Type.REGULAR_SEARCH));
   }
 }
diff --git a/java/com/android/dialer/searchfragment/remote/RemoteDirectoriesCursorLoader.java b/java/com/android/dialer/searchfragment/remote/RemoteDirectoriesCursorLoader.java
index de71025..3d16c43 100644
--- a/java/com/android/dialer/searchfragment/remote/RemoteDirectoriesCursorLoader.java
+++ b/java/com/android/dialer/searchfragment/remote/RemoteDirectoriesCursorLoader.java
@@ -36,12 +36,14 @@
 
   private static final int DISPLAY_NAME = 1;
   private static final int PHOTO_SUPPORT = 2;
+  private static final int AUTHORITY = 3;
 
   @VisibleForTesting
   static final String[] PROJECTION = {
     ContactsContract.Directory._ID,
     ContactsContract.Directory.DISPLAY_NAME,
     ContactsContract.Directory.PHOTO_SUPPORT,
+    ContactsContract.Directory.DIRECTORY_AUTHORITY,
   };
 
   public RemoteDirectoriesCursorLoader(Context context) {
@@ -51,7 +53,10 @@
   /** @return current cursor row represented as a {@link Directory}. */
   public static Directory readDirectory(Cursor cursor) {
     return Directory.create(
-        cursor.getInt(ID), cursor.getString(DISPLAY_NAME), cursor.getInt(PHOTO_SUPPORT) != 0);
+        cursor.getInt(ID),
+        cursor.getString(DISPLAY_NAME),
+        cursor.getInt(PHOTO_SUPPORT) != 0,
+        cursor.getString(AUTHORITY));
   }
 
   private static Uri getContentUri() {
@@ -63,8 +68,14 @@
   /** POJO representing the results returned from {@link RemoteDirectoriesCursorLoader}. */
   @AutoValue
   public abstract static class Directory {
+    public static Directory create(
+        int id, @Nullable String displayName, boolean supportsPhotos, @Nullable String authority) {
+      return new AutoValue_RemoteDirectoriesCursorLoader_Directory(
+          id, displayName, supportsPhotos, authority);
+    }
+
     public static Directory create(int id, @Nullable String displayName, boolean supportsPhotos) {
-      return new AutoValue_RemoteDirectoriesCursorLoader_Directory(id, displayName, supportsPhotos);
+      return create(id, displayName, supportsPhotos, null);
     }
 
     public abstract int getId();
@@ -73,5 +84,7 @@
     abstract @Nullable String getDisplayName();
 
     abstract boolean supportsPhotos();
+
+    abstract @Nullable String authority();
   }
 }
diff --git a/java/com/android/incallui/disconnectdialog/VideoCallNotAvailablePrompt.java b/java/com/android/incallui/disconnectdialog/VideoCallNotAvailablePrompt.java
index 526d45e..099450a 100644
--- a/java/com/android/incallui/disconnectdialog/VideoCallNotAvailablePrompt.java
+++ b/java/com/android/incallui/disconnectdialog/VideoCallNotAvailablePrompt.java
@@ -19,7 +19,6 @@
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.Context;
-import android.content.Intent;
 import android.support.annotation.NonNull;
 import android.telecom.DisconnectCause;
 import android.telecom.PhoneAccountHandle;
@@ -28,7 +27,7 @@
 import com.android.dialer.callintent.CallInitiationType;
 import com.android.dialer.callintent.CallIntentBuilder;
 import com.android.dialer.common.LogUtil;
-import com.android.dialer.util.DialerUtils;
+import com.android.dialer.precall.PreCall;
 import com.android.incallui.call.DialerCall;
 
 /** Prompt user to make voice call if video call is not currently available. */
@@ -67,10 +66,9 @@
 
   private void makeVoiceCall(Context context, String number, PhoneAccountHandle accountHandle) {
     LogUtil.enterBlock("VideoCallNotAvailablePrompt.makeVoiceCall");
-    Intent intent =
+    PreCall.start(
+        context,
         new CallIntentBuilder(number, CallInitiationType.Type.IMS_VIDEO_BLOCKED_FALLBACK_TO_VOICE)
-            .setPhoneAccountHandle(accountHandle)
-            .build();
-    DialerUtils.startActivityWithErrorToast(context, intent);
+            .setPhoneAccountHandle(accountHandle));
   }
 }
diff --git a/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java b/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java
index 2f8dc7a..3608c36 100644
--- a/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java
+++ b/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java
@@ -28,6 +28,7 @@
 import android.telephony.VisualVoicemailSms;
 import com.android.dialer.callintent.CallInitiationType;
 import com.android.dialer.callintent.CallIntentBuilder;
+import com.android.dialer.precall.PreCall;
 import com.android.voicemail.VoicemailClient;
 import com.android.voicemail.impl.OmtpConstants;
 import com.android.voicemail.impl.OmtpVvmCarrierConfigHelper;
@@ -94,9 +95,10 @@
           PendingIntent.getActivity(
               context,
               CALL_VOICEMAIL_REQUEST_CODE,
-              CallIntentBuilder.forVoicemail(
-                      phoneAccountHandle, CallInitiationType.Type.LEGACY_VOICEMAIL_NOTIFICATION)
-                  .build(),
+              PreCall.getIntent(
+                  context,
+                  CallIntentBuilder.forVoicemail(
+                      phoneAccountHandle, CallInitiationType.Type.LEGACY_VOICEMAIL_NOTIFICATION)),
               PendingIntent.FLAG_UPDATE_CURRENT);
     } else {
       Intent launchVoicemailSettingsIntent =