Merge changes I45374e61,I265dcc61,Id4622886,I09d0df69,I3ea0fb46 am: 2f6900466e
am: e6262b0bce

Change-Id: I46367591d38db2178a9f5ac1b5b8ac8ca0487efd
diff --git a/java/com/android/contacts/common/list/ContactEntry.java b/java/com/android/contacts/common/list/ContactEntry.java
index e33165e..90e6735 100644
--- a/java/com/android/contacts/common/list/ContactEntry.java
+++ b/java/com/android/contacts/common/list/ContactEntry.java
@@ -16,25 +16,19 @@
 
 package com.android.contacts.common.list;
 
+import android.content.Context;
 import android.net.Uri;
 import android.provider.ContactsContract.PinnedPositions;
-import android.text.TextUtils;
-import com.android.contacts.common.preference.ContactsPreferences;
+import com.android.dialer.contacts.ContactsComponent;
 
 /** Class to hold contact information */
 public class ContactEntry {
 
   public static final ContactEntry BLANK_ENTRY = new ContactEntry();
-  private static final int UNSET_DISPLAY_ORDER_PREFERENCE = -1;
   /** Primary name for a Contact */
   public String namePrimary;
   /** Alternative name for a Contact, e.g. last name first */
   public String nameAlternative;
-  /**
-   * The user's preference on name display order, last name first or first time first. {@see
-   * ContactsPreferences}
-   */
-  public int nameDisplayOrder = UNSET_DISPLAY_ORDER_PREFERENCE;
 
   public String phoneLabel;
   public String phoneNumber;
@@ -46,12 +40,9 @@
   public boolean isFavorite = false;
   public boolean isDefaultNumber = false;
 
-  public String getPreferredDisplayName() {
-    if (nameDisplayOrder == UNSET_DISPLAY_ORDER_PREFERENCE
-        || nameDisplayOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY
-        || TextUtils.isEmpty(nameAlternative)) {
-      return namePrimary;
-    }
-    return nameAlternative;
+  public String getPreferredDisplayName(Context context) {
+    return ContactsComponent.get(context)
+        .contactDisplayPreferences()
+        .getDisplayName(namePrimary, nameAlternative);
   }
 }
diff --git a/java/com/android/contacts/common/preference/ContactsPreferences.java b/java/com/android/contacts/common/preference/ContactsPreferences.java
deleted file mode 100644
index d0adb04..0000000
--- a/java/com/android/contacts/common/preference/ContactsPreferences.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.common.preference;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.os.Handler;
-import android.preference.PreferenceManager;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.text.TextUtils;
-import com.android.contacts.common.R;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.dialer.strictmode.StrictModeUtils;
-
-/** Manages user preferences for contacts. */
-public class ContactsPreferences implements OnSharedPreferenceChangeListener {
-
-  /** The value for the DISPLAY_ORDER key to show the given name first. */
-  public static final int DISPLAY_ORDER_PRIMARY = 1;
-
-  /** The value for the DISPLAY_ORDER key to show the family name first. */
-  public static final int DISPLAY_ORDER_ALTERNATIVE = 2;
-
-  public static final String DISPLAY_ORDER_KEY = "android.contacts.DISPLAY_ORDER";
-
-  /** The value for the SORT_ORDER key corresponding to sort by given name first. */
-  public static final int SORT_ORDER_PRIMARY = 1;
-
-  public static final String SORT_ORDER_KEY = "android.contacts.SORT_ORDER";
-
-  /** The value for the SORT_ORDER key corresponding to sort by family name first. */
-  public static final int SORT_ORDER_ALTERNATIVE = 2;
-
-  public static final String PREF_DISPLAY_ONLY_PHONES = "only_phones";
-
-  public static final boolean PREF_DISPLAY_ONLY_PHONES_DEFAULT = false;
-
-  /**
-   * Value to use when a preference is unassigned and needs to be read from the shared preferences
-   */
-  private static final int PREFERENCE_UNASSIGNED = -1;
-
-  private final Context mContext;
-  private final SharedPreferences mPreferences;
-  private int mSortOrder = PREFERENCE_UNASSIGNED;
-  private int mDisplayOrder = PREFERENCE_UNASSIGNED;
-  private String mDefaultAccount = null;
-  private ChangeListener mListener = null;
-  private Handler mHandler;
-  private String mDefaultAccountKey;
-  private String mDefaultAccountSavedKey;
-
-  public ContactsPreferences(Context context) {
-    mContext = context;
-    mHandler = new Handler();
-    mPreferences =
-        mContext
-            .getApplicationContext()
-            .getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
-    mDefaultAccountKey =
-        mContext.getResources().getString(R.string.contact_editor_default_account_key);
-    mDefaultAccountSavedKey =
-        mContext.getResources().getString(R.string.contact_editor_anything_saved_key);
-    maybeMigrateSystemSettings();
-  }
-
-  private boolean isSortOrderUserChangeable() {
-    return mContext.getResources().getBoolean(R.bool.config_sort_order_user_changeable);
-  }
-
-  private int getDefaultSortOrder() {
-    if (mContext.getResources().getBoolean(R.bool.config_default_sort_order_primary)) {
-      return SORT_ORDER_PRIMARY;
-    } else {
-      return SORT_ORDER_ALTERNATIVE;
-    }
-  }
-
-  public int getSortOrder() {
-    if (!isSortOrderUserChangeable()) {
-      return getDefaultSortOrder();
-    }
-    if (mSortOrder == PREFERENCE_UNASSIGNED) {
-      mSortOrder = mPreferences.getInt(SORT_ORDER_KEY, getDefaultSortOrder());
-    }
-    return mSortOrder;
-  }
-
-  public void setSortOrder(int sortOrder) {
-    mSortOrder = sortOrder;
-    final Editor editor = mPreferences.edit();
-    editor.putInt(SORT_ORDER_KEY, sortOrder);
-    StrictModeUtils.bypass(editor::commit);
-  }
-
-  private boolean isDisplayOrderUserChangeable() {
-    return mContext.getResources().getBoolean(R.bool.config_display_order_user_changeable);
-  }
-
-  private int getDefaultDisplayOrder() {
-    if (mContext.getResources().getBoolean(R.bool.config_default_display_order_primary)) {
-      return DISPLAY_ORDER_PRIMARY;
-    } else {
-      return DISPLAY_ORDER_ALTERNATIVE;
-    }
-  }
-
-  public int getDisplayOrder() {
-    if (!isDisplayOrderUserChangeable()) {
-      return getDefaultDisplayOrder();
-    }
-    if (mDisplayOrder == PREFERENCE_UNASSIGNED) {
-      mDisplayOrder = mPreferences.getInt(DISPLAY_ORDER_KEY, getDefaultDisplayOrder());
-    }
-    return mDisplayOrder;
-  }
-
-  public void setDisplayOrder(int displayOrder) {
-    mDisplayOrder = displayOrder;
-    final Editor editor = mPreferences.edit();
-    editor.putInt(DISPLAY_ORDER_KEY, displayOrder);
-    StrictModeUtils.bypass(editor::commit);
-  }
-
-  private boolean isDefaultAccountUserChangeable() {
-    return mContext.getResources().getBoolean(R.bool.config_default_account_user_changeable);
-  }
-
-  private String getDefaultAccount() {
-    if (!isDefaultAccountUserChangeable()) {
-      return mDefaultAccount;
-    }
-    if (TextUtils.isEmpty(mDefaultAccount)) {
-      final String accountString = mPreferences.getString(mDefaultAccountKey, mDefaultAccount);
-      if (!TextUtils.isEmpty(accountString)) {
-        final AccountWithDataSet accountWithDataSet = AccountWithDataSet.unstringify(accountString);
-        mDefaultAccount = accountWithDataSet.name;
-      }
-    }
-    return mDefaultAccount;
-  }
-
-  private void setDefaultAccount(AccountWithDataSet accountWithDataSet) {
-    mDefaultAccount = accountWithDataSet == null ? null : accountWithDataSet.name;
-    final Editor editor = mPreferences.edit();
-    if (TextUtils.isEmpty(mDefaultAccount)) {
-      editor.remove(mDefaultAccountKey);
-    } else {
-      editor.putString(mDefaultAccountKey, accountWithDataSet.stringify());
-    }
-    editor.putBoolean(mDefaultAccountSavedKey, true);
-    StrictModeUtils.bypass(editor::commit);
-  }
-
-  public void registerChangeListener(ChangeListener listener) {
-    if (mListener != null) {
-      unregisterChangeListener();
-    }
-
-    mListener = listener;
-
-    // Reset preferences to "unknown" because they may have changed while the
-    // listener was unregistered.
-    mDisplayOrder = PREFERENCE_UNASSIGNED;
-    mSortOrder = PREFERENCE_UNASSIGNED;
-    mDefaultAccount = null;
-
-    mPreferences.registerOnSharedPreferenceChangeListener(this);
-  }
-
-  public void unregisterChangeListener() {
-    if (mListener != null) {
-      mListener = null;
-    }
-
-    mPreferences.unregisterOnSharedPreferenceChangeListener(this);
-  }
-
-  @Override
-  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, final String key) {
-    // This notification is not sent on the Ui thread. Use the previously created Handler
-    // to switch to the Ui thread
-    mHandler.post(
-        new Runnable() {
-          @Override
-          public void run() {
-            refreshValue(key);
-          }
-        });
-  }
-
-  /**
-   * Forces the value for the given key to be looked up from shared preferences and notifies the
-   * registered {@link ChangeListener}
-   *
-   * @param key the {@link SharedPreferences} key to look up
-   */
-  public void refreshValue(String key) {
-    if (DISPLAY_ORDER_KEY.equals(key)) {
-      mDisplayOrder = PREFERENCE_UNASSIGNED;
-      mDisplayOrder = getDisplayOrder();
-    } else if (SORT_ORDER_KEY.equals(key)) {
-      mSortOrder = PREFERENCE_UNASSIGNED;
-      mSortOrder = getSortOrder();
-    } else if (mDefaultAccountKey.equals(key)) {
-      mDefaultAccount = null;
-      mDefaultAccount = getDefaultAccount();
-    }
-    if (mListener != null) {
-      mListener.onChange();
-    }
-  }
-
-  /**
-   * If there are currently no preferences (which means this is the first time we are run), For sort
-   * order and display order, check to see if there are any preferences stored in system settings
-   * (pre-L) which can be copied into our own SharedPreferences. For default account setting, check
-   * to see if there are any preferences stored in the previous SharedPreferences which can be
-   * copied into current SharedPreferences.
-   */
-  private void maybeMigrateSystemSettings() {
-    if (!mPreferences.contains(SORT_ORDER_KEY)) {
-      int sortOrder = getDefaultSortOrder();
-      try {
-        sortOrder = Settings.System.getInt(mContext.getContentResolver(), SORT_ORDER_KEY);
-      } catch (SettingNotFoundException e) {
-      }
-      setSortOrder(sortOrder);
-    }
-
-    if (!mPreferences.contains(DISPLAY_ORDER_KEY)) {
-      int displayOrder = getDefaultDisplayOrder();
-      try {
-        displayOrder = Settings.System.getInt(mContext.getContentResolver(), DISPLAY_ORDER_KEY);
-      } catch (SettingNotFoundException e) {
-      }
-      setDisplayOrder(displayOrder);
-    }
-
-    if (!mPreferences.contains(mDefaultAccountKey)) {
-      final SharedPreferences previousPrefs =
-          PreferenceManager.getDefaultSharedPreferences(mContext.getApplicationContext());
-      final String defaultAccount = previousPrefs.getString(mDefaultAccountKey, null);
-      if (!TextUtils.isEmpty(defaultAccount)) {
-        final AccountWithDataSet accountWithDataSet =
-            AccountWithDataSet.unstringify(defaultAccount);
-        setDefaultAccount(accountWithDataSet);
-      }
-    }
-  }
-
-  public interface ChangeListener {
-
-    void onChange();
-  }
-}
diff --git a/java/com/android/contacts/common/preference/DisplayOrderPreference.java b/java/com/android/contacts/common/preference/DisplayOrderPreference.java
deleted file mode 100644
index 8dda57f..0000000
--- a/java/com/android/contacts/common/preference/DisplayOrderPreference.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.common.preference;
-
-import android.app.AlertDialog.Builder;
-import android.content.Context;
-import android.preference.ListPreference;
-import android.util.AttributeSet;
-import com.android.contacts.common.R;
-
-/** Custom preference: view-name-as (first name first or last name first). */
-public final class DisplayOrderPreference extends ListPreference {
-
-  private ContactsPreferences mPreferences;
-  private Context mContext;
-
-  public DisplayOrderPreference(Context context) {
-    super(context);
-    prepare();
-  }
-
-  public DisplayOrderPreference(Context context, AttributeSet attrs) {
-    super(context, attrs);
-    prepare();
-  }
-
-  private void prepare() {
-    mContext = getContext();
-    mPreferences = new ContactsPreferences(mContext);
-    setEntries(
-        new String[] {
-          mContext.getString(R.string.display_options_view_given_name_first),
-          mContext.getString(R.string.display_options_view_family_name_first),
-        });
-    setEntryValues(
-        new String[] {
-          String.valueOf(ContactsPreferences.DISPLAY_ORDER_PRIMARY),
-          String.valueOf(ContactsPreferences.DISPLAY_ORDER_ALTERNATIVE),
-        });
-    setValue(String.valueOf(mPreferences.getDisplayOrder()));
-  }
-
-  @Override
-  protected boolean shouldPersist() {
-    return false; // This preference takes care of its own storage
-  }
-
-  @Override
-  public CharSequence getSummary() {
-    switch (mPreferences.getDisplayOrder()) {
-      case ContactsPreferences.DISPLAY_ORDER_PRIMARY:
-        return mContext.getString(R.string.display_options_view_given_name_first);
-      case ContactsPreferences.DISPLAY_ORDER_ALTERNATIVE:
-        return mContext.getString(R.string.display_options_view_family_name_first);
-    }
-    return null;
-  }
-
-  @Override
-  protected boolean persistString(String value) {
-    int newValue = Integer.parseInt(value);
-    if (newValue != mPreferences.getDisplayOrder()) {
-      mPreferences.setDisplayOrder(newValue);
-      notifyChanged();
-    }
-    return true;
-  }
-
-  @Override
-  // UX recommendation is not to show cancel button on such lists.
-  protected void onPrepareDialogBuilder(Builder builder) {
-    super.onPrepareDialogBuilder(builder);
-    builder.setNegativeButton(null, null);
-  }
-}
diff --git a/java/com/android/contacts/common/preference/SortOrderPreference.java b/java/com/android/contacts/common/preference/SortOrderPreference.java
deleted file mode 100644
index 9b6f578..0000000
--- a/java/com/android/contacts/common/preference/SortOrderPreference.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.common.preference;
-
-import android.app.AlertDialog.Builder;
-import android.content.Context;
-import android.preference.ListPreference;
-import android.util.AttributeSet;
-import com.android.contacts.common.R;
-
-/** Custom preference: sort-by. */
-public final class SortOrderPreference extends ListPreference {
-
-  private ContactsPreferences mPreferences;
-  private Context mContext;
-
-  public SortOrderPreference(Context context) {
-    super(context);
-    prepare();
-  }
-
-  public SortOrderPreference(Context context, AttributeSet attrs) {
-    super(context, attrs);
-    prepare();
-  }
-
-  private void prepare() {
-    mContext = getContext();
-    mPreferences = new ContactsPreferences(mContext);
-    setEntries(
-        new String[] {
-          mContext.getString(R.string.display_options_sort_by_given_name),
-          mContext.getString(R.string.display_options_sort_by_family_name),
-        });
-    setEntryValues(
-        new String[] {
-          String.valueOf(ContactsPreferences.SORT_ORDER_PRIMARY),
-          String.valueOf(ContactsPreferences.SORT_ORDER_ALTERNATIVE),
-        });
-    setValue(String.valueOf(mPreferences.getSortOrder()));
-  }
-
-  @Override
-  protected boolean shouldPersist() {
-    return false; // This preference takes care of its own storage
-  }
-
-  @Override
-  public CharSequence getSummary() {
-    switch (mPreferences.getSortOrder()) {
-      case ContactsPreferences.SORT_ORDER_PRIMARY:
-        return mContext.getString(R.string.display_options_sort_by_given_name);
-      case ContactsPreferences.SORT_ORDER_ALTERNATIVE:
-        return mContext.getString(R.string.display_options_sort_by_family_name);
-    }
-    return null;
-  }
-
-  @Override
-  protected boolean persistString(String value) {
-    int newValue = Integer.parseInt(value);
-    if (newValue != mPreferences.getSortOrder()) {
-      mPreferences.setSortOrder(newValue);
-      notifyChanged();
-    }
-    return true;
-  }
-
-  @Override
-  // UX recommendation is not to show cancel button on such lists.
-  protected void onPrepareDialogBuilder(Builder builder) {
-    super.onPrepareDialogBuilder(builder);
-    builder.setNegativeButton(null, null);
-  }
-}
diff --git a/java/com/android/contacts/common/res/values/strings.xml b/java/com/android/contacts/common/res/values/strings.xml
index cf24a88..2011282 100644
--- a/java/com/android/contacts/common/res/values/strings.xml
+++ b/java/com/android/contacts/common/res/values/strings.xml
@@ -332,26 +332,6 @@
   <!-- Displayed at the top of the contacts showing single contact. [CHAR LIMIT=64] -->
   <string name="listSingleContact">Single contact</string>
 
