Import translations. DO NOT MERGE
am: 585d0b1e3b  -s ours

* commit '585d0b1e3b20e4ba0fdf36bdd76e5a810c50601c':
  Import translations. DO NOT MERGE
diff --git a/src/com/android/dialer/CallDetailActivity.java b/src/com/android/dialer/CallDetailActivity.java
index 88d3fe2..c045967 100644
--- a/src/com/android/dialer/CallDetailActivity.java
+++ b/src/com/android/dialer/CallDetailActivity.java
@@ -43,6 +43,7 @@
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
 import com.android.contacts.common.GeoUtil;
+import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.interactions.TouchPointManager;
 import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.contacts.common.testing.NeededForTesting;
@@ -109,11 +110,19 @@
             // All calls are from the same number and same contact, so pick the first detail.
             mDetails = details[0];
             mNumber = TextUtils.isEmpty(mDetails.number) ? null : mDetails.number.toString();
+            mPostDialDigits = TextUtils.isEmpty(mDetails.postDialDigits)
+                    ? "" : mDetails.postDialDigits;
             mDisplayNumber = mDetails.displayNumber;
 
             final CharSequence callLocationOrType = getNumberTypeOrLocation(mDetails);
 
-            final CharSequence displayNumber = mDetails.displayNumber;
+            final CharSequence displayNumber;
+            if (!TextUtils.isEmpty(mDetails.postDialDigits)) {
+                displayNumber = mDetails.number + mDetails.postDialDigits;
+            } else {
+                displayNumber = mDetails.displayNumber;
+            }
+
             final String displayNumberStr = mBidiFormatter.unicodeWrap(
                     displayNumber.toString(), TextDirectionHeuristics.LTR);
 
@@ -199,6 +208,7 @@
     private PhoneCallDetails mDetails;
     protected String mNumber;
     private Uri mVoicemailUri;
+    private String mPostDialDigits = "";
     private String mDisplayNumber;
 
     private ListView mHistoryList;
@@ -240,7 +250,9 @@
 
         mQuickContactBadge = (QuickContactBadge) findViewById(R.id.quick_contact_photo);
         mQuickContactBadge.setOverlay(null);
-        mQuickContactBadge.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE);
+        if (CompatUtils.hasPrioritizedMimeType()) {
+            mQuickContactBadge.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE);
+        }
         mCallerName = (TextView) findViewById(R.id.caller_name);
         mCallerNumber = (TextView) findViewById(R.id.caller_number);
         mAccountLabel = (TextView) findViewById(R.id.phone_account_label);
@@ -254,7 +266,7 @@
                     return;
                 }
                 mContext.startActivity(
-                        new CallIntentBuilder(mNumber)
+                        new CallIntentBuilder(getDialableNumber())
                                 .setCallInitiationType(LogState.INITIATION_CALL_DETAILS)
                                 .build());
             }
@@ -372,7 +384,8 @@
                 ClipboardUtils.copyText(mContext, null, mNumber, true);
                 break;
             case R.id.call_detail_action_edit_before_call:
-                Intent dialIntent = new Intent(Intent.ACTION_DIAL, CallUtil.getCallUri(mNumber));
+                Intent dialIntent = new Intent(Intent.ACTION_DIAL,
+                        CallUtil.getCallUri(getDialableNumber()));
                 DialerUtils.startActivityWithErrorToast(mContext, dialIntent);
                 break;
             default:
@@ -468,6 +481,10 @@
         sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
     }
 
+    private String getDialableNumber() {
+        return mNumber + mPostDialDigits;
+    }
+
     @NeededForTesting
     public boolean hasVoicemail() {
         return mVoicemailUri != null;
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 6de1fdc..a6fb98c 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -787,7 +787,13 @@
             return;
         }
         if (clearDialpad) {
+            // Temporarily disable accessibility when we clear the dialpad, since it should be
+            // invisible and should not announce anything.
+            mDialpadFragment.getDigitsWidget().setImportantForAccessibility(
+                    View.IMPORTANT_FOR_ACCESSIBILITY_NO);
             mDialpadFragment.clearDialpad();
+            mDialpadFragment.getDigitsWidget().setImportantForAccessibility(
+                    View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
         }
         if (!mIsDialpadShown) {
             return;
diff --git a/src/com/android/dialer/PhoneCallDetails.java b/src/com/android/dialer/PhoneCallDetails.java
index fb1827d..71aa26d 100644
--- a/src/com/android/dialer/PhoneCallDetails.java
+++ b/src/com/android/dialer/PhoneCallDetails.java
@@ -31,6 +31,8 @@
 public class PhoneCallDetails {
     // The number of the other party involved in the call.
     public CharSequence number;
+    // Post-dial digits associated with the outgoing call.
+    public String postDialDigits;
     // The number presenting rules set by the network, e.g., {@link Calls#PRESENTATION_ALLOWED}
     public int numberPresentation;
     // The formatted version of {@link #number}.
@@ -114,16 +116,19 @@
             CharSequence number,
             int numberPresentation,
             CharSequence formattedNumber,
+            CharSequence postDialDigits,
             boolean isVoicemail) {
         this.number = number;
         this.numberPresentation = numberPresentation;
         this.formattedNumber = formattedNumber;
         this.isVoicemail = isVoicemail;
+        this.postDialDigits = postDialDigits.toString();
         this.displayNumber = PhoneNumberDisplayUtil.getDisplayNumber(
                 context,
                 this.number,
                 this.numberPresentation,
                 this.formattedNumber,
+                this.postDialDigits,
                 this.isVoicemail).toString();
     }
 
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 55e2fa0..ea2dbd2 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -441,6 +441,9 @@
         int count = getGroupSize(position);
 
         final String number = c.getString(CallLogQuery.NUMBER);
+        final String postDialDigits = PhoneNumberDisplayUtil.canShowPostDial()
+                ? c.getString(CallLogQuery.POST_DIAL_DIGITS) : "";
+
         final int numberPresentation = c.getInt(CallLogQuery.NUMBER_PRESENTATION);
         final PhoneAccountHandle accountHandle = PhoneAccountUtils.getAccount(
                 c.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME),
@@ -456,13 +459,15 @@
         ContactInfo info = ContactInfo.EMPTY;
         if (PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation) && !isVoicemailNumber) {
             // Lookup contacts with this number
-            info = mContactInfoCache.getValue(number, countryIso, cachedContactInfo);
+            info = mContactInfoCache.getValue(number + postDialDigits,
+                    countryIso, cachedContactInfo);
         }
         CharSequence formattedNumber = info.formattedNumber == null
                 ? null : PhoneNumberUtils.createTtsSpannable(info.formattedNumber);
 
         final PhoneCallDetails details = new PhoneCallDetails(
-                mContext, number, numberPresentation, formattedNumber, isVoicemailNumber);
+                mContext, number, numberPresentation, formattedNumber,
+                postDialDigits, isVoicemailNumber);
         details.accountHandle = accountHandle;
         details.callTypes = getCallTypes(c, count);
         details.countryIso = countryIso;
@@ -496,6 +501,7 @@
         views.rowId = c.getLong(CallLogQuery.ID);
         // Store values used when the actions ViewStub is inflated on expansion.
         views.number = number;
+        views.postDialDigits = details.postDialDigits;
         views.displayNumber = details.displayNumber;
         views.numberPresentation = numberPresentation;
         views.callType = c.getInt(CallLogQuery.CALL_TYPE);
diff --git a/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java b/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java
index 7771563..bb7bdbd 100644
--- a/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java
+++ b/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java
@@ -39,6 +39,9 @@
 
 import com.google.common.annotations.VisibleForTesting;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+
 public class CallLogAsyncTaskUtil {
     private static String TAG = CallLogAsyncTaskUtil.class.getSimpleName();
 
@@ -51,8 +54,9 @@
         GET_CALL_DETAILS,
     }
 
