Merge "Fix Activity leak and implement change notification for preferences"
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 24ee508..29d40bb 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -235,6 +235,7 @@
     @Override
     public void onCreate(Bundle savedState) {
         super.onCreate(savedState);
+        mContactsPrefs = new ContactsPreferences(mContext);
         restoreSavedState(savedState);
     }
 
@@ -274,21 +275,13 @@
 
     @Override
     public void onStart() {
-
-        if (mContactsPrefs == null) {
-            mContactsPrefs = new ContactsPreferences(mContext);
-        }
+        mContactsPrefs.registerChangeListener(mPreferencesChangeListener);
 
         if (mProviderStatusLoader == null) {
             mProviderStatusLoader = new ProviderStatusLoader(mContext);
         }
 
-        loadPreferences(mContactsPrefs);
-
-        if (mListView instanceof ContactEntryListView) {
-            ContactEntryListView listView = (ContactEntryListView)mListView;
-            listView.setHighlightNamesWhenScrolling(isNameHighlighingEnabled());
-        }
+        loadPreferences();
 
         mForceLoad = false;
         mLoadDirectoryList = true;
@@ -421,6 +414,7 @@
     @Override
     public void onStop() {
         super.onStop();
+        mContactsPrefs.unregisterChangeListener();
         mAdapter.clearPartitions();
     }
 
@@ -601,9 +595,13 @@
         return mContextMenuAdapter;
     }
 
-    protected void loadPreferences(ContactsPreferences contactsPrefs) {
-        setContactNameDisplayOrder(contactsPrefs.getDisplayOrder());
-        setSortOrder(contactsPrefs.getSortOrder());
+    protected void loadPreferences() {
+        setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder());
+        setSortOrder(mContactsPrefs.getSortOrder());
+        if (mListView instanceof ContactEntryListView) {
+            ContactEntryListView listView = (ContactEntryListView)mListView;
+            listView.setHighlightNamesWhenScrolling(isNameHighlighingEnabled());
+        }
     }
 
     @Override
@@ -994,4 +992,12 @@
 //                    ContactsContract.REQUESTING_PACKAGE_PARAM_KEY, callingPackage).build();
 //        }
 //    }
+    private ContactsPreferences.ChangeListener mPreferencesChangeListener =
+            new ContactsPreferences.ChangeListener() {
+        @Override
+        public void onChange() {
+            loadPreferences();
+            reloadData();
+        }
+    };
 }
diff --git a/src/com/android/contacts/ui/ContactsPreferences.java b/src/com/android/contacts/ui/ContactsPreferences.java
index 49a49ef..89f71fc 100644
--- a/src/com/android/contacts/ui/ContactsPreferences.java
+++ b/src/com/android/contacts/ui/ContactsPreferences.java
@@ -21,6 +21,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
+import android.os.Handler;
 import android.provider.ContactsContract;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
@@ -28,20 +29,17 @@
 /**
  * Manages user preferences for contacts.
  */
-public final class ContactsPreferences  {
-
+public final class ContactsPreferences extends ContentObserver {
     private Context mContext;
-    private ContentResolver mContentResolver;
     private int mSortOrder = -1;
     private int mDisplayOrder = -1;
-    private SettingsObserver mSettingsObserver;
+    private ChangeListener mListener = null;
+    private Handler mHandler;
 
     public ContactsPreferences(Context context) {
+        super(null);
         mContext = context;
-        mContentResolver = context.getContentResolver();
-
-        mSettingsObserver = new SettingsObserver();
-        mSettingsObserver.register();
+        mHandler = new Handler();
     }
 
     public boolean isSortOrderUserChangeable() {
@@ -112,27 +110,41 @@
                 ContactsContract.Preferences.DISPLAY_ORDER, displayOrder);
     }
 
-    private class SettingsObserver extends ContentObserver {
+    public void registerChangeListener(ChangeListener listener) {
+        if (mListener != null) unregisterChangeListener();
 
-        public SettingsObserver() {
-            super(null);
+        mListener = listener;
+        final ContentResolver contentResolver = mContext.getContentResolver();
+        contentResolver.registerContentObserver(
+                Settings.System.getUriFor(
+                        ContactsContract.Preferences.SORT_ORDER), false, this);
+        contentResolver.registerContentObserver(
+                Settings.System.getUriFor(
+                        ContactsContract.Preferences.DISPLAY_ORDER), false, this);
+    }
+
+    public void unregisterChangeListener() {
+        if (mListener != null) {
+            mContext.getContentResolver().unregisterContentObserver(this);
+            mListener = null;
         }
+    }
 
-        public void register() {
-            mContentResolver.registerContentObserver(
-                    Settings.System.getUriFor(
-                            ContactsContract.Preferences.SORT_ORDER), false, this);
-            mContentResolver.registerContentObserver(
-                    Settings.System.getUriFor(
-                            ContactsContract.Preferences.DISPLAY_ORDER), false, this);
-        }
+    @Override
+    public void onChange(boolean selfChange) {
+        // 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() {
+                mSortOrder = -1;
+                mDisplayOrder = -1;
+                if (mListener != null) mListener.onChange();
+            }
+        });
+    }
 
-        @Override
-        public void onChange(boolean selfChange) {
-            mSortOrder = -1;
-            mDisplayOrder = -1;
-
-            // TODO send a message to parent context to notify of the change
-        }
+    public interface ChangeListener {
+        void onChange();
     }
 }