-  <!-- Contact preferences related strings -->
-
-  <!-- Label of the "sort by" display option -->
-  <string name="display_options_sort_list_by">Sort by</string>
-
-  <!-- An allowable value for the "sort list by" contact display option  -->
-  <string name="display_options_sort_by_given_name">First name</string>
-
-  <!-- An allowable value for the "sort list by" contact display option  -->
-  <string name="display_options_sort_by_family_name">Last name</string>
-
-  <!-- Label of the "name format" display option [CHAR LIMIT=64]-->
-  <string name="display_options_view_names_as">Name format</string>
-
-  <!-- An allowable value for the "view names as" contact display option  -->
-  <string name="display_options_view_given_name_first">First name first</string>
-
-  <!-- An allowable value for the "view names as" contact display option  -->
-  <string name="display_options_view_family_name_first">Last name first</string>
-
   <!--  The menu item to clear frequents [CHAR LIMIT=30] -->
   <string name="menu_clear_frequents">Clear frequents</string>
 
diff --git a/java/com/android/contacts/common/util/ContactDisplayUtils.java b/java/com/android/contacts/common/util/ContactDisplayUtils.java
index 7d428e1..967395a 100644
--- a/java/com/android/contacts/common/util/ContactDisplayUtils.java
+++ b/java/com/android/contacts/common/util/ContactDisplayUtils.java
@@ -28,7 +28,6 @@
 import android.text.style.TtsSpan;
 import android.util.Patterns;
 import com.android.contacts.common.R;
-import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.dialer.common.LogUtil;
 import java.util.Objects;
 
@@ -244,62 +243,4 @@
     String msg = resources.getString(stringId, number);
     return ContactDisplayUtils.getTelephoneTtsSpannable(msg, number);
   }