-    private static class CallDetailQuery {
-        static final String[] CALL_LOG_PROJECTION = new String[] {
+    private static final class CallDetailQuery {
+
+        private static final String[] CALL_LOG_PROJECTION_INTERNAL = new String[] {
             CallLog.Calls.DATE,
             CallLog.Calls.DURATION,
             CallLog.Calls.NUMBER,
@@ -66,6 +70,7 @@
             CallLog.Calls.DATA_USAGE,
             CallLog.Calls.TRANSCRIPTION
         };
+        public static final String[] CALL_LOG_PROJECTION;
 
         static final int DATE_COLUMN_INDEX = 0;
         static final int DURATION_COLUMN_INDEX = 1;
@@ -79,6 +84,17 @@
         static final int FEATURES = 9;
         static final int DATA_USAGE = 10;
         static final int TRANSCRIPTION_COLUMN_INDEX = 11;
+        static final int POST_DIAL_DIGITS = 12;
+
+        static {
+            ArrayList<String> projectionList = new ArrayList<>();
+            projectionList.addAll(Arrays.asList(CALL_LOG_PROJECTION_INTERNAL));
+            if (PhoneNumberDisplayUtil.canShowPostDial()) {
+                projectionList.add(AppCompatConstants.POST_DIAL_DIGITS);
+            }
+            projectionList.trimToSize();
+            CALL_LOG_PROJECTION = projectionList.toArray(new String[projectionList.size()]);
+        }
     }
 
     private static class CallLogDeleteBlockedCallQuery {
@@ -164,6 +180,8 @@
             // Read call log.
             final String countryIso = cursor.getString(CallDetailQuery.COUNTRY_ISO_COLUMN_INDEX);
             final String number = cursor.getString(CallDetailQuery.NUMBER_COLUMN_INDEX);
+            final String postDialDigits = PhoneNumberDisplayUtil.canShowPostDial()
+                    ? cursor.getString(CallDetailQuery.POST_DIAL_DIGITS) : "";
             final int numberPresentation =
                     cursor.getInt(CallDetailQuery.NUMBER_PRESENTATION_COLUMN_INDEX);
 
@@ -185,7 +203,8 @@
             }
 
             PhoneCallDetails details = new PhoneCallDetails(
-                    context, number, numberPresentation, info.formattedNumber, isVoicemail);
+                    context, number, numberPresentation, info.formattedNumber,
+                    postDialDigits, isVoicemail);
 
             details.accountHandle = accountHandle;
             details.contactUri = info.lookupUri;
diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java
index ab5bd43..fa6deaf 100644
--- a/src/com/android/dialer/calllog/CallLogFragment.java
+++ b/src/com/android/dialer/calllog/CallLogFragment.java
@@ -33,6 +33,7 @@
 import android.provider.CallLog.Calls;
 import android.provider.ContactsContract;
 import android.provider.VoicemailContract.Status;
+import android.support.v13.app.FragmentCompat;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
@@ -55,7 +56,8 @@
  * (all, missed or voicemails), specify it in the constructor.
  */
 public class CallLogFragment extends Fragment implements CallLogQueryHandler.Listener,
-        CallLogAdapter.CallFetcher, OnEmptyViewActionButtonClickedListener {
+        CallLogAdapter.CallFetcher, OnEmptyViewActionButtonClickedListener,
+        FragmentCompat.OnRequestPermissionsResultCallback {
     private static final String TAG = "CallLogFragment";
 
     /**
@@ -513,7 +515,8 @@
         }
 
         if (!PermissionsUtil.hasPermission(activity, READ_CALL_LOG)) {
-            requestPermissions(new String[] {READ_CALL_LOG}, READ_CALL_LOG_PERMISSION_REQUEST_CODE);
+          FragmentCompat.requestPermissions(this, new String[] {READ_CALL_LOG},
+              READ_CALL_LOG_PERMISSION_REQUEST_CODE);
         } else if (!mIsCallLogActivity) {
             // Show dialpad if we are not in the call log activity.
             ((HostInterface) activity).showDialpad();
diff --git a/src/com/android/dialer/calllog/CallLogGroupBuilder.java b/src/com/android/dialer/calllog/CallLogGroupBuilder.java
index 5eea096..194231b 100644
--- a/src/com/android/dialer/calllog/CallLogGroupBuilder.java
+++ b/src/com/android/dialer/calllog/CallLogGroupBuilder.java
@@ -17,7 +17,6 @@
 package com.android.dialer.calllog;
 
 import android.database.Cursor;
-import android.provider.CallLog.Calls;
 import android.telephony.PhoneNumberUtils;
 import android.text.format.Time;
 import android.text.TextUtils;
@@ -28,8 +27,6 @@
 
 import com.google.common.annotations.VisibleForTesting;
 
-import java.util.Objects;
-
 /**
  * Groups together calls in the call log.  The primary grouping attempts to group together calls
  * to and from the same number into a single row on the call log.
@@ -125,12 +122,15 @@
 
         // Instantiate the group values to those of the first call in the cursor.
         String groupNumber = cursor.getString(CallLogQuery.NUMBER);
+        String groupPostDialDigits = PhoneNumberDisplayUtil.canShowPostDial()
+                ? cursor.getString(CallLogQuery.POST_DIAL_DIGITS) : "";
         int groupCallType = cursor.getInt(CallLogQuery.CALL_TYPE);
         String groupAccountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
         String groupAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
         int groupSize = 1;
 
         String number;
+        String numberPostDialDigits;
         int callType;
         String accountComponentName;
         String accountId;
@@ -138,17 +138,21 @@
         while (cursor.moveToNext()) {
             // Obtain the values for the current call to group.
             number = cursor.getString(CallLogQuery.NUMBER);
+            numberPostDialDigits = PhoneNumberDisplayUtil.canShowPostDial()
+                    ? cursor.getString(CallLogQuery.POST_DIAL_DIGITS) : "";
             callType = cursor.getInt(CallLogQuery.CALL_TYPE);
             accountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
             accountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
 
             final boolean isSameNumber = equalNumbers(groupNumber, number);
+            final boolean isSamePostDialDigits = groupPostDialDigits.equals(numberPostDialDigits);
             final boolean isSameAccount = isSameAccount(
                     groupAccountComponentName, accountComponentName, groupAccountId, accountId);
 
             // Group with the same number and account. Never group voicemails. Only group blocked
             // calls with other blocked calls.
-            if (isSameNumber && isSameAccount && areBothNotVoicemail(callType, groupCallType)
+            if (isSameNumber && isSameAccount && isSamePostDialDigits
+                    && areBothNotVoicemail(callType, groupCallType)
                     && (areBothNotBlocked(callType, groupCallType)
                             || areBothBlocked(callType, groupCallType))) {
                 // Increment the size of the group to include the current call, but do not create
@@ -168,6 +172,7 @@
 
                 // Update the group values to those of the current call.
                 groupNumber = number;
+                groupPostDialDigits = numberPostDialDigits;
                 groupCallType = callType;
                 groupAccountComponentName = accountComponentName;
                 groupAccountId = accountId;
diff --git a/src/com/android/dialer/calllog/CallLogListItemHelper.java b/src/com/android/dialer/calllog/CallLogListItemHelper.java
index be0e146..fb2bab8 100644
--- a/src/com/android/dialer/calllog/CallLogListItemHelper.java
+++ b/src/com/android/dialer/calllog/CallLogListItemHelper.java
@@ -16,7 +16,6 @@
 
 package com.android.dialer.calllog;
 
-import android.content.Context;
 import android.content.res.Resources;
 import android.provider.CallLog.Calls;
 import android.text.SpannableStringBuilder;
@@ -263,7 +262,7 @@
         if (!TextUtils.isEmpty(details.getPreferredName())) {
             recipient = details.getPreferredName();
         } else {
-            recipient = details.displayNumber;
+            recipient = details.displayNumber + details.postDialDigits;
         }
         return recipient;
     }
diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
index 63fbe29..88af547 100644
--- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
+++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
@@ -43,6 +43,7 @@
 import com.android.contacts.common.ClipboardUtils;
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
+import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.dialog.CallSubjectDialog;
 import com.android.contacts.common.testing.NeededForTesting;
 import com.android.contacts.common.util.UriUtils;
@@ -114,6 +115,11 @@
     public String number;
 
     /**
+     * The post-dial numbers that are dialed following the phone number.
+     */
+    public String postDialDigits;
+
+    /**
      * The formatted phone number to display.
      */
     public String displayNumber;
@@ -235,8 +241,9 @@
         phoneCallDetailsViews.callLocationAndDate.setElegantTextHeight(false);
 
         quickContactView.setOverlay(null);
-        quickContactView.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE);
-
+        if (CompatUtils.hasPrioritizedMimeType()) {
+            quickContactView.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE);
+        }
         primaryActionButtonView.setOnClickListener(this);
         primaryActionView.setOnClickListener(mExpandCollapseListener);
         primaryActionView.setOnCreateContextMenuListener(this);
@@ -421,7 +428,7 @@
                             IntentProvider.getReturnVoicemailCallIntentProvider());
                 } else {
                     primaryActionButtonView.setTag(
-                            IntentProvider.getReturnCallIntentProvider(number));
+                            IntentProvider.getReturnCallIntentProvider(number + postDialDigits));
                 }
 
                 primaryActionButtonView.setContentDescription(TextUtils.expandTemplate(
@@ -601,7 +608,7 @@
                     info.lookupUri,
                     (String) nameOrNumber /* top line of contact view in call subject dialog */,
                     isBusiness,
-                    number, /* callable number used for ACTION_CALL intent */
+                    number,
                     TextUtils.isEmpty(info.name) ? null : displayNumber, /* second line of contact
                                                                            view in dialog. */
                     numberType, /* phone number type (e.g. mobile) in second line of contact view */
diff --git a/src/com/android/dialer/calllog/CallLogNotificationsService.java b/src/com/android/dialer/calllog/CallLogNotificationsService.java
index 9a67b61..d2a494d 100644
--- a/src/com/android/dialer/calllog/CallLogNotificationsService.java
+++ b/src/com/android/dialer/calllog/CallLogNotificationsService.java
@@ -67,12 +67,6 @@
     }
 
     @Override
-    public void onCreate() {
-        super.onCreate();
-        mVoicemailQueryHandler = new VoicemailQueryHandler(this, getContentResolver());
-    }
-
-    @Override
     protected void onHandleIntent(Intent intent) {
         if (intent == null) {
             Log.d(TAG, "onHandleIntent: could not handle null intent");
@@ -84,6 +78,9 @@
         }
 
         if (ACTION_MARK_NEW_VOICEMAILS_AS_OLD.equals(intent.getAction())) {
+            if (mVoicemailQueryHandler == null) {
+                mVoicemailQueryHandler = new VoicemailQueryHandler(this, getContentResolver());
+            }
             mVoicemailQueryHandler.markNewVoicemailsAsOld();
         } else if (ACTION_UPDATE_NOTIFICATIONS.equals(intent.getAction())) {
             Uri voicemailUri = (Uri) intent.getParcelableExtra(EXTRA_NEW_VOICEMAIL_URI);
diff --git a/src/com/android/dialer/calllog/CallLogQuery.java b/src/com/android/dialer/calllog/CallLogQuery.java
index 2b43c28..905a4b7 100644
--- a/src/com/android/dialer/calllog/CallLogQuery.java
+++ b/src/com/android/dialer/calllog/CallLogQuery.java
@@ -18,11 +18,19 @@
 
 import android.provider.CallLog.Calls;
 
+import com.android.dialer.compat.DialerCompatUtils;
+import com.android.dialer.util.AppCompatConstants;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
 /**
  * The query for the call log table.
  */
 public final class CallLogQuery {
-    public static final String[] _PROJECTION = new String[] {
+
+    private static final String[] _PROJECTION_INTERNAL = new String[] {
             Calls._ID,                          // 0
             Calls.NUMBER,                       // 1
             Calls.DATE,                         // 2
@@ -46,7 +54,6 @@
             Calls.FEATURES,                     // 20
             Calls.DATA_USAGE,                   // 21
             Calls.TRANSCRIPTION,                // 22
-            Calls.CACHED_PHOTO_URI              // 23
     };
 
     public static final int ID = 0;
@@ -72,5 +79,33 @@
     public static final int FEATURES = 20;
     public static final int DATA_USAGE = 21;
     public static final int TRANSCRIPTION = 22;
-    public static final int CACHED_PHOTO_URI = 23;
+
+    // Indices for columns that may not be available, depending on the Sdk Version
+    /**
+     * Only available in versions >= M
+     * Call {@link DialerCompatUtils#isCallsCachedPhotoUriCompatible()} prior to use
+     */
+    public static int CACHED_PHOTO_URI = -1;
+
+    /**
+     * Only available in versions > M
+     * Call {@link PhoneNumberDisplayUtil#canShowPostDial()} prior to use
+     */
+    public static int POST_DIAL_DIGITS = -1;
+
+    public static final String[] _PROJECTION;
+
+    static {
+        List<String> projectionList = Lists.newArrayList(_PROJECTION_INTERNAL);
+        if (DialerCompatUtils.isCallsCachedPhotoUriCompatible()) {
+            projectionList.add(Calls.CACHED_PHOTO_URI);
+            CACHED_PHOTO_URI = projectionList.size() - 1;
+        }
+        if (PhoneNumberDisplayUtil.canShowPostDial()) {
+            projectionList.add(AppCompatConstants.POST_DIAL_DIGITS);
+            POST_DIAL_DIGITS = projectionList.size() - 1;
+        }
+        _PROJECTION = projectionList.toArray(new String[projectionList.size()]);
+    }
+
 }
diff --git a/src/com/android/dialer/calllog/ContactInfoHelper.java b/src/com/android/dialer/calllog/ContactInfoHelper.java
index 2da6840..3e4f70f 100644
--- a/src/com/android/dialer/calllog/ContactInfoHelper.java
+++ b/src/com/android/dialer/calllog/ContactInfoHelper.java
@@ -33,6 +33,7 @@
 import com.android.contacts.common.util.PermissionsUtil;
 import com.android.contacts.common.util.PhoneNumberHelper;
 import com.android.contacts.common.util.UriUtils;
+import com.android.dialer.compat.DialerCompatUtils;
 import com.android.dialer.service.CachedNumberLookupService;
 import com.android.dialer.service.CachedNumberLookupService.CachedContactInfo;
 import com.android.dialer.util.TelecomUtil;
@@ -157,9 +158,14 @@
             return ContactInfo.EMPTY;
         }
 
-        Cursor phoneLookupCursor = mContext.getContentResolver().query(uri,
-                PhoneQuery.PHONE_LOOKUP_PROJECTION, null, null, null);
-
+        Cursor phoneLookupCursor = null;
+        try {
+            phoneLookupCursor = mContext.getContentResolver().query(uri,
+                    PhoneQuery.PHONE_LOOKUP_PROJECTION, null, null, null);
+        } catch (NullPointerException e) {
+            // Trap NPE from pre-N CP2
+            return null;
+        }
         if (phoneLookupCursor == null) {
             return null;
         }
@@ -330,7 +336,8 @@
 
             final Uri updatedPhotoUriContactsOnly =
                     UriUtils.nullForNonContactsUri(updatedInfo.photoUri);
-            if (!UriUtils.areEqual(updatedPhotoUriContactsOnly, callLogInfo.photoUri)) {
+            if (DialerCompatUtils.isCallsCachedPhotoUriCompatible() &&
+                    !UriUtils.areEqual(updatedPhotoUriContactsOnly, callLogInfo.photoUri)) {
                 values.put(Calls.CACHED_PHOTO_URI,
                         UriUtils.uriToString(updatedPhotoUriContactsOnly));
                 needsUpdate = true;
@@ -349,8 +356,10 @@
             values.put(Calls.CACHED_MATCHED_NUMBER, updatedInfo.number);
             values.put(Calls.CACHED_NORMALIZED_NUMBER, updatedInfo.normalizedNumber);
             values.put(Calls.CACHED_PHOTO_ID, updatedInfo.photoId);
-            values.put(Calls.CACHED_PHOTO_URI, UriUtils.uriToString(
-                    UriUtils.nullForNonContactsUri(updatedInfo.photoUri)));
+            if (DialerCompatUtils.isCallsCachedPhotoUriCompatible()) {
+                values.put(Calls.CACHED_PHOTO_URI, UriUtils.uriToString(
+                        UriUtils.nullForNonContactsUri(updatedInfo.photoUri)));
+            }
             values.put(Calls.CACHED_FORMATTED_NUMBER, updatedInfo.formattedNumber);
             needsUpdate = true;
         }
@@ -400,11 +409,17 @@
         info.type = c.getInt(CallLogQuery.CACHED_NUMBER_TYPE);
         info.label = c.getString(CallLogQuery.CACHED_NUMBER_LABEL);
         String matchedNumber = c.getString(CallLogQuery.CACHED_MATCHED_NUMBER);
-        info.number = matchedNumber == null ? c.getString(CallLogQuery.NUMBER) : matchedNumber;
+        String postDialDigits = PhoneNumberDisplayUtil.canShowPostDial()
+                ? c.getString(CallLogQuery.POST_DIAL_DIGITS) : "";
+        info.number = (matchedNumber == null) ?
+                c.getString(CallLogQuery.NUMBER) + postDialDigits : matchedNumber;
+
         info.normalizedNumber = c.getString(CallLogQuery.CACHED_NORMALIZED_NUMBER);
         info.photoId = c.getLong(CallLogQuery.CACHED_PHOTO_ID);
-        info.photoUri = UriUtils.nullForNonContactsUri(
-                UriUtils.parseUriOrNull(c.getString(CallLogQuery.CACHED_PHOTO_URI)));
+        info.photoUri = DialerCompatUtils.isCallsCachedPhotoUriCompatible() ?
+                UriUtils.nullForNonContactsUri(
+                        UriUtils.parseUriOrNull(c.getString(CallLogQuery.CACHED_PHOTO_URI)))
+                : null;
         info.formattedNumber = c.getString(CallLogQuery.CACHED_FORMATTED_NUMBER);
 
         return info;
diff --git a/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java b/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java
index 96dbf82..4d201b0 100644
--- a/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java
+++ b/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java
@@ -24,6 +24,7 @@
 import android.graphics.Typeface;
 import android.provider.CallLog.Calls;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.support.v4.content.ContextCompat;
 import android.telecom.PhoneAccount;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
@@ -152,9 +153,8 @@
         views.nameView.setTypeface(typeface);
         views.voicemailTranscriptionView.setTypeface(typeface);
         views.callLocationAndDate.setTypeface(typeface);
-        views.callLocationAndDate.setTextColor(mResources.getColor(
-                details.isRead ? R.color.call_log_detail_color : R.color.call_log_unread_text_color,
-                mContext.getTheme()));
+        views.callLocationAndDate.setTextColor(ContextCompat.getColor(mContext, details.isRead ?
+                R.color.call_log_detail_color : R.color.call_log_unread_text_color));
     }
 
     /**
diff --git a/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java b/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java
index 5030efd..91cd3e1 100644
--- a/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java
+++ b/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java
@@ -17,10 +17,9 @@
 package com.android.dialer.calllog;
 
 import android.content.Context;
-import android.content.res.Resources;
+import android.os.Build;
 import android.provider.CallLog.Calls;
 import android.text.TextUtils;
-import android.util.Log;
 
 import com.android.dialer.R;
 import com.android.dialer.util.PhoneNumberUtil;
@@ -67,6 +66,7 @@
             CharSequence number,
             int presentation,
             CharSequence formattedNumber,
+            CharSequence postDialDigits,
             boolean isVoicemail) {
         final CharSequence displayName = getDisplayName(context, number, presentation, isVoicemail);
         if (!TextUtils.isEmpty(displayName)) {
@@ -76,9 +76,18 @@
         if (!TextUtils.isEmpty(formattedNumber)) {
             return formattedNumber;
         } else if (!TextUtils.isEmpty(number)) {
-            return number;
+            return number.toString() + postDialDigits;
         } else {
             return "";
         }
     }
+
+    /**
+     * Returns whether we can expect the post-dial digits to be in the call log.
+     *
+     * These digits will be present in versions N+.
+     */
+    public static boolean canShowPostDial() {
+        return Build.VERSION.SDK_INT > Build.VERSION_CODES.M;
+    }
 }
diff --git a/src/com/android/dialer/compat/DialerCompatUtils.java b/src/com/android/dialer/compat/DialerCompatUtils.java
new file mode 100644
index 0000000..07a279a
--- /dev/null
+++ b/src/com/android/dialer/compat/DialerCompatUtils.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 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.compat;
+
+import android.os.Build;
+
+import com.android.contacts.common.compat.SdkVersionOverride;
+
+public final class DialerCompatUtils {
+    /**
+     * Determines if this version is compatible with video calling. Can also force the version to be
+     * lower through SdkVersionOverride.
+     *
+     * @return {@code true} if video calling is allowed, {@code false} otherwise.
+     */
+    public static boolean isVideoCompatible() {
+        return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.LOLLIPOP)
+                >= Build.VERSION_CODES.M;
+    }
+
+    /**
+     * Determines if this version is compatible with a default dialer. Can also force the version to
+     * be lower through SdkVersionOverride.
+     *
+     * @return {@code true} if default dialer is a feature on this device, {@code false} otherwise.
+     */
+    public static boolean isDefaultDialerCompatible() {
+        return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.LOLLIPOP)
+                >= Build.VERSION_CODES.M;
+    }
+
+    /**
+     * Determines if this version has access to the
+     * {@link android.provider.CallLog.Calls.CACHED_PHOTO_URI} column
+     *
+     * @return {@code true} if {@link android.provider.CallLog.Calls.CACHED_PHOTO_URI} is available,
+     * {@code false} otherwise
+     */
+    public static boolean isCallsCachedPhotoUriCompatible() {
+        return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M)
+                >= Build.VERSION_CODES.M;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/dialer/compat/SettingsCompat.java b/src/com/android/dialer/compat/SettingsCompat.java
new file mode 100644
index 0000000..474a600
--- /dev/null
+++ b/src/com/android/dialer/compat/SettingsCompat.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 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.compat;
+
+import android.content.Context;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
+import android.provider.Settings;
+
+import com.android.contacts.common.compat.SdkVersionOverride;
+
+/**
+ * Compatibility class for {@link android.provider.Settings}
+ */
+public class SettingsCompat {
+
+    public static class System {
+
+        /**
+         * Compatibility version of {@link android.provider.Settings.System#canWrite(Context)}
+         *
+         * Note: Since checking preferences at runtime started in M, this method always returns
+         * {@code true} for SDK versions prior to 23. In those versions, the app wouldn't be
+         * installed if it didn't have the proper permission
+         */
+        public static boolean canWrite(Context context) {
+            if (SdkVersionOverride.getSdkVersion(VERSION_CODES.LOLLIPOP) >= Build.VERSION_CODES.M) {
+                return Settings.System.canWrite(context);
+            }
+            return true;
+        }
+    }
+
+}
diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index 760b020..246b0d7 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -274,6 +274,11 @@
     }
 
     @Override
