Preventing cursor leaks

Change-Id: I0cea0615134d92fe8569262099de4ab13d75e5ef
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 0da9a36..59f34fb 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -224,6 +224,9 @@
     @Override
     protected void onLoadFinished(Loader<Cursor> loader, Cursor data) {
         if (!checkProviderStatus(false)) {
+            if (data != null) {
+                data.close();
+            }
             return;
         }
 
@@ -343,31 +346,34 @@
         } else {
             mAdapter.configureLoader(loader, partition.getDirectoryId());
             if (forceLoad) {
-                loader.cancelLoad();
                 loader.forceLoad();
             }
         }
     }
 
     protected void reloadData() {
-        mAdapter.onDataReload();
-        if (mDirectoryPartitions.size() > 0) {
-            // We need to cancel _all_ current queries and then launch
-            // a new query for the 0th partition.
+        if (mInitialLoadComplete) {
+            mAdapter.onDataReload();
+            if (mDirectoryPartitions.size() > 0) {
+                // We need to cancel _all_ current queries and then launch
+                // a new query for the 0th partition.
 
-            CursorLoader directoryLoader = (CursorLoader)getLoader(DIRECTORY_LOADER_ID);
-            if (directoryLoader != null) {
-                directoryLoader.cancelLoad();
-            }
-            int size = mDirectoryPartitions.size();
-            for (int i = 0; i < size; i++) {
-                CursorLoader loader = (CursorLoader)getLoader(i);
-                if (loader != null) {
-                    loader.cancelLoad();
+                CursorLoader directoryLoader = (CursorLoader)getLoader(DIRECTORY_LOADER_ID);
+                if (directoryLoader != null) {
+                    directoryLoader.cancelLoad();
                 }
-            }
+                int size = mDirectoryPartitions.size();
+                for (int i = 0; i < size; i++) {
+                    CursorLoader loader = (CursorLoader)getLoader(i);
+                    if (loader != null) {
+                        loader.cancelLoad();
+                    }
+                }
 
-            startLoading(mDirectoryPartitions.get(0), true);
+                startLoading(mDirectoryPartitions.get(0), true);
+            }
+        } else {
+            startLoading(0, null);
         }
     }
 
@@ -378,6 +384,13 @@
         }
     }
 
+    @Override
+    public void onStop() {
+        super.onStop();
+        mAdapter.resetPartitions();
+        mInitialLoadComplete = false;
+    }
+
     /**
      * Configures the empty view. It is called when we are about to populate
      * the list with an empty cursor.
diff --git a/src/com/android/contacts/widget/CompositeCursorAdapter.java b/src/com/android/contacts/widget/CompositeCursorAdapter.java
index 3eb48bb..c6d2ea3 100644
--- a/src/com/android/contacts/widget/CompositeCursorAdapter.java
+++ b/src/com/android/contacts/widget/CompositeCursorAdapter.java
@@ -80,6 +80,12 @@
     }
 
     public void resetPartitions() {
+        for (int i = 0; i < mSize; i++) {
+            Cursor cursor = mPartitions[i].cursor;
+            if (cursor != null && !cursor.isClosed()) {
+                cursor.close();
+            }
+        }
         mSize = 0;
         invalidate();
         notifyDataSetChanged();
@@ -140,12 +146,18 @@
      * Changes the cursor for an individual partition.
      */
     public void changeCursor(int partition, Cursor cursor) {
-        mPartitions[partition].cursor = cursor;
-        if (cursor != null) {
-            mPartitions[partition].idColumnIndex = cursor.getColumnIndex("_id");
+        Cursor prevCursor = mPartitions[partition].cursor;
+        if (prevCursor != cursor) {
+            if (prevCursor != null && !prevCursor.isClosed()) {
+                prevCursor.close();
+            }
+            mPartitions[partition].cursor = cursor;
+            if (cursor != null) {
+                mPartitions[partition].idColumnIndex = cursor.getColumnIndex("_id");
+            }
+            invalidate();
+            notifyDataSetChanged();
         }
-        invalidate();
-        notifyDataSetChanged();
     }
 
     /**