-
-  /**
-   * Returns either namePrimary or nameAlternative based on the {@link ContactsPreferences}.
-   * Defaults to the name that is non-null.
-   *
-   * @param namePrimary the primary name.
-   * @param nameAlternative the alternative name.
-   * @param contactsPreferences the ContactsPreferences used to determine the preferred display
-   *     name.
-   * @return namePrimary or nameAlternative depending on the value of displayOrderPreference.
-   */
-  public static String getPreferredDisplayName(
-      String namePrimary,
-      String nameAlternative,
-      @Nullable ContactsPreferences contactsPreferences) {
-    if (contactsPreferences == null) {
-      return namePrimary != null ? namePrimary : nameAlternative;
-    }
-    if (contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
-      return namePrimary;
-    }
-
-    if (contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_ALTERNATIVE
-        && !TextUtils.isEmpty(nameAlternative)) {
-      return nameAlternative;
-    }
-
-    return namePrimary;
-  }
-
-  /**
-   * Returns either namePrimary or nameAlternative based on the {@link ContactsPreferences}.
-   * Defaults to the name that is non-null.
-   *
-   * @param namePrimary the primary name.
-   * @param nameAlternative the alternative name.
-   * @param contactsPreferences the ContactsPreferences used to determine the preferred sort order.
-   * @return namePrimary or nameAlternative depending on the value of displayOrderPreference.
-   */
-  public static String getPreferredSortName(
-      String namePrimary,
-      String nameAlternative,
-      @Nullable ContactsPreferences contactsPreferences) {
-    if (contactsPreferences == null) {
-      return namePrimary != null ? namePrimary : nameAlternative;
-    }
-
-    if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) {
-      return namePrimary;
-    }
-
-    if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_ALTERNATIVE
-        && !TextUtils.isEmpty(nameAlternative)) {
-      return nameAlternative;
-    }
-
-    return namePrimary;
-  }
 }
diff --git a/java/com/android/dialer/app/calllog/CallLogAdapter.java b/java/com/android/dialer/app/calllog/CallLogAdapter.java
index d3fd365..f5474ee 100644
--- a/java/com/android/dialer/app/calllog/CallLogAdapter.java
+++ b/java/com/android/dialer/app/calllog/CallLogAdapter.java
@@ -53,7 +53,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import com.android.contacts.common.ContactsUtils;
-import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.dialer.app.R;
 import com.android.dialer.app.calllog.CallLogFragment.CallLogFragmentListener;
 import com.android.dialer.app.calllog.CallLogGroupBuilder.GroupCreator;
@@ -73,6 +72,7 @@
 import com.android.dialer.common.concurrent.AsyncTaskExecutors;
 import com.android.dialer.compat.android.provider.VoicemailCompat;
 import com.android.dialer.configprovider.ConfigProviderComponent;
+import com.android.dialer.contacts.ContactsComponent;
 import com.android.dialer.duo.Duo;
 import com.android.dialer.duo.DuoComponent;
 import com.android.dialer.duo.DuoListener;
@@ -506,7 +506,6 @@
   private final Map<Long, Integer> dayGroups = new ArrayMap<>();
 
   private boolean loading = true;
-  private ContactsPreferences contactsPreferences;
 
   private boolean isSpamEnabled;
 
@@ -551,8 +550,6 @@
     callLogGroupBuilder = new CallLogGroupBuilder(activity.getApplicationContext(), this);
     this.filteredNumberAsyncQueryHandler = Assert.isNotNull(filteredNumberAsyncQueryHandler);
 
-    contactsPreferences = new ContactsPreferences(this.activity);
-
     blockReportSpamListener =
         new BlockReportSpamListener(
             this.activity,
@@ -674,7 +671,6 @@
     if (PermissionsUtil.hasPermission(activity, android.Manifest.permission.READ_CONTACTS)) {
       contactInfoCache.start();
     }
-    contactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY);
     isSpamEnabled = SpamComponent.get(activity).spamSettings().isSpamEnabled();
     getDuo().registerListener(this);
     notifyDataSetChanged();
@@ -1078,7 +1074,8 @@
       details.contactUri = info.lookupUri;
       details.namePrimary = info.name;
       details.nameAlternative = info.nameAlternative;
-      details.nameDisplayOrder = contactsPreferences.getDisplayOrder();
+      details.nameDisplayOrder =
+          ContactsComponent.get(activity).contactDisplayPreferences().getDisplayOrder();
       details.numberType = info.type;
       details.numberLabel = info.label;
       details.photoUri = info.photoUri;
diff --git a/java/com/android/dialer/app/list/OldSpeedDialFragment.java b/java/com/android/dialer/app/list/OldSpeedDialFragment.java
index 9b83d54..9922ee2 100644
--- a/java/com/android/dialer/app/list/OldSpeedDialFragment.java
+++ b/java/com/android/dialer/app/list/OldSpeedDialFragment.java
@@ -113,9 +113,6 @@
   public void onResume() {
     Trace.beginSection(TAG + " onResume");
     super.onResume();
-    if (contactTileAdapter != null) {
-      contactTileAdapter.refreshContactsPreferences();
-    }
     if (PermissionsUtil.hasContactsReadPermissions(getContext())) {
       if (getLoaderManager().getLoader(LOADER_ID_CONTACT_TILE) == null) {
         getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null, contactTileLoaderListener);
diff --git a/java/com/android/dialer/app/list/PhoneFavoriteSquareTileView.java b/java/com/android/dialer/app/list/PhoneFavoriteSquareTileView.java
index 6b41547..8fe67f4 100644
--- a/java/com/android/dialer/app/list/PhoneFavoriteSquareTileView.java
+++ b/java/com/android/dialer/app/list/PhoneFavoriteSquareTileView.java
@@ -104,7 +104,7 @@
 
   @Override
   protected String getNameForView(ContactEntry contactEntry) {
-    return contactEntry.getPreferredDisplayName();
+    return contactEntry.getPreferredDisplayName(getContext());
   }
 
   public ContactEntry getContactEntry() {
diff --git a/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java b/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java
index a201859..4cc48a6 100644
--- a/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java
+++ b/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java
@@ -37,10 +37,10 @@
 import com.android.contacts.common.ContactTileLoaderFactory;
 import com.android.contacts.common.list.ContactEntry;
 import com.android.contacts.common.list.ContactTileView;
-import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.dialer.app.R;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.contactphoto.ContactPhotoManager;
+import com.android.dialer.contacts.ContactsComponent;
 import com.android.dialer.duo.Duo;
 import com.android.dialer.duo.DuoComponent;
 import com.android.dialer.logging.InteractionEvent;
@@ -78,11 +78,11 @@
   private OnDataSetChangedForAnimationListener dataSetChangedListener;
   private Context context;
   private Resources resources;
-  private ContactsPreferences contactsPreferences;
   private final Comparator<ContactEntry> contactEntryComparator =
       new Comparator<ContactEntry>() {
         @Override
         public int compare(ContactEntry lhs, ContactEntry rhs) {
+
           return ComparisonChain.start()
               .compare(lhs.pinned, rhs.pinned)
               .compare(getPreferredSortName(lhs), getPreferredSortName(rhs))
@@ -90,11 +90,9 @@
         }
 
         private String getPreferredSortName(ContactEntry contactEntry) {
-          if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY
-              || TextUtils.isEmpty(contactEntry.nameAlternative)) {
-            return contactEntry.namePrimary;
-          }
-          return contactEntry.nameAlternative;
+          return ContactsComponent.get(context)
+              .contactDisplayPreferences()
+              .getSortName(contactEntry.namePrimary, contactEntry.nameAlternative);
         }
       };
   /** Back up of the temporarily removed Contact during dragging. */
@@ -121,7 +119,6 @@
     this.listener = listener;
     this.context = context;
     resources = context.getResources();
-    contactsPreferences = new ContactsPreferences(this.context);
     numFrequents = 0;
     contactEntries = new ArrayList<>();
   }
@@ -140,11 +137,6 @@
     this.inDragging = inDragging;
   }
 