+    public Context getContext() {
+        return getActivity();
+    }
+
+    @Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
         mWasEmptyBeforeTextChange = TextUtils.isEmpty(s);
     }
diff --git a/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java b/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java
index 0f4bd74..de4fe99 100644
--- a/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java
+++ b/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java
@@ -123,6 +123,11 @@
     }
 
     @Override
+    public Context getContext() {
+        return getActivity();
+    }
+
+    @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         super.onCreateDialog(savedInstanceState);
         final boolean isBlocked = getArguments().containsKey(ARG_BLOCK_ID);
diff --git a/src/com/android/dialer/filterednumber/BlockedNumbersFragment.java b/src/com/android/dialer/filterednumber/BlockedNumbersFragment.java
index 881ec04..e231c6a 100644
--- a/src/com/android/dialer/filterednumber/BlockedNumbersFragment.java
+++ b/src/com/android/dialer/filterednumber/BlockedNumbersFragment.java
@@ -23,6 +23,7 @@
 import android.database.Cursor;
 import android.graphics.drawable.ColorDrawable;
 import android.os.Bundle;
+import android.support.v4.app.ActivityCompat;
 import android.support.v7.app.ActionBar;
 import android.support.v7.app.AppCompatActivity;
 import android.view.LayoutInflater;
@@ -51,6 +52,11 @@
     private View mBlockedNumberListDivider;
 
     @Override
