Make ContactPreferences use SharedPreferences instead of System settings (2/5)

* Move constants that originally lived in the framework into ContactsCommon
* Use SharedPreferences instead of System settings to persist preferences
* Use a SharedPreferenceListener to monitor changes instead of a content observer
on system settings
* Move DisplayOrderPreference and SortOrderPreference into ContactsCommon so that
it can be used by Dialer
* Create base DialerSettingsActivity in Dialer, and make GoogleDialerSettingsActivity
extend it
Bug: 16153186

Change-Id: Ibaacc26619889e28db7b4b30ee37a00827dd48e4
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 085cacf..0683190 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -370,24 +370,6 @@
     <!-- Text used to explain that a group cannot be edited since the data is read only [CHAR LIMIT=40] -->
     <string name="group_read_only">Not editable on this device.</string>
 
-    <!-- Label of the "sort list by" display option -->
-    <string name="display_options_sort_list_by">Sort list by</string>
-
-    <!-- An allowable value for the "sort list by" contact display option  -->
-    <string name="display_options_sort_by_given_name">Given name</string>
-
-    <!-- An allowable value for the "sort list by" contact display option  -->
-    <string name="display_options_sort_by_family_name">Family name</string>
-
-    <!-- Label of the "view names as" display option [CHAR LIMIT=64]-->
-    <string name="display_options_view_names_as">View contact names</string>
-
-    <!-- An allowable value for the "view names as" contact display option  -->
-    <string name="display_options_view_given_name_first">Given name first</string>
-
-    <!-- An allowable value for the "view names as" contact display option  -->
-    <string name="display_options_view_family_name_first">Family name first</string>
-
     <!-- An option in the 'Contact photo' dialog, if there is no photo yet [CHAR LIMIT=50] -->
     <string name="take_photo">Take photo</string>
 
diff --git a/res/xml/preference_display_options.xml b/res/xml/preference_display_options.xml
deleted file mode 100644
index 4ec31b2..0000000
--- a/res/xml/preference_display_options.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
-    <com.android.contacts.preference.SortOrderPreference
-        android:key="sortOrder"
-        android:title="@string/display_options_sort_list_by"
-        android:dialogTitle="@string/display_options_sort_list_by" />
-
-    <com.android.contacts.preference.DisplayOrderPreference
-        android:key="displayOrder"
-        android:title="@string/display_options_view_names_as"
-        android:dialogTitle="@string/display_options_view_names_as" />
-</PreferenceScreen>
diff --git a/res/xml/preference_headers.xml b/res/xml/preference_headers.xml
index ed709fc..98019fd 100644
--- a/res/xml/preference_headers.xml
+++ b/res/xml/preference_headers.xml
@@ -18,7 +18,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android">
 
     <header
-        android:fragment="com.android.contacts.preference.DisplayOptionsPreferenceFragment"
+        android:fragment="com.android.contacts.common.preference.DisplayOptionsPreferenceFragment"
         android:title="@string/preference_displayOptions" />
 
 </preference-headers>
diff --git a/src/com/android/contacts/GroupMemberLoader.java b/src/com/android/contacts/GroupMemberLoader.java
index e52ddda..6001f2c 100644
--- a/src/com/android/contacts/GroupMemberLoader.java
+++ b/src/com/android/contacts/GroupMemberLoader.java
@@ -95,7 +95,7 @@
         setSelectionArgs(createSelectionArgs());
 
         ContactsPreferences prefs = new ContactsPreferences(context);