-  void refreshContactsPreferences() {
-    contactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY);
-    contactsPreferences.refreshValue(ContactsPreferences.SORT_ORDER_KEY);
-  }
-
   /**
    * Gets the number of frequents from the passed in cursor.
    *
@@ -256,7 +248,6 @@
             (!TextUtils.isEmpty(nameAlternative))
                 ? nameAlternative
                 : resources.getString(R.string.missing_name);
-        contact.nameDisplayOrder = contactsPreferences.getDisplayOrder();
         contact.photoUri = (photoUri != null ? Uri.parse(photoUri) : null);
         contact.lookupKey = lookupKey;
         contact.lookupUri =
diff --git a/java/com/android/dialer/app/res/xml/display_options_settings.xml b/java/com/android/dialer/app/res/xml/display_options_settings.xml
index 0b4e11d..60301db 100644
--- a/java/com/android/dialer/app/res/xml/display_options_settings.xml
+++ b/java/com/android/dialer/app/res/xml/display_options_settings.xml
@@ -18,14 +18,22 @@
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
 
-  <com.android.contacts.common.preference.SortOrderPreference
-    android:dialogTitle="@string/display_options_sort_list_by"
-    android:key="sortOrder"
-    android:title="@string/display_options_sort_list_by"/>
+  <ListPreference
+      android:dialogTitle="@string/display_options_sort_list_by"
+      android:key="@string/display_options_sort_list_by_key"
+      android:summary="%s"
+      android:entries="@array/contact_sort_order_entries"
+      android:entryValues="@array/contact_sort_order_values"
+      android:title="@string/display_options_sort_list_by"
+      android:defaultValue="1"/>
 
-  <com.android.contacts.common.preference.DisplayOrderPreference
-    android:dialogTitle="@string/display_options_view_names_as"
-    android:key="displayOrder"
-    android:title="@string/display_options_view_names_as"/>
+  <ListPreference
+      android:dialogTitle="@string/display_options_view_names_as"
+      android:key="@string/display_options_view_names_as_key"
+      android:summary="%s"
+      android:entries="@array/contact_display_order_entries"
+      android:entryValues="@array/contact_display_order_values"
+      android:title="@string/display_options_view_names_as"
+      android:defaultValue="1"/>
 
 </PreferenceScreen>
diff --git a/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java b/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
index ae068ac..8181e21 100644
--- a/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
+++ b/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
@@ -24,6 +24,7 @@
 import com.android.dialer.commandline.CommandLineModule;
 import com.android.dialer.common.concurrent.DialerExecutorModule;
 import com.android.dialer.configprovider.SharedPrefConfigProviderModule;
+import com.android.dialer.contacts.ContactsModule;
 import com.android.dialer.duo.stub.StubDuoModule;
 import com.android.dialer.enrichedcall.stub.StubEnrichedCallModule;
 import com.android.dialer.feedback.stub.StubFeedbackModule;
@@ -57,6 +58,7 @@
       CallLogModule.class,
       CallLogConfigModule.class,
       CommandLineModule.class,
+      ContactsModule.class,
       ContextModule.class,
       DialerExecutorModule.class,
       GlidePhotoManagerModule.class,
diff --git a/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java b/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
index 666a0be..acf14b1 100644
--- a/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
+++ b/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
@@ -25,6 +25,7 @@
 import com.android.dialer.commandline.CommandLineComponent;
 import com.android.dialer.common.concurrent.DialerExecutorComponent;
 import com.android.dialer.configprovider.ConfigProviderComponent;
+import com.android.dialer.contacts.ContactsComponent;
 import com.android.dialer.duo.DuoComponent;
 import com.android.dialer.enrichedcall.EnrichedCallComponent;
 import com.android.dialer.feedback.FeedbackComponent;
@@ -62,6 +63,7 @@
         CallLogUiComponent.HasComponent,
         ConfigProviderComponent.HasComponent,
         CommandLineComponent.HasComponent,
+        ContactsComponent.HasComponent,
         DialerExecutorComponent.HasComponent,
         DuoComponent.HasComponent,
         EnrichedCallComponent.HasComponent,
diff --git a/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java b/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
index 622bd5d..35e7809 100644
--- a/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
+++ b/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
@@ -24,6 +24,7 @@
 import com.android.dialer.commandline.CommandLineModule;
 import com.android.dialer.common.concurrent.DialerExecutorModule;
 import com.android.dialer.configprovider.SharedPrefConfigProviderModule;
+import com.android.dialer.contacts.ContactsModule;
 import com.android.dialer.duo.stub.StubDuoModule;
 import com.android.dialer.enrichedcall.stub.StubEnrichedCallModule;
 import com.android.dialer.feedback.stub.StubFeedbackModule;
@@ -62,6 +63,7 @@
       CallLogConfigModule.class,
       CommandLineModule.class,
       ContextModule.class,
+      ContactsModule.class,
       DialerExecutorModule.class,
       GlidePhotoManagerModule.class,
       MapsModule.class,
diff --git a/java/com/android/dialer/calllogutils/PhoneCallDetails.java b/java/com/android/dialer/calllogutils/PhoneCallDetails.java
index fe8bfde..7212fa9 100644
--- a/java/com/android/dialer/calllogutils/PhoneCallDetails.java
+++ b/java/com/android/dialer/calllogutils/PhoneCallDetails.java
@@ -25,8 +25,8 @@
 import android.telecom.PhoneAccountHandle;
 import android.text.TextUtils;
 import com.android.contacts.common.ContactsUtils.UserType;
-import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.contacts.common.util.ContactDisplayUtils;
+import com.android.dialer.contacts.displaypreference.ContactDisplayPreferences.DisplayOrder;
 import com.android.dialer.logging.ContactSource;
 import com.android.dialer.phonenumbercache.ContactInfo;
 
@@ -65,7 +65,7 @@
    * The user's preference on name display order, last name first or first time first. {@see
    * ContactsPreferences}
    */
-  public int nameDisplayOrder;
+  public DisplayOrder nameDisplayOrder;
   // The type of phone, e.g., {@link Phone#TYPE_HOME}, 0 if not available.
   public int numberType;
   // The custom label associated with the phone number in the contact, or the empty string.