+    public Context getContext() {
+        return getActivity();
+    }
+
+    @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
 
@@ -62,8 +68,8 @@
         ImageView addNumberIcon = (ImageView) getActivity().findViewById(R.id.add_number_icon);
         LetterTileDrawable drawable = new LetterTileDrawable(getResources());
         drawable.setLetter(ADD_BLOCKED_NUMBER_ICON_LETTER);
-        drawable.setColor(getResources().getColor(R.color.add_blocked_number_icon_color,
-                getActivity().getTheme()));
+        drawable.setColor(ActivityCompat.getColor(getActivity(),
+                R.color.add_blocked_number_icon_color));
         drawable.setIsCircular(true);
         addNumberIcon.setImageDrawable(drawable);
 
@@ -103,8 +109,8 @@
         super.onResume();
 
         ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
-        ColorDrawable backgroundDrawable =
-                new ColorDrawable(getActivity().getColor(R.color.dialer_theme_color));
+        ColorDrawable backgroundDrawable = new ColorDrawable(
+                ActivityCompat.getColor(getActivity(), R.color.dialer_theme_color));
         actionBar.setBackgroundDrawable(backgroundDrawable);
         actionBar.setDisplayShowCustomEnabled(false);
         actionBar.setDisplayHomeAsUpEnabled(true);
diff --git a/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java b/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java
index 23ce8a8..e3870de 100644
--- a/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java
+++ b/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java
@@ -31,10 +31,6 @@
 import android.text.TextUtils;
 import android.widget.Toast;
 
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
 import com.android.contacts.common.testing.NeededForTesting;
 import com.android.dialer.R;
 import com.android.dialer.database.FilteredNumberAsyncQueryHandler;
@@ -44,6 +40,8 @@
 import com.android.dialer.logging.InteractionEvent;
 import com.android.dialer.logging.Logger;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * Utility to help with tasks related to filtered numbers.
  */
@@ -53,11 +51,11 @@
     private static final long RECENT_EMERGENCY_CALL_THRESHOLD_MS = 1000 * 60 * 60 * 24 * 2;
 
     // Pref key for storing the time of end of the last emergency call in milliseconds after epoch.
-    private static final String LAST_EMERGENCY_CALL_MS_PREF_KEY = "last_emergency_call_ms";
+    protected static final String LAST_EMERGENCY_CALL_MS_PREF_KEY = "last_emergency_call_ms";
 
     // Pref key for storing whether a notification has been dispatched to notify the user that call
     // blocking has been disabled because of a recent emergency call.