-        if (prefs.getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
+        if (prefs.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) {
             setSortOrder(Contacts.SORT_KEY_PRIMARY);
         } else {
             setSortOrder(Contacts.SORT_KEY_ALTERNATIVE);
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index ed13950..5759350 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -62,12 +62,12 @@
 import com.android.contacts.list.ContactsUnavailableFragment;
 import com.android.contacts.list.DefaultContactBrowseListFragment;
 import com.android.contacts.common.list.DirectoryListLoader;
+import com.android.contacts.common.preference.DisplayOptionsPreferenceFragment;
 import com.android.contacts.list.OnContactBrowserActionListener;
 import com.android.contacts.list.OnContactsUnavailableActionListener;
 import com.android.contacts.list.ProviderStatusWatcher;
 import com.android.contacts.list.ProviderStatusWatcher.ProviderStatusListener;
 import com.android.contacts.preference.ContactsPreferenceActivity;
-import com.android.contacts.preference.DisplayOptionsPreferenceFragment;
 import com.android.contacts.common.util.AccountFilterUtil;
 import com.android.contacts.common.util.ViewUtil;
 import com.android.contacts.quickcontact.QuickContactActivity;
diff --git a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
index 67d14e2..2684af7 100644
--- a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
+++ b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
@@ -34,7 +34,6 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.provider.ContactsContract.DisplayNameSources;
-import android.provider.ContactsContract.Preferences;
 import android.text.Html;
 import android.text.TextUtils;
 import android.util.Log;
@@ -61,7 +60,7 @@
     public static CharSequence getDisplayName(Context context, Contact contactData) {
         ContactsPreferences prefs = new ContactsPreferences(context);
         final CharSequence displayName = contactData.getDisplayName();
-        if (prefs.getDisplayOrder() == Preferences.DISPLAY_ORDER_PRIMARY) {
+        if (prefs.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
             if (!TextUtils.isEmpty(displayName)) {
                 return displayName;
             }
diff --git a/src/com/android/contacts/list/EmailAddressListAdapter.java b/src/com/android/contacts/list/EmailAddressListAdapter.java
index 9d5ae7a..5396364 100644
--- a/src/com/android/contacts/list/EmailAddressListAdapter.java
+++ b/src/com/android/contacts/list/EmailAddressListAdapter.java
@@ -32,6 +32,7 @@
 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
 import com.android.contacts.common.list.ContactEntryListAdapter;
 import com.android.contacts.common.list.ContactListItemView;
+import com.android.contacts.common.preference.ContactsPreferences;
 
 /**
  * A cursor adapter for the {@link Email#CONTENT_TYPE} content type.
@@ -94,13 +95,13 @@
         builder.appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true");
         loader.setUri(builder.build());
 
-        if (getContactNameDisplayOrder() == ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY) {
+        if (getContactNameDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
             loader.setProjection(EmailQuery.PROJECTION_PRIMARY);
         } else {
             loader.setProjection(EmailQuery.PROJECTION_ALTERNATIVE);
         }
 
-        if (getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
+        if (getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) {
             loader.setSortOrder(Email.SORT_KEY_PRIMARY);
         } else {
             loader.setSortOrder(Email.SORT_KEY_ALTERNATIVE);
diff --git a/src/com/android/contacts/list/JoinContactListAdapter.java b/src/com/android/contacts/list/JoinContactListAdapter.java
index 597a7c3..a9c9c94 100644
--- a/src/com/android/contacts/list/JoinContactListAdapter.java
+++ b/src/com/android/contacts/list/JoinContactListAdapter.java
@@ -34,6 +34,7 @@
 import com.android.contacts.common.list.ContactListAdapter;
 import com.android.contacts.common.list.ContactListItemView;
 import com.android.contacts.common.list.DirectoryListLoader;
+import com.android.contacts.common.preference.ContactsPreferences;
 
 public class JoinContactListAdapter extends ContactListAdapter {
 
@@ -101,7 +102,7 @@
         loader.setUri(allContactsUri);
         loader.setSelection(Contacts._ID + "!=?");
         loader.setSelectionArgs(new String[]{ String.valueOf(mTargetContactId) });
-        if (getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
+        if (getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) {
             loader.setSortOrder(Contacts.SORT_KEY_PRIMARY);
         } else {
             loader.setSortOrder(Contacts.SORT_KEY_ALTERNATIVE);
diff --git a/src/com/android/contacts/list/PostalAddressListAdapter.java b/src/com/android/contacts/list/PostalAddressListAdapter.java
index d011430..35fccfe 100644
--- a/src/com/android/contacts/list/PostalAddressListAdapter.java
+++ b/src/com/android/contacts/list/PostalAddressListAdapter.java
@@ -31,6 +31,7 @@
 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
 import com.android.contacts.common.list.ContactEntryListAdapter;
 import com.android.contacts.common.list.ContactListItemView;
+import com.android.contacts.common.preference.ContactsPreferences;
 
 /**
  * A cursor adapter for the {@link StructuredPostal#CONTENT_TYPE} content type.
@@ -84,13 +85,13 @@
         }
         loader.setUri(builder.build());
 
-        if (getContactNameDisplayOrder() == ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY) {
+        if (getContactNameDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
             loader.setProjection(PostalQuery.PROJECTION_PRIMARY);
         } else {
             loader.setProjection(PostalQuery.PROJECTION_ALTERNATIVE);
         }
 
-        if (getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
+        if (getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) {
             loader.setSortOrder(StructuredPostal.SORT_KEY_PRIMARY);
         } else {
             loader.setSortOrder(StructuredPostal.SORT_KEY_ALTERNATIVE);
diff --git a/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java b/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java
deleted file mode 100644
index 02177d2..0000000
--- a/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java
+++ /dev/null
@@ -1,37 +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.preference;
-
-import android.os.Bundle;
-import android.preference.PreferenceFragment;
-
-import com.android.contacts.R;
-
-/**
- * This fragment shows the preferences for the first header.
- */
-public class DisplayOptionsPreferenceFragment extends PreferenceFragment {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Load the preferences from an XML resource
-        addPreferencesFromResource(R.xml.preference_display_options);
-    }
-}
-
diff --git a/src/com/android/contacts/preference/DisplayOrderPreference.java b/src/com/android/contacts/preference/DisplayOrderPreference.java
deleted file mode 100644
index 81489a0..0000000
--- a/src/com/android/contacts/preference/DisplayOrderPreference.java
+++ /dev/null
@@ -1,92 +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.preference;
-
-import android.app.AlertDialog.Builder;
-import android.content.Context;
-import android.preference.ListPreference;
-import android.provider.ContactsContract;
-import android.util.AttributeSet;
-
-import com.android.contacts.R;
-import com.android.contacts.common.preference.ContactsPreferences;
-
-/**
- * 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(ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY),
-                String.valueOf(ContactsContract.Preferences.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 ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY:
-                return mContext.getString(R.string.display_options_view_given_name_first);
-            case ContactsContract.Preferences.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/src/com/android/contacts/preference/SortOrderPreference.java b/src/com/android/contacts/preference/SortOrderPreference.java
deleted file mode 100644
index da51eed..0000000
--- a/src/com/android/contacts/preference/SortOrderPreference.java
+++ /dev/null
@@ -1,92 +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.preference;
-
-import android.app.AlertDialog.Builder;
-import android.content.Context;
-import android.preference.ListPreference;
-import android.provider.ContactsContract;
-import android.util.AttributeSet;
-
-import com.android.contacts.R;
-import com.android.contacts.common.preference.ContactsPreferences;
-
-/**
- * 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(ContactsContract.Preferences.SORT_ORDER_PRIMARY),
-                String.valueOf(ContactsContract.Preferences.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 ContactsContract.Preferences.SORT_ORDER_PRIMARY:
-                return mContext.getString(R.string.display_options_sort_by_given_name);
-            case ContactsContract.Preferences.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/tests/src/com/android/contacts/activities/PeopleActivityTest.java b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
index 4b9c281..88585c5 100644
--- a/tests/src/com/android/contacts/activities/PeopleActivityTest.java
+++ b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
@@ -47,6 +47,7 @@
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.model.account.BaseAccountType;
+import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.contacts.common.test.mocks.MockAccountTypeManager;
 import com.android.contacts.common.test.mocks.MockContactPhotoManager;
 import com.android.contacts.common.test.mocks.MockSharedPreferences;
@@ -121,23 +122,6 @@
         super.tearDown();
     }
 
-    private void expectSettingsQueriesAndReturnDefault() {
-        mSettingsProvider
-                .expectQuery(Settings.System.CONTENT_URI)
-                .withProjection(Settings.System.VALUE)
-                .withSelection(Settings.System.NAME + "=?",
-                        ContactsContract.Preferences.DISPLAY_ORDER)
-                .returnRow(ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY)
-                .anyNumberOfTimes();
-        mSettingsProvider
-                .expectQuery(Settings.System.CONTENT_URI)
-                .withProjection(Settings.System.VALUE)
-                .withSelection(Settings.System.NAME + "=?",
-                        ContactsContract.Preferences.SORT_ORDER)
-                .returnRow(ContactsContract.Preferences.SORT_ORDER_PRIMARY)
-                .anyNumberOfTimes();
-    }
-
     private void expectProviderStatusQueryAndReturnNormal() {
         mContactsProvider
                 .expectQuery(ProviderStatus.CONTENT_URI)