Restart default directory loader after yenta search deletes

Test: manually delete search results 1) using multi-select and
  2) from QuickContact with populous both on and off.
Bug: 33643057
Change-Id: I58514c46722c775ce3b319d1665a982a8918e056
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index bec2add..d2157ea 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -82,6 +82,7 @@
 import com.android.contacts.group.GroupsFragment.GroupsListener;
 import com.android.contacts.interactions.AccountFiltersFragment;
 import com.android.contacts.interactions.AccountFiltersFragment.AccountFiltersListener;
+import com.android.contacts.interactions.ContactDeletionInteraction;
 import com.android.contacts.list.AccountFilterActivity;
 import com.android.contacts.list.ContactListFilter;
 import com.android.contacts.list.ContactListFilterController;
@@ -1522,5 +1523,12 @@
         return intent;
     }
 
-
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == DefaultContactBrowseListFragment.ACTIVITY_REQUEST_QUICK_CONTACT &&
+                resultCode == ContactDeletionInteraction.RESULT_CODE_DELETED &&
+                mContactsListFragment != null) {
+            mContactsListFragment.maybeRestartDefaultDirectoryPartitionLoader();
+        }
+    }
 }
diff --git a/src/com/android/contacts/interactions/ContactDeletionInteraction.java b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
index 161571c..e63fca4 100644
--- a/src/com/android/contacts/interactions/ContactDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
@@ -81,6 +81,10 @@
     private static final int COLUMN_INDEX_DISPLAY_NAME = 5;
     private static final int COLUMN_INDEX_DISPLAY_NAME_ALT = 6;
 
+    public interface Listener {
+        void onDeletionFinished();
+    }
+
     private boolean mActive;
     private Uri mContactUri;
     private String mDisplayName;
@@ -88,6 +92,7 @@
     private boolean mFinishActivityWhenDone;
     private Context mContext;
     private AlertDialog mDialog;
+    private Listener mListener;
 
     /** This is a wrapper around the fragment's loader manager to be used only during testing. */
     private TestLoaderManagerBase mTestLoaderManager;
@@ -346,6 +351,9 @@
 
     protected void doDeleteContact(Uri contactUri) {
         mContext.startService(ContactSaveService.createDeleteContactIntent(mContext, contactUri));
+        if (mListener != null) {
+            mListener.onDeletionFinished();
+        }
         if (isAdded() && mFinishActivityWhenDone) {
             getActivity().setResult(RESULT_CODE_DELETED);
             getActivity().finish();
@@ -362,4 +370,8 @@
             Toast.makeText(mContext, deleteToastMessage, Toast.LENGTH_LONG).show();
         }
     }
+
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
 }
diff --git a/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java b/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
index 695e9f6..3e1dd5d 100644
--- a/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
@@ -313,7 +313,9 @@
     protected void doDeleteContact(long[] contactIds, final String[] names) {
         mContext.startService(ContactSaveService.createDeleteMultipleContactsIntent(mContext,
                 contactIds, names));
-        mListener.onDeletionFinished();
+        if (mListener != null) {
+            mListener.onDeletionFinished();
+        }
     }
 
     public void setListener(MultiContactDeleteListener listener) {
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 6115b50..d8620a8 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -348,6 +348,22 @@
         mLoadPriorityDirectoriesOnly = false;
     }
 
+    /** Restarts the {@link DirectoryPartition} with {@link Directory#DEFAULT} directory ID. */
+    protected void restartDefaultDirectoryPartitionLoader() {
+        if (mAdapter == null) return;
+        int partitionCount = mAdapter.getPartitionCount();
+        for (int i = 0; i < partitionCount; i++) {
+            final Partition partition = mAdapter.getPartition(i);
+            if (partition instanceof DirectoryPartition) {
+                final DirectoryPartition directoryPartition = (DirectoryPartition) partition;
+                long directoryId = directoryPartition.getDirectoryId();
+                if (directoryId == Directory.DEFAULT) {
+                    loadDirectoryPartitionDelayed(i, directoryPartition);
+                }
+            }
+        }
+    }
+
     @Override
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
         if (id == DIRECTORY_LOADER_ID) {
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index f4d244e..a174b91 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -97,6 +97,7 @@
     private static final String KEY_SEARCH_RESULT_CLICKED = "search_result_clicked";
 
     private static final int ACTIVITY_REQUEST_CODE_SHARE = 0;
+    public static final int ACTIVITY_REQUEST_QUICK_CONTACT = 1000;
 
     private View mSearchHeaderView;
     private View mSearchProgress;
@@ -942,14 +943,24 @@
                         /* count */ getAdapter().getCount(),
                         /* clickedIndex */ position, /* numSelected */ 0);
 
-                ImplicitIntentsUtil.startQuickContact(
-                        getActivity(), contactLookupUri, previousScreen);
+                // Start QuickContact "for result" in case we're using yenta search and need
+                // to manually reload the default directory partition when contacts are deleted.
+                // The QuickContact Activity result is handled in PeopleActivity.
+                ImplicitIntentsUtil.startQuickContactForResult(getActivity(), contactLookupUri,
+                        previousScreen, ACTIVITY_REQUEST_QUICK_CONTACT);
             }
         }
 
         @Override
         public void onDeleteContactAction(Uri contactUri) {
-            ContactDeletionInteraction.start(mActivity, contactUri, false);
+            final ContactDeletionInteraction interacton =
+                    ContactDeletionInteraction.start(mActivity, contactUri, false);
+            interacton.setListener(new ContactDeletionInteraction.Listener() {
+                @Override
+                public void onDeletionFinished() {
+                    maybeRestartDefaultDirectoryPartitionLoader();
+                }
+            });
         }
 
         @Override
@@ -1157,6 +1168,16 @@
                 /* numSelected */ getSelectedContactIds().size());
             mActionBarAdapter.setSelectionMode(false);
             mIsDeletionInProgress = false;
+            maybeRestartDefaultDirectoryPartitionLoader();
+        }
+    }
+
+    // Because the yenta search loader is not automatically restarted when contacts are deleted
+    // we must manually restart it when contacts displayed in yenta search results are deleted
+    // either on this fragment directly or after opening QuickContact.
+    public void maybeRestartDefaultDirectoryPartitionLoader() {
+        if (isSearchMode() && Flags.getInstance().getBoolean(Experiments.SEARCH_YENTA)) {
+            restartDefaultDirectoryPartitionLoader();
         }
     }
 
@@ -1183,7 +1204,7 @@
                     /* listType */ getListTypeIncludingSearch(),
                     /* count */ getAdapter().getCount(), /* clickedIndex */ -1,
                     /* numSelected */ getAdapter().getSelectedContactIds().size());
-
+                break;
 // TODO fix or remove multipicker code: ag/54762
 //                else if (resultCode == RESULT_CANCELED && mMode == MODE_PICK_MULTIPLE_PHONES) {
 //                    // Finish the activity if the sub activity was canceled as back key is used