-    private static final String NOTIFIED_CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_PREF_KEY =
+    protected static final String NOTIFIED_CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_PREF_KEY =
             "notified_call_blocking_disabled_by_emergency_call";
 
     public static final String CALL_BLOCKING_NOTIFICATION_TAG = "call_blocking";
@@ -241,6 +239,10 @@
             return false;
         }
 
+        if (hasRecentEmergencyCall(context)) {
+            return false;
+        }
+
         final Cursor cursor = context.getContentResolver().query(
                 FilteredNumber.CONTENT_URI,
                 new String[] {
diff --git a/src/com/android/dialer/filterednumber/NumbersAdapter.java b/src/com/android/dialer/filterednumber/NumbersAdapter.java
index 1706107..4e2e578 100644
--- a/src/com/android/dialer/filterednumber/NumbersAdapter.java
+++ b/src/com/android/dialer/filterednumber/NumbersAdapter.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.text.BidiFormatter;
 import android.text.TextDirectionHeuristics;
 import android.text.TextUtils;
@@ -30,6 +31,7 @@
 
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
+import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.util.UriUtils;
 import com.android.dialer.R;
 import com.android.dialer.calllog.ContactInfo;
@@ -63,9 +65,9 @@
         final QuickContactBadge quickContactBadge =
                 (QuickContactBadge) view.findViewById(R.id.quick_contact_photo);
         quickContactBadge.setOverlay(null);
-        quickContactBadge.setPrioritizedMimeType(
-                ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
-
+        if (CompatUtils.hasPrioritizedMimeType()) {
+            quickContactBadge.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE);
+        }
         final ContactInfo info = mContactInfoHelper.lookupNumber(number, countryIso);
         final CharSequence locationOrType = getNumberTypeOrLocation(info);
         final String displayNumber = getDisplayNumber(info);
diff --git a/src/com/android/dialer/filterednumber/ViewNumbersToImportFragment.java b/src/com/android/dialer/filterednumber/ViewNumbersToImportFragment.java
index 9912416..153d73c 100644
--- a/src/com/android/dialer/filterednumber/ViewNumbersToImportFragment.java
+++ b/src/com/android/dialer/filterednumber/ViewNumbersToImportFragment.java
@@ -44,6 +44,11 @@
     private ViewNumbersToImportAdapter mAdapter;
 
     @Override
+    public Context getContext() {
+        return getActivity();
+    }
+
+    @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
 
diff --git a/src/com/android/dialer/list/AllContactsFragment.java b/src/com/android/dialer/list/AllContactsFragment.java
index 0f31ff8..7e76279 100644
--- a/src/com/android/dialer/list/AllContactsFragment.java
+++ b/src/com/android/dialer/list/AllContactsFragment.java
@@ -28,11 +28,13 @@
 import android.net.Uri;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.QuickContact;
+import android.support.v13.app.FragmentCompat;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 
+import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.list.ContactEntryListAdapter;
 import com.android.contacts.common.list.ContactEntryListFragment;
 import com.android.contacts.common.list.ContactListFilter;
@@ -49,7 +51,8 @@
  * Fragments to show all contacts with phone numbers.
  */
 public class AllContactsFragment extends ContactEntryListFragment<ContactEntryListAdapter>
-        implements OnEmptyViewActionButtonClickedListener {
+        implements OnEmptyViewActionButtonClickedListener,
+        FragmentCompat.OnRequestPermissionsResultCallback {
 
     private static final int READ_CONTACTS_PERMISSION_REQUEST_CODE = 1;
 
@@ -150,8 +153,13 @@
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         final Uri uri = (Uri) view.getTag();
         if (uri != null) {
-            QuickContact.showQuickContact(getContext(), view, uri, null,
-                    Phone.CONTENT_ITEM_TYPE);
+            if (CompatUtils.hasPrioritizedMimeType()) {
+                QuickContact.showQuickContact(getContext(), view, uri, null,
+                        Phone.CONTENT_ITEM_TYPE);
+            } else {
+                QuickContact.showQuickContact(getActivity(), view, uri, QuickContact.MODE_LARGE,
+                        null);
+            }
         }
     }
 
@@ -168,7 +176,8 @@
         }
 
         if (!PermissionsUtil.hasPermission(activity, READ_CONTACTS)) {
-            requestPermissions(new String[] {READ_CONTACTS}, READ_CONTACTS_PERMISSION_REQUEST_CODE);
+          FragmentCompat.requestPermissions(this, new String[] {READ_CONTACTS},
+              READ_CONTACTS_PERMISSION_REQUEST_CODE);
         } else {
             // Add new contact
             DialerUtils.startActivityWithErrorToast(activity, IntentUtil.getNewContactIntent(),
diff --git a/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java b/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
index c12bed7..69a230c 100644
--- a/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
@@ -24,6 +24,7 @@
 import android.widget.ImageButton;
 import android.widget.TextView;
 
+import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.list.ContactEntry;
 import com.android.dialer.R;
 
@@ -63,8 +64,13 @@
     }
 
     private void launchQuickContact() {
-        QuickContact.showQuickContact(getContext(), PhoneFavoriteSquareTileView.this,
-                getLookupUri(), null, Phone.CONTENT_ITEM_TYPE);
+        if (CompatUtils.hasPrioritizedMimeType()) {
+            QuickContact.showQuickContact(getContext(), PhoneFavoriteSquareTileView.this,
+                    getLookupUri(), null, Phone.CONTENT_ITEM_TYPE);
+        } else {
+            QuickContact.showQuickContact(getContext(), PhoneFavoriteSquareTileView.this,
+                    getLookupUri(), QuickContact.MODE_LARGE, null);
+        }
     }
 
     @Override
diff --git a/src/com/android/dialer/list/RegularSearchFragment.java b/src/com/android/dialer/list/RegularSearchFragment.java
index 30b01c0..d067b65 100644
--- a/src/com/android/dialer/list/RegularSearchFragment.java
+++ b/src/com/android/dialer/list/RegularSearchFragment.java
@@ -19,6 +19,7 @@
 
 import android.app.Activity;
 import android.content.pm.PackageManager;
+import android.support.v13.app.FragmentCompat;
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 
@@ -37,7 +38,8 @@
 import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener;
 
 public class RegularSearchFragment extends SearchFragment
-        implements OnEmptyViewActionButtonClickedListener {
+        implements OnEmptyViewActionButtonClickedListener,
+        FragmentCompat.OnRequestPermissionsResultCallback {
 
     public static final int PERMISSION_REQUEST_CODE = 1;
 
@@ -123,7 +125,8 @@
         }
 
         if (READ_CONTACTS.equals(mPermissionToRequest)) {
-            requestPermissions(new String[] {mPermissionToRequest}, PERMISSION_REQUEST_CODE);
+          FragmentCompat.requestPermissions(this, new String[] {mPermissionToRequest},
+              PERMISSION_REQUEST_CODE);
         }
     }
 
diff --git a/src/com/android/dialer/list/SmartDialSearchFragment.java b/src/com/android/dialer/list/SmartDialSearchFragment.java
index a230e6e..4984d95 100644
--- a/src/com/android/dialer/list/SmartDialSearchFragment.java
+++ b/src/com/android/dialer/list/SmartDialSearchFragment.java
@@ -22,6 +22,7 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
+import android.support.v13.app.FragmentCompat;
 import android.util.Log;
 import android.view.View;
 
@@ -40,7 +41,8 @@
  * Implements a fragment to load and display SmartDial search results.
  */
 public class SmartDialSearchFragment extends SearchFragment
-        implements EmptyContentView.OnEmptyViewActionButtonClickedListener {
+        implements EmptyContentView.OnEmptyViewActionButtonClickedListener,
+        FragmentCompat.OnRequestPermissionsResultCallback {
     private static final String TAG = SmartDialSearchFragment.class.getSimpleName();
 
     private static final int CALL_PHONE_PERMISSION_REQUEST_CODE = 1;
@@ -108,7 +110,8 @@
             return;
         }
 
-        requestPermissions(new String[] {CALL_PHONE}, CALL_PHONE_PERMISSION_REQUEST_CODE);
+        FragmentCompat.requestPermissions(this, new String[] {CALL_PHONE},
+            CALL_PHONE_PERMISSION_REQUEST_CODE);
     }
 
     @Override
diff --git a/src/com/android/dialer/list/SpeedDialFragment.java b/src/com/android/dialer/list/SpeedDialFragment.java
index 19180f8..fcfff21 100644
--- a/src/com/android/dialer/list/SpeedDialFragment.java
+++ b/src/com/android/dialer/list/SpeedDialFragment.java
@@ -31,6 +31,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Trace;
+import android.support.v13.app.FragmentCompat;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -63,7 +64,8 @@
  */
 public class SpeedDialFragment extends Fragment implements OnItemClickListener,
         PhoneFavoritesTileAdapter.OnDataSetChangedForAnimationListener,
-        EmptyContentView.OnEmptyViewActionButtonClickedListener {
+        EmptyContentView.OnEmptyViewActionButtonClickedListener,
+        FragmentCompat.OnRequestPermissionsResultCallback {
 
     private static final int READ_CONTACTS_PERMISSION_REQUEST_CODE = 1;
 
@@ -482,7 +484,8 @@
         }
 
         if (!PermissionsUtil.hasPermission(activity, READ_CONTACTS)) {
-            requestPermissions(new String[] {READ_CONTACTS}, READ_CONTACTS_PERMISSION_REQUEST_CODE);
+          FragmentCompat.requestPermissions(this, new String[] {READ_CONTACTS},
+              READ_CONTACTS_PERMISSION_REQUEST_CODE);
         } else {
             // Switch tabs
             ((HostInterface) activity).showAllContactsTab();
diff --git a/src/com/android/dialer/settings/DefaultRingtonePreference.java b/src/com/android/dialer/settings/DefaultRingtonePreference.java
index a174381..a8a23fd 100644
--- a/src/com/android/dialer/settings/DefaultRingtonePreference.java
+++ b/src/com/android/dialer/settings/DefaultRingtonePreference.java
@@ -16,17 +16,16 @@
 
 package com.android.dialer.settings;
 
-import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.Intent;
 import android.media.RingtoneManager;
 import android.net.Uri;
 import android.preference.RingtonePreference;
-import android.provider.Settings;
 import android.util.AttributeSet;
 import android.widget.Toast;
 
 import com.android.dialer.R;
+import com.android.dialer.compat.SettingsCompat;
 
 /**
  * RingtonePreference which doesn't show default ringtone setting.
@@ -49,7 +48,7 @@
 
     @Override
     protected void onSaveRingtone(Uri ringtoneUri) {
-        if (!Settings.System.canWrite(getContext())) {
+        if (!SettingsCompat.System.canWrite(getContext())) {
             Toast.makeText(
                     getContext(),
                     getContext().getResources().getString(R.string.toast_cannot_write_system_settings),
diff --git a/src/com/android/dialer/settings/DialerSettingsActivity.java b/src/com/android/dialer/settings/DialerSettingsActivity.java
index d0bfbc2..cc84486 100644
--- a/src/com/android/dialer/settings/DialerSettingsActivity.java
+++ b/src/com/android/dialer/settings/DialerSettingsActivity.java
@@ -18,6 +18,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.UserManager;
 import android.preference.PreferenceManager;
@@ -27,7 +28,9 @@
 import android.view.MenuItem;
 import android.widget.Toast;
 
+import com.android.contacts.common.compat.SdkVersionOverride;
 import com.android.dialer.R;
+import com.android.dialer.compat.SettingsCompat;
 import com.android.dialer.filterednumber.BlockedNumbersSettingsActivity;
 
 import java.util.List;
@@ -54,12 +57,16 @@
         soundSettingsHeader.id = R.id.settings_header_sounds_and_vibration;
         target.add(soundSettingsHeader);
 
-        Header quickResponseSettingsHeader = new Header();
-        Intent quickResponseSettingsIntent =
-                new Intent(TelecomManager.ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS);
-        quickResponseSettingsHeader.titleRes = R.string.respond_via_sms_setting_title;
-        quickResponseSettingsHeader.intent = quickResponseSettingsIntent;
-        target.add(quickResponseSettingsHeader);
+        if (SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M)
+                >= Build.VERSION_CODES.M) {
+            Header quickResponseSettingsHeader = new Header();
+            Intent quickResponseSettingsIntent =
+                    new Intent(TelecomManager.ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS);
+            quickResponseSettingsHeader.titleRes = R.string.respond_via_sms_setting_title;
+            quickResponseSettingsHeader.intent = quickResponseSettingsIntent;
+            target.add(quickResponseSettingsHeader);
+        }
+
 
         TelephonyManager telephonyManager =
                 (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
@@ -91,8 +98,10 @@
             blockedCallsHeader.intent = new Intent(this, BlockedNumbersSettingsActivity.class);
             target.add(blockedCallsHeader);
 
-            if (telephonyManager.isTtyModeSupported()
-                    || telephonyManager.isHearingAidCompatibilitySupported()) {
+            if (SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M)
+                    >= Build.VERSION_CODES.M
+                    && (telephonyManager.isTtyModeSupported()
+                    || telephonyManager.isHearingAidCompatibilitySupported())) {
                 Header accessibilitySettingsHeader = new Header();
                 Intent accessibilitySettingsIntent =
                         new Intent(TelecomManager.ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS);
@@ -109,7 +118,7 @@
             // If we don't have the permission to write to system settings, go to system sound
             // settings instead. Otherwise, perform the super implementation (which launches our
             // own preference fragment.
-            if (!Settings.System.canWrite(this)) {
+            if (!SettingsCompat.System.canWrite(this)) {
                 Toast.makeText(
                         this,
                         getResources().getString(R.string.toast_cannot_write_system_settings),
diff --git a/src/com/android/dialer/settings/SoundSettingsFragment.java b/src/com/android/dialer/settings/SoundSettingsFragment.java
index 8384700..59f8798 100644
--- a/src/com/android/dialer/settings/SoundSettingsFragment.java
+++ b/src/com/android/dialer/settings/SoundSettingsFragment.java
@@ -16,10 +16,9 @@
 
 package com.android.dialer.settings;
 
-import android.app.AppOpsManager;
 import android.content.Context;
-import android.content.Intent;
 import android.media.RingtoneManager;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -32,21 +31,13 @@
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
 import android.telephony.TelephonyManager;
-import android.view.MenuItem;
 import android.widget.Toast;
 
-import com.android.contacts.common.util.PermissionsUtil;
+import com.android.contacts.common.compat.SdkVersionOverride;
 import com.android.dialer.R;
+import com.android.dialer.compat.SettingsCompat;
 import com.android.phone.common.util.SettingsUtil;
 
-import java.lang.Boolean;
-import java.lang.CharSequence;
-import java.lang.Object;
-import java.lang.Override;
-import java.lang.Runnable;
-import java.lang.String;
-import java.lang.Thread;
-
 public class SoundSettingsFragment extends PreferenceFragment
         implements Preference.OnPreferenceChangeListener {
 
@@ -88,6 +79,11 @@
     };
 
     @Override
+    public Context getContext() {
+        return getActivity();
+    }
+
+    @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
@@ -115,7 +111,8 @@
 
         TelephonyManager telephonyManager =
                 (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
-        if (telephonyManager.canChangeDtmfToneLength()
+        if (SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M) >= Build.VERSION_CODES.M
+                && telephonyManager.canChangeDtmfToneLength()
                 && (telephonyManager.isWorldPhone() || !shouldHideCarrierSettings())) {
             mDtmfToneLength.setOnPreferenceChangeListener(this);
             mDtmfToneLength.setValueIndex(
@@ -132,7 +129,7 @@
     public void onResume() {
         super.onResume();
 
-        if (!Settings.System.canWrite(getContext())) {
+        if (!SettingsCompat.System.canWrite(getContext())) {
             // If the user launches this setting fragment, then toggles the WRITE_SYSTEM_SETTINGS
             // AppOp, then close the fragment since there is nothing useful to do.
             getActivity().onBackPressed();
@@ -155,7 +152,7 @@
      */
     @Override
     public boolean onPreferenceChange(Preference preference, Object objValue) {
-        if (!Settings.System.canWrite(getContext())) {
+        if (!SettingsCompat.System.canWrite(getContext())) {
             // A user shouldn't be able to get here, but this protects against monkey crashes.
             Toast.makeText(
                     getContext(),
@@ -181,7 +178,7 @@
      */
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        if (!Settings.System.canWrite(getContext())) {
+        if (!SettingsCompat.System.canWrite(getContext())) {
             Toast.makeText(
                     getContext(),
                     getResources().getString(R.string.toast_cannot_write_system_settings),
diff --git a/src/com/android/dialer/util/AppCompatConstants.java b/src/com/android/dialer/util/AppCompatConstants.java
index 1d52eee..0bb78df 100644
--- a/src/com/android/dialer/util/AppCompatConstants.java
+++ b/src/com/android/dialer/util/AppCompatConstants.java
@@ -27,4 +27,6 @@
     public static final int CALLS_REJECTED_TYPE = 5;
     // Added to android.provider.CallLog.Calls in N+.
     public static final int CALLS_BLOCKED_TYPE = 6;
+    // Added to android.provider.CallLog.Calls in N+.
+    public static final String POST_DIAL_DIGITS = "post_dial_digits";
 }
diff --git a/src/com/android/dialer/util/TelecomUtil.java b/src/com/android/dialer/util/TelecomUtil.java
index bab1ade..a0c8334 100644
--- a/src/com/android/dialer/util/TelecomUtil.java
+++ b/src/com/android/dialer/util/TelecomUtil.java
@@ -22,11 +22,14 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.CallLog.Calls;
+import android.support.v4.content.ContextCompat;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.dialer.compat.DialerCompatUtils;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -181,11 +184,15 @@
     }
 
     private static boolean hasPermission(Context context, String permission) {
-        return context.checkSelfPermission(permission)
+        return ContextCompat.checkSelfPermission(context, permission)
                 == PackageManager.PERMISSION_GRANTED;
     }
 
     public static boolean isDefaultDialer(Context context) {
+        if (!DialerCompatUtils.isDefaultDialerCompatible()) {
+            return false;
+        }
+
         final boolean result = TextUtils.equals(context.getPackageName(),
                 getTelecomManager(context).getDefaultDialerPackage());
         if (result) {
diff --git a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
index a5a61ad..80dfe35 100644
--- a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
@@ -64,6 +64,7 @@
     private static final String TEST_NUMBER_1 = "12345678";
     private static final String TEST_NUMBER_2 = "87654321";
     private static final String TEST_NUMBER_3 = "18273645";
+    private static final String TEST_POST_DIAL_DIGITS = ";12345";
     private static final String TEST_FORMATTED_NUMBER = "1 212-555-1000";
 
     // The object under test.
@@ -233,6 +234,18 @@
     }
 
     @MediumTest
+    public void testBindView_CallButtonWithPostDialDigits() {
+        createCallLogEntry(TEST_NUMBER, TEST_POST_DIAL_DIGITS, NO_VALUE_SET, NO_VALUE_SET);
+
+        mAdapter.changeCursor(mCursor);
+        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        if (PhoneNumberDisplayUtil.canShowPostDial()) {
+            assertHasCallActionToGivenNumber(mViewHolder, TEST_NUMBER + TEST_POST_DIAL_DIGITS);
+        }
+    }
+
+    @MediumTest
     public void testBindView_VoicemailUri() {
         createVoicemailCallLogEntry();
 
@@ -245,6 +258,32 @@
     }
 
     @MediumTest
+    public void testBindView_NumberWithPostDialDigits() {
+        createCallLogEntry(TEST_NUMBER, TEST_POST_DIAL_DIGITS, NO_VALUE_SET, NO_VALUE_SET);
+
+        mAdapter.changeCursor(mCursor);
+        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        if (PhoneNumberDisplayUtil.canShowPostDial()) {
+            assertNameIs(mViewHolder, TEST_NUMBER + TEST_POST_DIAL_DIGITS);
+        }
+    }
+
+    @MediumTest
+    public void testBindView_ContactWithPostDialDigits() {
+        createCallLogEntry(TEST_NUMBER, TEST_POST_DIAL_DIGITS, NO_VALUE_SET, NO_VALUE_SET);
+        mAdapter.injectContactInfoForTest(TEST_NUMBER + TEST_POST_DIAL_DIGITS, TEST_COUNTRY_ISO,
+                createContactInfo());
+
+        mAdapter.changeCursor(mCursor);
+        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        if (PhoneNumberDisplayUtil.canShowPostDial()) {
+            assertNameIs(mViewHolder, TEST_CACHED_NAME_PRIMARY);
+        }
+    }
+
+    @MediumTest
     public void testPresentationAfterRebindingViewHolders() {
         final int increment = 10;
         final int size = increment * 4;
@@ -513,12 +552,13 @@
     }
 
     private void createCallLogEntry(String testNumber) {
-        createCallLogEntry(testNumber, NO_VALUE_SET, NO_VALUE_SET);
+        createCallLogEntry(testNumber, EMPTY_STRING, NO_VALUE_SET, NO_VALUE_SET);
     }
 
     private void createPrivateCallLogEntry() {
         createCallLogEntry(
                 EMPTY_STRING,
+                EMPTY_STRING,
                 Calls.PRESENTATION_RESTRICTED,
                 AppCompatConstants.CALLS_INCOMING_TYPE);
     }
@@ -526,16 +566,17 @@
     private void createUnknownCallLogEntry() {
         createCallLogEntry(
                 EMPTY_STRING,
+                EMPTY_STRING,
                 Calls.PRESENTATION_UNKNOWN,
                 AppCompatConstants.CALLS_INCOMING_TYPE);
     }
 
     private void createVoicemailCallLogEntry() {
-        createCallLogEntry(TEST_NUMBER, NO_VALUE_SET, Calls.VOICEMAIL_TYPE);
+        createCallLogEntry(TEST_NUMBER, EMPTY_STRING, NO_VALUE_SET, Calls.VOICEMAIL_TYPE);
     }
 
-    private void createCallLogEntry(String number, int presentation, int type) {
-        Object[] values = getValues(number, presentation, type);
+    private void createCallLogEntry(String number, String postDialDigits, int presentation, int type) {
+        Object[] values = getValues(number, postDialDigits, presentation, type);
         mCursor.addRow(values);
     }
 
@@ -583,7 +624,7 @@
             String cachedNumberLabel,
             String cachedFormattedNumber,
             boolean inject) {
-        Object[] values = getValues(number, NO_VALUE_SET, type);
+        Object[] values = getValues(number, EMPTY_STRING, NO_VALUE_SET, type);
         values[CallLogQuery.CACHED_NAME] = cachedName;
         values[CallLogQuery.CACHED_NUMBER_TYPE] = cachedNumberType;
         values[CallLogQuery.CACHED_NUMBER_LABEL] = cachedNumberLabel;
@@ -600,12 +641,14 @@
 
     /**
      * @param number The phone number.
+     * @param postDialDigits The post dial digits dialed (if any)
      * @param presentation Number representing display rules for "allowed",
      *               "payphone", "restricted", or "unknown".
-     * @param date In millisec since epoch. Use NOW to use the current time.
+     * @param type The type of the call (outgoing/ingoing)
      */
     private Object[] getValues(
             String number,
+            String postDialDigits,
             int presentation,
             int type) {
         Object[] values = CallLogQueryTestUtils.createTestValues();
@@ -618,6 +661,9 @@
         if (!TextUtils.isEmpty(number)) {
             values[CallLogQuery.NUMBER] = number;
         }
+        if (!TextUtils.isEmpty(postDialDigits) && PhoneNumberDisplayUtil.canShowPostDial()) {
+            values[CallLogQuery.POST_DIAL_DIGITS] = postDialDigits;
+        }
         if (presentation != NO_VALUE_SET) {
             values[CallLogQuery.NUMBER_PRESENTATION] = presentation;
         }
@@ -676,14 +722,16 @@
     }
 
     private void assertHasCallAction(CallLogListItemViewHolder viewHolder) {
-        // The primaryActionView tag is set when the ViewHolder is binded. If it is possible
-        // to place a call to the phone number, a call intent will have been created which
-        // starts a phone call to the entry's number.
+        assertHasCallActionToGivenNumber(viewHolder, TEST_NUMBER);
+    }
+
+    private void assertHasCallActionToGivenNumber(CallLogListItemViewHolder viewHolder,
+            String number) {
         IntentProvider intentProvider =
                 (IntentProvider) viewHolder.primaryActionButtonView.getTag();
         Intent intent = intentProvider.getIntent(getContext());
         assertEquals(TestConstants.CALL_INTENT_ACTION, intent.getAction());
-        assertEquals(Uri.parse("tel:" + TEST_NUMBER), intent.getData());
+        assertEquals(Uri.parse("tel:" + Uri.encode(number)), intent.getData());
     }
 
     /** Returns the label associated with a given phone type. */
diff --git a/tests/src/com/android/dialer/calllog/CallLogGroupBuilderTest.java b/tests/src/com/android/dialer/calllog/CallLogGroupBuilderTest.java
index 5d0b6be..04463c2 100644
--- a/tests/src/com/android/dialer/calllog/CallLogGroupBuilderTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogGroupBuilderTest.java
@@ -35,6 +35,8 @@
     private static final String TEST_NUMBER1 = "14125551234";
     /** A phone number for testing. */
     private static final String TEST_NUMBER2 = "14125555555";
+    /** A post-dial string for testing */
+    private static final String TEST_POST_DIAL_DIGITS = ";12435;0987";
 
     /** The object under test. */
     private CallLogGroupBuilder mBuilder;
@@ -86,6 +88,26 @@
         assertGroupIs(0, 3, mFakeGroupCreator.groups.get(0));
     }
 
+    public void testAddGroups_WithPostDialMatching() {
+        addCallLogEntryWithPostDialDigits(TEST_NUMBER1, TEST_POST_DIAL_DIGITS,
+                AppCompatConstants.CALLS_OUTGOING_TYPE);
+        addCallLogEntryWithPostDialDigits(TEST_NUMBER1, TEST_POST_DIAL_DIGITS,
+                AppCompatConstants.CALLS_OUTGOING_TYPE);
+        addCallLogEntryWithPostDialDigits(TEST_NUMBER1, "",
+                AppCompatConstants.CALLS_OUTGOING_TYPE);
+
+        mBuilder.addGroups(mCursor);
+
+        if (PhoneNumberDisplayUtil.canShowPostDial()) {
+            assertEquals(2, mFakeGroupCreator.groups.size());
+            assertGroupIs(0, 2, mFakeGroupCreator.groups.get(0));
+            assertGroupIs(2, 1, mFakeGroupCreator.groups.get(1));
+        } else {
+            assertEquals(1, mFakeGroupCreator.groups.size());
+            assertGroupIs(0, 3, mFakeGroupCreator.groups.get(0));
+        }
+    }
+
     public void testAddGroups_MatchingIncomingAndOutgoing() {
         addCallLogEntry(TEST_NUMBER1, AppCompatConstants.CALLS_INCOMING_TYPE);
         addCallLogEntry(TEST_NUMBER1, AppCompatConstants.CALLS_OUTGOING_TYPE);
@@ -312,11 +334,19 @@
     }
     /** Adds a call log entry with the given number and type to the cursor. */
     private void addCallLogEntry(String number, int type) {
+        addCallLogEntryWithPostDialDigits(number, "", type);
+    }
+
+    /** Adds a call log entry with the given number, post-dial digits, and type to the cursor. */
+    private void addCallLogEntryWithPostDialDigits(String number, String postDialDigits, int type) {
         mCursor.moveToNext();
         Object[] values = CallLogQueryTestUtils.createTestValues();
         values[CallLogQuery.ID] = mCursor.getPosition();
         values[CallLogQuery.NUMBER] = number;
         values[CallLogQuery.CALL_TYPE] = type;
+        if (PhoneNumberDisplayUtil.canShowPostDial()) {
+            values[CallLogQuery.POST_DIAL_DIGITS] = postDialDigits;
+        }
         mCursor.addRow(values);
     }
 
diff --git a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
index c9d8264..a97fce3 100644
--- a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
@@ -246,26 +246,34 @@
     /** Sets the details of a phone call using the specified phone number. */
     private void setPhoneCallDetailsWithNumber(String number,
             int presentation, String formattedNumber) {
-        setPhoneCallDetailsWithNumberAndType(number, presentation,
+        setPhoneCallDetailsWithNumberTypeAndPostDialDigits(number, "", presentation,
                 formattedNumber, Calls.INCOMING_TYPE);
     }
 
     /** Sets the details of a phone call using the specified phone number. */
     private void setPhoneCallDetailsWithNumberAndType(String number,
             int presentation, String formattedNumber, int callType) {
+        setPhoneCallDetailsWithNumberTypeAndPostDialDigits(number, "", presentation,
+                formattedNumber, callType);
+    }
+
+    /** Sets the details of a phone call using the specified phone number and post-dial digits. */
+    private void setPhoneCallDetailsWithNumberTypeAndPostDialDigits(String number,
+            String postDialDigits, int presentation, String formattedNumber, int callType) {
         PhoneCallDetails details = getPhoneCallDetails(
-                number, presentation, formattedNumber);
+                number, postDialDigits, presentation, formattedNumber);
         details.callTypes = new int[] {callType};
         mHelper.setPhoneCallDetails(mViewHolder, details);
     }
 
     private PhoneCallDetails getPhoneCallDetails(
-            String number, int presentation, String formattedNumber) {
+            String number, String postDialDigits, int presentation, String formattedNumber) {
         PhoneCallDetails details = new PhoneCallDetails(
                 mContext,
                 number,
                 presentation,
                 formattedNumber,
+                postDialDigits,
                 false /* isVoicemail */);
         setDefaultDetails(details);
         return details;
@@ -278,6 +286,7 @@
                 TEST_NUMBER,
                 Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
+                "",
                 false /* isVoicemail */);
         setDefaultDetails(details);
         details.callTypes = types;
diff --git a/tests/src/com/android/dialer/calllog/CallLogQueryTestUtils.java b/tests/src/com/android/dialer/calllog/CallLogQueryTestUtils.java
index 5b46293..1e4a000 100644
--- a/tests/src/com/android/dialer/calllog/CallLogQueryTestUtils.java
+++ b/tests/src/com/android/dialer/calllog/CallLogQueryTestUtils.java
@@ -20,17 +20,24 @@
 
 import android.provider.CallLog.Calls;
 
-import junit.framework.Assert;
-
 /**
  * Helper class to create test values for {@link CallLogQuery}.
  */
 public class CallLogQueryTestUtils {
     public static Object[] createTestValues() {
-        Object[] values = new Object[]{
-                0L, "", 0L, 0L, Calls.INCOMING_TYPE, "", "", "", null, 0, null, null, null, null,
-                0L, null, 0, Calls.PRESENTATION_ALLOWED, null, null, 0, null, null, null
-        };
+        Object[] values;
+        if (PhoneNumberDisplayUtil.canShowPostDial()) {
+            values = new Object[]{
+                    0L, "", 0L, 0L, Calls.INCOMING_TYPE, "", "", "", null, 0, null, null, null,
+                    null, 0L, null, 0, Calls.PRESENTATION_ALLOWED, null, null, 0, null, null,
+                    null, ""
+            };
+        } else {
+            values = new Object[]{
+                    0L, "", 0L, 0L, Calls.INCOMING_TYPE, "", "", "", null, 0, null, null, null,
+                    null, 0L, null, 0, Calls.PRESENTATION_ALLOWED, null, null, 0, null, null, null
+            };
+        }
         assertEquals(CallLogQuery._PROJECTION.length, values.length);
         return values;
     }
diff --git a/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java b/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java
index c30861c..23ee7b3 100644
--- a/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java
+++ b/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java
@@ -58,6 +58,8 @@
     private static final String TEST_GEOCODE = "United States";
     /** Empty geocode label */
     private static final String EMPTY_GEOCODE = "";
+    /** Empty post-dial digits label */
+    private static final String EMPTY_POSTDIAL = "";
 
     /** The object under test. */
     private PhoneCallDetailsHelper mHelper;
@@ -428,6 +430,7 @@
                 TEST_NUMBER,
                 Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
+                EMPTY_POSTDIAL,
                 false /* isVoicemail */);
         setDefaultDetails(details);
         return details;
@@ -440,6 +443,7 @@
                 number,
                 presentation,
                 formattedNumber,
+                EMPTY_POSTDIAL,
                 isVoicemail(number));
         setDefaultDetails(details);
         return details;
diff --git a/tests/src/com/android/dialer/filterednumber/FilteredNumbersUtilTest.java b/tests/src/com/android/dialer/filterednumber/FilteredNumbersUtilTest.java
index 180295c..ccd95ab 100644
--- a/tests/src/com/android/dialer/filterednumber/FilteredNumbersUtilTest.java
+++ b/tests/src/com/android/dialer/filterednumber/FilteredNumbersUtilTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.dialer.filterednumber;
 
+import android.preference.PreferenceManager;
 import android.test.AndroidTestCase;
 
 import com.android.contacts.common.test.mocks.ContactsMockContext;
@@ -46,6 +47,12 @@
     public void setUp() throws Exception {
         super.setUp();
         mContext = new ContactsMockContext(getContext(), FilteredNumberContract.AUTHORITY);
+
+        // Reset whether an emergency number was dialed
+        PreferenceManager.getDefaultSharedPreferences(mContext)
+                .edit()
+                .putLong(FilteredNumbersUtil.LAST_EMERGENCY_CALL_MS_PREF_KEY, 0)
+                .apply();
     }
 
     public void testShouldBlockVoicemail_NotBlocked() {
@@ -78,6 +85,17 @@
                 COUNTRY_ISO, EARLIER_TIME + 30000));
     }
 
+    public void testShouldBlockVoicemail_AfterEmergencyCall() {
+        // Just called emergency services
+        PreferenceManager.getDefaultSharedPreferences(mContext)
+                .edit()
+                .putLong(FilteredNumbersUtil.LAST_EMERGENCY_CALL_MS_PREF_KEY,
+                        System.currentTimeMillis())
+                .apply();
+        assertFalse(FilteredNumbersUtil.shouldBlockVoicemail(mContext, NORMALIZED_NUMBER,
+                COUNTRY_ISO, 0));
+    }
+
     private void setupShouldBlockVoicemailQuery(long creationTimeMs) {
         Query query = mContext.getContactsProvider().expectQuery(FilteredNumber.CONTENT_URI)
                 .withProjection(FILTERED_NUMBER_PROJECTION)