@@ -183,8 +183,7 @@
    * @return the preferred name
    */
   public CharSequence getPreferredName() {
-    if (nameDisplayOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY
-        || TextUtils.isEmpty(nameAlternative)) {
+    if (nameDisplayOrder == DisplayOrder.PRIMARY || TextUtils.isEmpty(nameAlternative)) {
       return namePrimary;
     }
     return nameAlternative;
diff --git a/java/com/android/dialer/contacts/ContactsComponent.java b/java/com/android/dialer/contacts/ContactsComponent.java
new file mode 100644
index 0000000..5c4097a
--- /dev/null
+++ b/java/com/android/dialer/contacts/ContactsComponent.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.contacts;
+
+import android.content.Context;
+import com.android.dialer.contacts.displaypreference.ContactDisplayPreferences;
+import com.android.dialer.inject.HasRootComponent;
+import dagger.Subcomponent;
+
+/** Component for contacts related utilities */
+@Subcomponent
+public abstract class ContactsComponent {
+
+  public abstract ContactDisplayPreferences contactDisplayPreferences();
+
+  public static ContactsComponent get(Context context) {
+    return ((HasComponent) ((HasRootComponent) context.getApplicationContext()).component())
+        .contactsComponent();
+  }
+
+  /** Used to refer to the root application component. */
+  public interface HasComponent {
+    ContactsComponent contactsComponent();
+  }
+}
diff --git a/java/com/android/dialer/contacts/ContactsModule.java b/java/com/android/dialer/contacts/ContactsModule.java
new file mode 100644
index 0000000..979c525
--- /dev/null
+++ b/java/com/android/dialer/contacts/ContactsModule.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.contacts;
+
+import com.android.dialer.contacts.displaypreference.ContactDisplayPreferences;
+import com.android.dialer.contacts.displaypreference.ContactDisplayPreferencesImpl;
+import com.android.dialer.inject.DialerVariant;
+import com.android.dialer.inject.InstallIn;
+import dagger.Binds;
+import dagger.Module;
+
+/** Module for standard {@link ContactsComponent} */
+@InstallIn(variants = {DialerVariant.DIALER_TEST})
+@Module
+public abstract class ContactsModule {
+  @Binds
+  public abstract ContactDisplayPreferences to(ContactDisplayPreferencesImpl impl);
+}
diff --git a/java/com/android/dialer/contacts/displaypreference/AndroidManifest.xml b/java/com/android/dialer/contacts/displaypreference/AndroidManifest.xml
new file mode 100644
index 0000000..2751461
--- /dev/null
+++ b/java/com/android/dialer/contacts/displaypreference/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<manifest
+    package="com.android.dialer.contacts.displaypreference">
+</manifest>
\ No newline at end of file
diff --git a/java/com/android/dialer/contacts/displaypreference/ContactDisplayPreferences.java b/java/com/android/dialer/contacts/displaypreference/ContactDisplayPreferences.java
new file mode 100644
index 0000000..dca466e
--- /dev/null
+++ b/java/com/android/dialer/contacts/displaypreference/ContactDisplayPreferences.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.contacts.displaypreference;
+
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.text.TextUtils;
+import java.util.Arrays;
+
+/** Handles name ordering of a contact (Given name first or family name first.) */
+public interface ContactDisplayPreferences {
+
+  /**
+   * A enum whose value is a String from a Android string resource which can only be resolved at run
+   * time.
+   */
+  interface StringResEnum {
+
+    @StringRes
+    int getStringRes();
+
+    default String getValue(Context context) {
+      return context.getString(getStringRes());
+    }
+
+    static <T extends Enum<T> & StringResEnum> T fromValue(
+        Context context, T[] values, String value) {
+      return Arrays.stream(values)
+          .filter(enumValue -> TextUtils.equals(enumValue.getValue(context), value))
+          // MoreCollectors.onlyElement() is not available to android guava.
+          .reduce(
+              (a, b) -> {
+                throw new AssertionError("multiple result");
+              })
+          .get();
+    }
+  }
+
+  /** Order when displaying the name; */
+  enum DisplayOrder implements StringResEnum {
+
+    /**
+     * The default display order of a name. For western names it will be "Given Family". For
+     * unstructured names like east asian this will be the only order.
+     *
+     * @see android.provider.ContactsContract.Contacts#DISPLAY_NAME_PRIMARY
+     */
+    PRIMARY(R.string.display_options_view_given_name_first_value),
+    /**
+     * The alternative display order of a name. For western names it will be "Family, Given". For
+     * unstructured names like east asian this order will be ignored and treated as primary.
+     *
+     * @see android.provider.ContactsContract.Contacts#DISPLAY_NAME_ALTERNATIVE
+     */
+    ALTERNATIVE(R.string.display_options_view_family_name_first_value);
+
+    @StringRes private final int value;
+
+    DisplayOrder(@StringRes int value) {
+      this.value = value;
+    }
+
+    @Override
+    @StringRes
+    public int getStringRes() {
+      return value;
+    }
+
+    static DisplayOrder fromValue(Context context, String value) {
+      return StringResEnum.fromValue(context, DisplayOrder.values(), value);
+    }
+  }
+
+  /**
+   * Order when sorting the name. In some conventions, names are displayed as given name first, but
+   * sorted by family name.
+   */
+  enum SortOrder implements StringResEnum {
+    /**
+     * Sort by the default display order of a name. For western names it will be "Given Family". For
+     * unstructured names like east asian this will be the only order.
+     *
+     * @see android.provider.ContactsContract.Contacts#DISPLAY_NAME_PRIMARY
+     */
+    BY_PRIMARY(R.string.display_options_sort_by_given_name_value),
+    /**
+     * Sort by the alternative display order of a name. For western names it will be "Family,
+     * Given". For unstructured names like east asian this order will be ignored and treated as
+     * primary.
+     *
+     * @see android.provider.ContactsContract.Contacts#DISPLAY_NAME_ALTERNATIVE
+     */
+    BY_ALTERNATIVE(R.string.display_options_sort_by_family_name_value);
+
+    @StringRes private final int value;
+
+    SortOrder(@StringRes int value) {
+      this.value = value;
+    }
+
+    @Override
+    @StringRes
+    public int getStringRes() {
+      return value;
+    }
+
+    static SortOrder fromValue(Context context, String value) {
+      return StringResEnum.fromValue(context, SortOrder.values(), value);
+    }
+  }
+
+  DisplayOrder getDisplayOrder();
+
+  void setDisplayOrder(DisplayOrder displayOrder);
+
+  SortOrder getSortOrder();
+
+  void setSortOrder(SortOrder sortOrder);
+
+  /** Selects display name based on {@link DisplayOrder} */
+  default String getDisplayName(@Nullable String primaryName, @Nullable String alternativeName) {
+    if (TextUtils.isEmpty(alternativeName)) {
+      return primaryName;
+    }
+    switch (getDisplayOrder()) {
+      case PRIMARY:
+        return primaryName;
+      case ALTERNATIVE:
+        return alternativeName;
+    }
+    throw new AssertionError("exhaustive switch");
+  }
+
+  /** Selects sort name based on {@link SortOrder} */
+  default String getSortName(@Nullable String primaryName, @Nullable String alternativeName) {
+    if (TextUtils.isEmpty(alternativeName)) {
+      return primaryName;
+    }
+    switch (getSortOrder()) {
+      case BY_PRIMARY:
+        return primaryName;
+      case BY_ALTERNATIVE:
+        return alternativeName;
+    }
+    throw new AssertionError("exhaustive switch");
+  }
+}
diff --git a/java/com/android/dialer/contacts/displaypreference/ContactDisplayPreferencesImpl.java b/java/com/android/dialer/contacts/displaypreference/ContactDisplayPreferencesImpl.java
new file mode 100644
index 0000000..6072cc1
--- /dev/null
+++ b/java/com/android/dialer/contacts/displaypreference/ContactDisplayPreferencesImpl.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.contacts.displaypreference;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.UserManager;
+import android.preference.PreferenceManager;
+import com.android.dialer.inject.ApplicationContext;
+import javax.inject.Inject;
+
+/** Implementation of {@link ContactDisplayPreferences} backed by a {@link SharedPreferences} */
+public final class ContactDisplayPreferencesImpl implements ContactDisplayPreferences {
+
+  private final Context appContext;
+  private final SharedPreferences sharedPreferences;
+  private final String displayOrderKey;
+  private final String sortOrderKey;
+
+  @Inject
+  ContactDisplayPreferencesImpl(@ApplicationContext Context appContext) {
+    this.appContext = appContext;
+    // @Unencrypted preference would be a better choice, but Android Preference only supports the
+    // default file. Names cannot be shown on @Unencrypted anyway.
+    this.sharedPreferences = PreferenceManager.getDefaultSharedPreferences(appContext);
+    displayOrderKey = appContext.getString(R.string.display_options_view_names_as_key);
+    sortOrderKey = appContext.getString(R.string.display_options_sort_list_by_key);
+  }
+
+  @Override
+  public DisplayOrder getDisplayOrder() {
+    migrate();
+    if (!sharedPreferences.contains(displayOrderKey)) {
+      return DisplayOrder.PRIMARY;
+    }
+    return DisplayOrder.fromValue(appContext, sharedPreferences.getString(displayOrderKey, null));
+  }
+
+  @Override
+  public void setDisplayOrder(DisplayOrder displayOrder) {
+    sharedPreferences.edit().putString(displayOrderKey, displayOrder.getValue(appContext)).apply();
+  }
+
+  @Override
+  public SortOrder getSortOrder() {
+    migrate();
+    if (!sharedPreferences.contains(sortOrderKey)) {
+      return SortOrder.BY_PRIMARY;
+    }
+    return SortOrder.fromValue(appContext, sharedPreferences.getString(sortOrderKey, null));
+  }
+
+  @Override
+  public void setSortOrder(SortOrder sortOrder) {
+    sharedPreferences.edit().putString(sortOrderKey, sortOrder.getValue(appContext)).apply();
+  }
+
+  /**
+   * Moves the stored values to the standard location.
+   *
+   * <p>Usually preferences are stored in {@code package.name_preferences.xml}. However the old
+   * com.android.contacts.common.preference.ContactsPreferences stored it in {@code
+   * package.name.xml} which is incompatible with the regular {@link android.preference.Preference}
+   * widgets.
+   */
+  private void migrate() {
+    if (!appContext.getSystemService(UserManager.class).isUserUnlocked()) {
+      return;
+    }
+    SharedPreferences oldPreference =
+        appContext.getSharedPreferences(appContext.getPackageName(), Context.MODE_PRIVATE);
+    if (oldPreference.contains(displayOrderKey) || oldPreference.contains(sortOrderKey)) {
+      sharedPreferences
+          .edit()
+          .putString(
+              displayOrderKey,
+              translateLegacyDisplayOrder(oldPreference.getInt(displayOrderKey, 1)))
+          .putString(sortOrderKey, translateLegacySortOrder(oldPreference.getInt(sortOrderKey, 1)))
+          .apply();
+      oldPreference.edit().remove(displayOrderKey).remove(sortOrderKey).apply();
+    }
+  }
+
+  private String translateLegacyDisplayOrder(int legacyValue) {
+    switch (legacyValue) {
+      case 2:
+        return DisplayOrder.ALTERNATIVE.getValue(appContext);
+      default:
+        return DisplayOrder.PRIMARY.getValue(appContext);
+    }
+  }
+
+  private String translateLegacySortOrder(int legacyValue) {
+    switch (legacyValue) {
+      case 2:
+        return SortOrder.BY_ALTERNATIVE.getValue(appContext);
+      default:
+        return SortOrder.BY_PRIMARY.getValue(appContext);
+    }
+  }
+}
diff --git a/java/com/android/dialer/contacts/displaypreference/res/values/display_preference.xml b/java/com/android/dialer/contacts/displaypreference/res/values/display_preference.xml
new file mode 100644
index 0000000..b74b8b9
--- /dev/null
+++ b/java/com/android/dialer/contacts/displaypreference/res/values/display_preference.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<resources>
+  <string-array name="contact_display_order_entries">
+    <item>@string/display_options_view_given_name_first</item>
+    <item>@string/display_options_view_family_name_first</item>
+  </string-array>
+
+  <string-array name="contact_display_order_values">
+    <item>@string/display_options_view_given_name_first_value</item>
+    <item>@string/display_options_view_family_name_first_value</item>
+  </string-array>
+
+  <string-array name="contact_sort_order_entries">
+    <item>@string/display_options_sort_by_given_name</item>
+    <item>@string/display_options_sort_by_family_name</item>
+  </string-array>
+
+  <string-array name="contact_sort_order_values">
+    <item>@string/display_options_sort_by_given_name_value</item>
+    <item>@string/display_options_sort_by_family_name_value</item>
+  </string-array>
+</resources>
\ No newline at end of file
diff --git a/java/com/android/dialer/contacts/displaypreference/res/values/strings.xml b/java/com/android/dialer/contacts/displaypreference/res/values/strings.xml
new file mode 100644
index 0000000..8914ddf
--- /dev/null
+++ b/java/com/android/dialer/contacts/displaypreference/res/values/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <!-- Contact preferences related strings -->
+
+  <!-- Label of the "sort by" display option -->
+  <string name="display_options_sort_list_by">Sort by</string>
+
+  <string translatable="false" name="display_options_sort_list_by_key">android.contacts.SORT_ORDER</string>
+
+  <!-- An allowable value for the "sort list by" contact display option  -->
+  <string name="display_options_sort_by_given_name">First name</string>
+
+  <string translatable="false" name="display_options_sort_by_given_name_value">sort_by_given_name</string>
+
+  <!-- An allowable value for the "sort list by" contact display option  -->
+  <string name="display_options_sort_by_family_name">Last name</string>
+
+  <string translatable="false" name="display_options_sort_by_family_name_value">sort_by_family_name</string>
+
+  <!-- Label of the "name format" display option [CHAR LIMIT=64]-->
+  <string name="display_options_view_names_as">Name format</string>
+  <string translatable="false" name="display_options_view_names_as_key">android.contacts.DISPLAY_ORDER</string>
+
+  <!-- An allowable value for the "view names as" contact display option  -->
+  <string name="display_options_view_given_name_first">First name first</string>
+
+  <string translatable="false" name="display_options_view_given_name_first_value">view_given_name_first</string>
+
+  <!-- An allowable value for the "view names as" contact display option  -->
+  <string name="display_options_view_family_name_first">Last name first</string>
+
+  <string translatable="false" name="display_options_view_family_name_first_value">view_family_name_first</string>
+</resources>
diff --git a/java/com/android/dialer/contactsfragment/ContactsCursorLoader.java b/java/com/android/dialer/contactsfragment/ContactsCursorLoader.java
index e55f951..d74afe5 100644
--- a/java/com/android/dialer/contactsfragment/ContactsCursorLoader.java
+++ b/java/com/android/dialer/contactsfragment/ContactsCursorLoader.java
@@ -21,7 +21,7 @@
 import android.net.Uri;
 import android.provider.ContactsContract.Contacts;
 import android.text.TextUtils;
-import com.android.contacts.common.preference.ContactsPreferences;
+import com.android.dialer.contacts.ContactsComponent;
 
 /** Cursor Loader for {@link ContactsFragment}. */
 final class ContactsCursorLoader extends CursorLoader {
@@ -61,12 +61,13 @@
   }
 
   private static String[] getProjection(Context context) {
-    ContactsPreferences contactsPrefs = new ContactsPreferences(context);
-    boolean displayOrderPrimary =
-        (contactsPrefs.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY);
-    return displayOrderPrimary
-        ? CONTACTS_PROJECTION_DISPLAY_NAME_PRIMARY
-        : CONTACTS_PROJECTION_DISPLAY_NAME_ALTERNATIVE;
+    switch (ContactsComponent.get(context).contactDisplayPreferences().getDisplayOrder()) {
+      case PRIMARY:
+        return CONTACTS_PROJECTION_DISPLAY_NAME_PRIMARY;
+      case ALTERNATIVE:
+        return CONTACTS_PROJECTION_DISPLAY_NAME_ALTERNATIVE;
+    }
+    throw new AssertionError("exhaustive switch");
   }
 
   private static String getWhere(Context context, boolean hasPhoneNumbers) {
@@ -78,10 +79,14 @@
   }
 
   private static String getSortKey(Context context) {
-    ContactsPreferences contactsPrefs = new ContactsPreferences(context);
-    boolean sortOrderPrimary =
-        (contactsPrefs.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY);
-    return sortOrderPrimary ? Contacts.SORT_KEY_PRIMARY : Contacts.SORT_KEY_ALTERNATIVE;
+
+    switch (ContactsComponent.get(context).contactDisplayPreferences().getSortOrder()) {
+      case BY_PRIMARY:
+        return Contacts.SORT_KEY_PRIMARY;
+      case BY_ALTERNATIVE:
+        return Contacts.SORT_KEY_ALTERNATIVE;
+    }
+    throw new AssertionError("exhaustive switch");
   }
 
   /** Update cursor loader to filter contacts based on the provided query. */
diff --git a/java/com/android/dialer/contactsfragment/ContactsFragment.java b/java/com/android/dialer/contactsfragment/ContactsFragment.java
index 794a5b9..f40abec 100644
--- a/java/com/android/dialer/contactsfragment/ContactsFragment.java
+++ b/java/com/android/dialer/contactsfragment/ContactsFragment.java
@@ -41,8 +41,6 @@
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
-import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.common.preference.ContactsPreferences.ChangeListener;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.FragmentUtils;
 import com.android.dialer.common.LogUtil;
@@ -60,8 +58,7 @@
 public class ContactsFragment extends Fragment
     implements LoaderCallbacks<Cursor>,
         OnScrollChangeListener,
-        OnEmptyViewActionButtonClickedListener,
-        ChangeListener {
+        OnEmptyViewActionButtonClickedListener {
 
   /** An enum for the different types of headers that be inserted at position 0 in the list. */
   @Retention(RetentionPolicy.SOURCE)
@@ -98,7 +95,6 @@
 
   private @Header int header;
 
-  private ContactsPreferences contactsPrefs;
   private boolean hasPhoneNumbers;
   private String query;
 
@@ -154,8 +150,6 @@
   @Override
   public void onCreate(@Nullable Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
-    contactsPrefs = new ContactsPreferences(getContext());
-    contactsPrefs.registerChangeListener(this);
     header = getArguments().getInt(EXTRA_HEADER);
     hasPhoneNumbers = getArguments().getBoolean(EXTRA_HAS_PHONE_NUMBERS);
     if (savedInstanceState == null) {
@@ -224,7 +218,8 @@
   }
 
   @Override
-  public void onChange() {
+  public void onResume() {
+    super.onResume();
     if (getActivity() != null
         && isAdded()
         && PermissionsUtil.hasContactsReadPermissions(getContext())) {
@@ -268,7 +263,6 @@
     recyclerView.setAdapter(null);
     recyclerView.setOnScrollChangeListener(null);
     adapter = null;
-    contactsPrefs.unregisterChangeListener();
   }
 
   /*
diff --git a/java/com/android/dialer/searchfragment/cp2/SearchContactsCursorLoader.java b/java/com/android/dialer/searchfragment/cp2/SearchContactsCursorLoader.java
index 7caa314..f4ed21e 100644
--- a/java/com/android/dialer/searchfragment/cp2/SearchContactsCursorLoader.java
+++ b/java/com/android/dialer/searchfragment/cp2/SearchContactsCursorLoader.java
@@ -27,8 +27,10 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.text.TextUtils;
-import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.dialer.common.LogUtil;
+import com.android.dialer.contacts.ContactsComponent;
+import com.android.dialer.contacts.displaypreference.ContactDisplayPreferences.DisplayOrder;
+import com.android.dialer.contacts.displaypreference.ContactDisplayPreferences.SortOrder;
 import com.android.dialer.searchfragment.common.Projections;
 import com.android.dialer.searchfragment.common.SearchCursor;
 import com.android.dialer.smartdial.SmartDialCursorLoader;
@@ -55,9 +57,9 @@
   }
 
   private static String[] getProjection(Context context) {
-    ContactsPreferences contactsPrefs = new ContactsPreferences(context);
     boolean displayOrderPrimary =
-        (contactsPrefs.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY);
+        (ContactsComponent.get(context).contactDisplayPreferences().getDisplayOrder()
+            == DisplayOrder.PRIMARY);
     return displayOrderPrimary
         ? Projections.CP2_PROJECTION
         : Projections.CP2_PROJECTION_ALTERNATIVE;
@@ -70,9 +72,9 @@
   }
 
   private static String getSortKey(Context context) {
-    ContactsPreferences contactsPrefs = new ContactsPreferences(context);
     boolean sortOrderPrimary =
-        (contactsPrefs.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY);
+        (ContactsComponent.get(context).contactDisplayPreferences().getSortOrder()
+            == SortOrder.BY_PRIMARY);
     return sortOrderPrimary ? Phone.SORT_KEY_PRIMARY : Phone.SORT_KEY_ALTERNATIVE;
   }
 
diff --git a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java
index fd6db75..65ce873 100644
--- a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java
+++ b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java
@@ -404,7 +404,7 @@
     }
 
     // If the user dismissed the prompt without granting us the permission, don't load the cursor.
-    if (!PermissionsUtil.hasLocationPermissions(getContext())) {
+    if (getContext() == null || !PermissionsUtil.hasLocationPermissions(getContext())) {
       return;
     }
 
diff --git a/java/com/android/dialer/shortcuts/DynamicShortcuts.java b/java/com/android/dialer/shortcuts/DynamicShortcuts.java
index be9e088..e39dc27 100644
--- a/java/com/android/dialer/shortcuts/DynamicShortcuts.java
+++ b/java/com/android/dialer/shortcuts/DynamicShortcuts.java
@@ -124,7 +124,7 @@
           DialerShortcut.builder()
               .setContactId(entry.id)
               .setLookupKey(entry.lookupKey)
-              .setDisplayName(entry.getPreferredDisplayName())
+              .setDisplayName(entry.getPreferredDisplayName(context))
               .setRank(rank++)
               .build();
       newDynamicShortcutsById.put(shortcut.getShortcutId(), shortcut);
diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java
index 72f0a68..b0b83ac 100644
--- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java
+++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java
@@ -31,13 +31,14 @@
 import android.support.annotation.WorkerThread;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor;
 import com.android.dialer.common.concurrent.DialerExecutor.SuccessListener;
 import com.android.dialer.common.concurrent.DialerFutureSerializer;
 import com.android.dialer.common.database.Selection;
+import com.android.dialer.contacts.displaypreference.ContactDisplayPreferences;
+import com.android.dialer.contacts.displaypreference.ContactDisplayPreferences.DisplayOrder;
 import com.android.dialer.duo.DuoComponent;
 import com.android.dialer.inject.ApplicationContext;
 import com.android.dialer.speeddial.database.SpeedDialEntry;
@@ -84,15 +85,16 @@
   private final ListeningExecutorService backgroundExecutor;
   // Used to ensure that only one refresh flow runs at a time.
   private final DialerFutureSerializer dialerFutureSerializer = new DialerFutureSerializer();
-  private final ContactsPreferences contactsPreferences;
+  private final ContactDisplayPreferences contactDisplayPreferences;
 
   @Inject
   public SpeedDialUiItemMutator(
       @ApplicationContext Context appContext,
-      @BackgroundExecutor ListeningExecutorService backgroundExecutor) {
+      @BackgroundExecutor ListeningExecutorService backgroundExecutor,
+      ContactDisplayPreferences contactDisplayPreferences) {
     this.appContext = appContext;
     this.backgroundExecutor = backgroundExecutor;
-    this.contactsPreferences = new ContactsPreferences(appContext);
+    this.contactDisplayPreferences = contactDisplayPreferences;
   }
 
   /**
@@ -183,7 +185,6 @@
   @WorkerThread
   private ImmutableList<SpeedDialUiItem> insertNewContactEntry(Uri contactUri) {
     Assert.isWorkerThread();
-    contactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY);
     try (Cursor cursor =
         appContext
             .getContentResolver()
@@ -225,7 +226,6 @@
   private ImmutableList<SpeedDialUiItem> loadSpeedDialUiItemsInternal() {
     Trace.beginSection("loadSpeedDialUiItemsInternal");
     Assert.isWorkerThread();
-    contactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY);
     Trace.beginSection("getAllEntries");
     SpeedDialEntryDao db = getSpeedDialEntryDao();
     Trace.endSection(); // getAllEntries
@@ -663,6 +663,6 @@
   }
 
   private boolean isPrimaryDisplayNameOrder() {
-    return contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY;
+    return contactDisplayPreferences.getDisplayOrder() == DisplayOrder.PRIMARY;
   }
 }
diff --git a/java/com/android/dialer/theme/common/res/values/text_styles.xml b/java/com/android/dialer/theme/common/res/values/text_styles.xml
index def5862..0d1fd85 100644
--- a/java/com/android/dialer/theme/common/res/values/text_styles.xml
+++ b/java/com/android/dialer/theme/common/res/values/text_styles.xml
@@ -33,7 +33,7 @@
 
   <style name="Dialer.TextAppearance.SubHeader" parent="TextAppearance.AppCompat">
     <item name="android:textColor">?android:attr/textColorPrimary</item>
-    <item name="android:textSize">16sp</item>
+    <item name="android:textSize">14sp</item>
     <item name="android:fontFamily">sans-serif-medium</item>
   </style>
 
diff --git a/java/com/android/incallui/CallCardPresenter.java b/java/com/android/incallui/CallCardPresenter.java
index 91255cc..b9e6744 100644
--- a/java/com/android/incallui/CallCardPresenter.java
+++ b/java/com/android/incallui/CallCardPresenter.java
@@ -44,11 +44,10 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import com.android.contacts.common.ContactsUtils;
-import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.common.util.ContactDisplayUtils;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.configprovider.ConfigProviderComponent;
+import com.android.dialer.contacts.ContactsComponent;
 import com.android.dialer.logging.DialerImpression;
 import com.android.dialer.logging.Logger;
 import com.android.dialer.multimedia.MultimediaData;
@@ -123,7 +122,6 @@
   private String secondaryNumber;
   private ContactCacheEntry primaryContactInfo;
   private ContactCacheEntry secondaryContactInfo;
-  @Nullable private ContactsPreferences contactsPreferences;
   private boolean isFullscreen = false;
   private InCallScreen inCallScreen;
   private boolean isInCallScreenReady;
@@ -159,7 +157,6 @@
   public void onInCallScreenDelegateInit(InCallScreen inCallScreen) {
     Assert.isNotNull(inCallScreen);
     this.inCallScreen = inCallScreen;
-    contactsPreferences = ContactsPreferencesFactory.newContactsPreferences(context);
 
     // Call may be null if disconnect happened already.
     DialerCall call = CallList.getInstance().getFirstCall();
@@ -184,9 +181,6 @@
   public void onInCallScreenReady() {
     LogUtil.i("CallCardPresenter.onInCallScreenReady", null);
     Assert.checkState(!isInCallScreenReady);
-    if (contactsPreferences != null) {
-      contactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY);
-    }
 
     // Contact search may have completed before ui is ready.
     if (primaryContactInfo != null) {
@@ -985,8 +979,9 @@
   /** Gets the name to display for the call. */
   private String getNameForCall(ContactCacheEntry contactInfo) {
     String preferredName =
-        ContactDisplayUtils.getPreferredDisplayName(
-            contactInfo.namePrimary, contactInfo.nameAlternative, contactsPreferences);
+        ContactsComponent.get(context)
+            .contactDisplayPreferences()
+            .getDisplayName(contactInfo.namePrimary, contactInfo.nameAlternative);
     if (TextUtils.isEmpty(preferredName)) {
       return TextUtils.isEmpty(contactInfo.number)
           ? null
diff --git a/java/com/android/incallui/ConferenceParticipantListAdapter.java b/java/com/android/incallui/ConferenceParticipantListAdapter.java
index c71bf59..d13bd3d 100644
--- a/java/com/android/incallui/ConferenceParticipantListAdapter.java
+++ b/java/com/android/incallui/ConferenceParticipantListAdapter.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.net.Uri;
-import android.support.annotation.Nullable;
 import android.support.v4.util.ArrayMap;
 import android.telephony.PhoneNumberUtils;
 import android.text.BidiFormatter;
@@ -33,11 +32,10 @@
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
-import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.common.util.ContactDisplayUtils;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.contactphoto.ContactPhotoManager;
 import com.android.dialer.contactphoto.ContactPhotoManager.DefaultImageRequest;
+import com.android.dialer.contacts.ContactsComponent;
 import com.android.incallui.ContactInfoCache.ContactCacheEntry;
 import com.android.incallui.call.CallList;
 import com.android.incallui.call.DialerCall;
@@ -59,8 +57,6 @@
   private final ListView listView;
   /** Hashmap to make accessing participant info by call Id faster. */
   private final Map<String, ParticipantInfo> participantsByCallId = new ArrayMap<>();
-  /** ContactsPreferences used to lookup displayName preferences */
-  @Nullable private final ContactsPreferences contactsPreferences;
   /** Contact photo manager to retrieve cached contact photo information. */
   private final ContactPhotoManager contactPhotoManager;
   /** Listener used to handle tap of the "disconnect' button for a participant. */
@@ -103,7 +99,6 @@
       ListView listView, ContactPhotoManager contactPhotoManager) {
 
     this.listView = listView;
-    contactsPreferences = ContactsPreferencesFactory.newContactsPreferences(getContext());
     this.contactPhotoManager = contactPhotoManager;
   }
 
@@ -116,10 +111,6 @@
    */
   public void updateParticipants(
       List<DialerCall> conferenceParticipants, boolean parentCanSeparate) {
-    if (contactsPreferences != null) {
-      contactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY);
-      contactsPreferences.refreshValue(ContactsPreferences.SORT_ORDER_KEY);
-    }
     this.parentCanSeparate = parentCanSeparate;
     updateParticipantInfo(conferenceParticipants);
   }
@@ -235,8 +226,9 @@
         call.can(android.telecom.Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE);
 
     String name =
-        ContactDisplayUtils.getPreferredDisplayName(
-            contactCache.namePrimary, contactCache.nameAlternative, contactsPreferences);
+        ContactsComponent.get(getContext())
+            .contactDisplayPreferences()
+            .getDisplayName(contactCache.namePrimary, contactCache.nameAlternative);
 
     setCallerInfoForRow(
         result,
@@ -441,14 +433,16 @@
             // Contact names might be null, so replace with empty string.
             ContactCacheEntry c1 = p1.getContactCacheEntry();
             String p1Name =
-                ContactDisplayUtils.getPreferredSortName(
-                    c1.namePrimary, c1.nameAlternative, contactsPreferences);
+                ContactsComponent.get(getContext())
+                    .contactDisplayPreferences()
+                    .getSortName(c1.namePrimary, c1.nameAlternative);
             p1Name = p1Name != null ? p1Name : "";
 
             ContactCacheEntry c2 = p2.getContactCacheEntry();
             String p2Name =
-                ContactDisplayUtils.getPreferredSortName(
-                    c2.namePrimary, c2.nameAlternative, contactsPreferences);
+                ContactsComponent.get(getContext())
+                    .contactDisplayPreferences()
+                    .getSortName(c2.namePrimary, c2.nameAlternative);
             p2Name = p2Name != null ? p2Name : "";
 
             return p1Name.compareToIgnoreCase(p2Name);
diff --git a/java/com/android/incallui/ContactsPreferencesFactory.java b/java/com/android/incallui/ContactsPreferencesFactory.java
deleted file mode 100644
index a9a2109..0000000
--- a/java/com/android/incallui/ContactsPreferencesFactory.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 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.incallui;
-
-import android.content.Context;
-import android.support.annotation.Nullable;
-import android.support.v4.os.UserManagerCompat;
-import com.android.contacts.common.preference.ContactsPreferences;
-
-/** Factory class for {@link ContactsPreferences}. */
-public class ContactsPreferencesFactory {
-
-  private static boolean useTestInstance;
-  private static ContactsPreferences testInstance;
-
-  /**
-   * Creates a new {@link ContactsPreferences} object if possible.
-   *
-   * @param context the context to use when creating the ContactsPreferences.
-   * @return a new ContactsPreferences object or {@code null} if the user is locked.
-   */
-  @Nullable
-  public static ContactsPreferences newContactsPreferences(Context context) {
-    if (useTestInstance) {
-      return testInstance;
-    }
-    if (UserManagerCompat.isUserUnlocked(context)) {
-      return new ContactsPreferences(context);
-    }
-    return null;
-  }
-
-  /**
-   * Sets the instance to be returned by all calls to {@link #newContactsPreferences(Context)}.
-   *
-   * @param testInstance the instance to return.
-   */
-  static void setTestInstance(ContactsPreferences testInstance) {
-    useTestInstance = true;
-    ContactsPreferencesFactory.testInstance = testInstance;
-  }
-}
diff --git a/java/com/android/incallui/ExternalCallNotifier.java b/java/com/android/incallui/ExternalCallNotifier.java
index 10c4a64..160e250 100644
--- a/java/com/android/incallui/ExternalCallNotifier.java
+++ b/java/com/android/incallui/ExternalCallNotifier.java
@@ -38,10 +38,9 @@
 import android.util.ArrayMap;
 import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.compat.CallCompat;
-import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.common.util.ContactDisplayUtils;
 import com.android.dialer.common.Assert;
 import com.android.dialer.contactphoto.BitmapUtil;
+import com.android.dialer.contacts.ContactsComponent;
 import com.android.dialer.notification.DialerNotificationManager;
 import com.android.dialer.notification.NotificationChannelId;
 import com.android.dialer.telecom.TelecomCallUtil;
@@ -78,13 +77,11 @@
   private final ContactInfoCache contactInfoCache;
   private Map<Call, NotificationInfo> notifications = new ArrayMap<>();
   private int nextUniqueNotificationId;
-  private ContactsPreferences contactsPreferences;
 
   /** Initializes a new instance of the external call notifier. */
   public ExternalCallNotifier(
       @NonNull Context context, @NonNull ContactInfoCache contactInfoCache) {
     this.context = context;
-    contactsPreferences = ContactsPreferencesFactory.newContactsPreferences(this.context);
     this.contactInfoCache = contactInfoCache;
   }
 
@@ -216,7 +213,7 @@
    * notification to the notification manager.
    */
   private void saveContactInfo(NotificationInfo info, ContactInfoCache.ContactCacheEntry entry) {
-    info.setContentTitle(getContentTitle(context, contactsPreferences, entry, info.getCall()));
+    info.setContentTitle(getContentTitle(context, entry, info.getCall()));
     info.setPersonReference(getPersonReference(entry, info.getCall()));
     postNotification(info);
   }
@@ -342,17 +339,12 @@
    * number.
    *
    * @param context The context.
-   * @param contactsPreferences Contacts preferences, used to determine the preferred formatting for
-   *     contact names.
    * @param contactInfo The contact info which was looked up in the contact cache.
    * @param call The call to generate a title for.
    * @return The content title.
    */
   private @Nullable String getContentTitle(
-      Context context,
-      @Nullable ContactsPreferences contactsPreferences,
-      ContactInfoCache.ContactCacheEntry contactInfo,
-      android.telecom.Call call) {
+      Context context, ContactInfoCache.ContactCacheEntry contactInfo, android.telecom.Call call) {
 
     if (call.getDetails().hasProperty(android.telecom.Call.Details.PROPERTY_CONFERENCE)) {
       return CallerInfoUtils.getConferenceString(
@@ -361,8 +353,9 @@
     }
 
     String preferredName =
-        ContactDisplayUtils.getPreferredDisplayName(
-            contactInfo.namePrimary, contactInfo.nameAlternative, contactsPreferences);
+        ContactsComponent.get(context)
+            .contactDisplayPreferences()
+            .getDisplayName(contactInfo.namePrimary, contactInfo.nameAlternative);
     if (TextUtils.isEmpty(preferredName)) {
       return TextUtils.isEmpty(contactInfo.number)
           ? null
diff --git a/java/com/android/incallui/ReturnToCallController.java b/java/com/android/incallui/ReturnToCallController.java
index 94ce8d7..addde55 100644
--- a/java/com/android/incallui/ReturnToCallController.java
+++ b/java/com/android/incallui/ReturnToCallController.java
@@ -30,9 +30,9 @@
 import com.android.bubble.BubbleComponent;
 import com.android.bubble.BubbleInfo;
 import com.android.bubble.BubbleInfo.Action;
-import com.android.contacts.common.util.ContactDisplayUtils;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.configprovider.ConfigProviderComponent;
+import com.android.dialer.contacts.ContactsComponent;
 import com.android.dialer.lettertile.LetterTileDrawable;
 import com.android.dialer.telecom.TelecomUtil;
 import com.android.dialer.theme.base.ThemeComponent;
@@ -369,10 +369,9 @@
   private LetterTileDrawable createLettleTileDrawable(
       DialerCall dialerCall, ContactCacheEntry entry) {
     String preferredName =
-        ContactDisplayUtils.getPreferredDisplayName(
-            entry.namePrimary,
-            entry.nameAlternative,
-            ContactsPreferencesFactory.newContactsPreferences(context));
+        ContactsComponent.get(context)
+            .contactDisplayPreferences()
+            .getDisplayName(entry.namePrimary, entry.nameAlternative);
     if (TextUtils.isEmpty(preferredName)) {
       preferredName = entry.number;
     }
diff --git a/java/com/android/incallui/RttRequestDialogFragment.java b/java/com/android/incallui/RttRequestDialogFragment.java
index 5437cc6..589625b 100644
--- a/java/com/android/incallui/RttRequestDialogFragment.java
+++ b/java/com/android/incallui/RttRequestDialogFragment.java
@@ -28,9 +28,9 @@
 import android.text.TextUtils;
 import android.view.View;
 import android.widget.TextView;
-import com.android.contacts.common.util.ContactDisplayUtils;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
+import com.android.dialer.contacts.ContactsComponent;
 import com.android.incallui.ContactInfoCache.ContactCacheEntry;
 import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
 import com.android.incallui.call.CallList;
@@ -130,10 +130,9 @@
 
     private CharSequence getNameOrNumber(ContactCacheEntry entry, Context context) {
       String preferredName =
-          ContactDisplayUtils.getPreferredDisplayName(
-              entry.namePrimary,
-              entry.nameAlternative,
-              ContactsPreferencesFactory.newContactsPreferences(context));
+          ContactsComponent.get(context)
+              .contactDisplayPreferences()
+              .getDisplayName(entry.namePrimary, entry.nameAlternative);
       if (TextUtils.isEmpty(preferredName)) {
         return TextUtils.isEmpty(entry.number)
             ? null
diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java
index 1d73fe8..8316d76 100644
--- a/java/com/android/incallui/StatusBarNotifier.java
+++ b/java/com/android/incallui/StatusBarNotifier.java
@@ -64,12 +64,11 @@
 import android.text.style.ForegroundColorSpan;
 import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.ContactsUtils.UserType;
-import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.common.util.ContactDisplayUtils;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.configprovider.ConfigProviderComponent;
 import com.android.dialer.contactphoto.BitmapUtil;
+import com.android.dialer.contacts.ContactsComponent;
 import com.android.dialer.enrichedcall.EnrichedCallManager;
 import com.android.dialer.enrichedcall.Session;
 import com.android.dialer.lettertile.LetterTileDrawable;
@@ -121,7 +120,6 @@
   private final Context context;
   private final ContactInfoCache contactInfoCache;
   private final DialerRingtoneManager dialerRingtoneManager;
-  @Nullable private ContactsPreferences contactsPreferences;
   private int currentNotification = NOTIFICATION_NONE;
   private int callState = DialerCallState.INVALID;
   private int videoState = VideoProfile.STATE_AUDIO_ONLY;
@@ -136,7 +134,6 @@
   public StatusBarNotifier(@NonNull Context context, @NonNull ContactInfoCache contactInfoCache) {
     Trace.beginSection("StatusBarNotifier.Constructor");
     this.context = Assert.isNotNull(context);
-    contactsPreferences = ContactsPreferencesFactory.newContactsPreferences(this.context);
     this.contactInfoCache = contactInfoCache;
     dialerRingtoneManager =
         new DialerRingtoneManager(
@@ -565,8 +562,9 @@
     }
 
     String preferredName =
-        ContactDisplayUtils.getPreferredDisplayName(
-            contactInfo.namePrimary, contactInfo.nameAlternative, contactsPreferences);
+        ContactsComponent.get(context)
+            .contactDisplayPreferences()
+            .getDisplayName(contactInfo.namePrimary, contactInfo.nameAlternative);
     if (TextUtils.isEmpty(preferredName)) {
       return TextUtils.isEmpty(contactInfo.number)
           ? null
diff --git a/java/com/android/incallui/answer/impl/res/drawable/urgent_call_background.xml b/java/com/android/incallui/answer/impl/res/drawable/urgent_call_background.xml
index d995980..7695290 100644
--- a/java/com/android/incallui/answer/impl/res/drawable/urgent_call_background.xml
+++ b/java/com/android/incallui/answer/impl/res/drawable/urgent_call_background.xml
@@ -18,5 +18,5 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle">
   <corners android:radius="24dp"/>
-  <solid android:color="#F50057"/>
+  <solid android:color="?android:attr/colorPrimary"/>
 </shape>
\ No newline at end of file
diff --git a/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml b/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml
index 1672bf9..3a68bd4 100644
--- a/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml
+++ b/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml
@@ -121,19 +121,16 @@
       <!-- TODO(a bug): textColorPrimary or textColorPrimaryInverse? -->
       <TextView
           android:id="@+id/incall_important_call_badge"
-          android:textStyle="bold"
           android:layout_width="wrap_content"
-          android:layout_height="48dp"
+          android:layout_height="32dp"
           android:layout_marginTop="4dp"
           android:layout_marginBottom="@dimen/answer_importance_margin_bottom"
           android:background="@drawable/urgent_call_background"
-          android:elevation="@dimen/answer_data_elevation"
           android:gravity="center"
           android:maxLines="1"
           android:text="@string/call_incoming_important"
-          android:textAllCaps="true"
-          android:textColor="?android:attr/colorBackground"
-          android:textSize="14sp"/>
+          style="@style/Dialer.TextAppearance.SubHeader"
+          android:textColor="?android:attr/colorBackground"/>
 
       <FrameLayout
           android:id="@+id/incall_location_holder"
diff --git a/java/com/android/incallui/incall/impl/CheckableLabeledButton.java b/java/com/android/incallui/incall/impl/CheckableLabeledButton.java
index 4e8fa82..d4aba4c 100644
--- a/java/com/android/incallui/incall/impl/CheckableLabeledButton.java
+++ b/java/com/android/incallui/incall/impl/CheckableLabeledButton.java
@@ -39,7 +39,6 @@
 public class CheckableLabeledButton extends LinearLayout implements Checkable {
 
   private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};
-  private static final float DISABLED_STATE_OPACITY = .3f;
   private boolean broadcasting;
   private boolean isChecked;
   private OnCheckedChangeListener onCheckedChangeListener;
@@ -124,13 +123,6 @@
     setOutlineProvider(null);
   }
 
-  @Override
-  public void refreshDrawableState() {
-    super.refreshDrawableState();
-    iconView.setAlpha(isEnabled() ? 1f : DISABLED_STATE_OPACITY);
-    labelView.setAlpha(isEnabled() ? 1f : DISABLED_STATE_OPACITY);
-  }
-
   public Drawable getIconDrawable() {
     return iconView.getDrawable();
   }
diff --git a/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java b/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java
index 6ac2337..3bbda47 100644
--- a/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java
+++ b/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java
@@ -210,6 +210,7 @@
       clickSubscribeLink(subscribeLink);
     } catch (ProvisioningException e) {
       VvmLog.e(TAG, e.toString());
+      helper.handleEvent(status, OmtpEvents.CONFIG_SERVICE_NOT_AVAILABLE);
       task.fail();
     }
   }
diff --git a/packages.mk b/packages.mk
index f2b1c7e..1be1f83 100644
--- a/packages.mk
+++ b/packages.mk
@@ -30,6 +30,7 @@
 	com.android.dialer.common.concurrent.testing \
 	com.android.dialer.common.preference \
 	com.android.dialer.configprovider \
+	com.android.dialer.contacts.displaypreference \
 	com.android.dialer.contactphoto \
 	com.android.dialer.contactsfragment \
 	com.android.dialer.databasepopulator \