Preventing multiple instances of contact browser from launching

There is a lot of complexity (and simplifications) in
this CL because as it turns out having fragment transactions
was causing focus to be acquired by the search field,
which was causing all kinds of problems.  So now we only
have one permanent list fragment (which should go into the XML
file) and we just change modes on it.


Bug: 3345023

Change-Id: I096be24b7598350a074eb1dadc954c7619f26669
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 617d5c7..fc476d1 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -176,6 +176,8 @@
             android:label="@string/contactsList"
             android:icon="@mipmap/ic_launcher_contacts"
             android:theme="@style/ContactBrowserTheme"
+            android:clearTaskOnLaunch="true"
+            android:launchMode="singleTop"
         >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -198,8 +200,9 @@
         <!-- The actual list of contacts -->
         <activity android:name=".activities.ContactBrowserActivity"
             android:label="@string/contactsList"
-            android:clearTaskOnLaunch="true"
             android:theme="@style/ContactBrowserTheme"
+            android:launchMode="singleTop"
+            android:clearTaskOnLaunch="true"
         >
             <intent-filter>
                 <action android:name="com.android.contacts.action.LIST_DEFAULT" />
@@ -261,8 +264,9 @@
         
         <activity android:name=".activities.ContactSelectionActivity"
             android:label="@string/contactsList"
-            android:clearTaskOnLaunch="true"
             android:theme="@style/ContactPickerTheme"
+            android:launchMode="singleTop"
+            android:clearTaskOnLaunch="true"
         >
             <intent-filter>
                 <action android:name="android.intent.action.INSERT_OR_EDIT" />
diff --git a/src/com/android/contacts/activities/ActionBarAdapter.java b/src/com/android/contacts/activities/ActionBarAdapter.java
index 8bdf405..2faa345 100644
--- a/src/com/android/contacts/activities/ActionBarAdapter.java
+++ b/src/com/android/contacts/activities/ActionBarAdapter.java
@@ -219,6 +219,11 @@
         outState.putString(EXTRA_KEY_QUERY, mQueryString);
     }
 
+    public void onRestoreInstanceState(Bundle savedState) {
+        mSearchMode = savedState.getBoolean(EXTRA_KEY_SEARCH_MODE);
+        mQueryString = savedState.getString(EXTRA_KEY_QUERY);
+    }
+
     @Override
     public void onContactListFiltersLoaded() {
         update();
diff --git a/src/com/android/contacts/activities/ContactBrowserActivity.java b/src/com/android/contacts/activities/ContactBrowserActivity.java
index 240fb3a..4ff9e63 100644
--- a/src/com/android/contacts/activities/ContactBrowserActivity.java
+++ b/src/com/android/contacts/activities/ContactBrowserActivity.java
@@ -40,7 +40,6 @@
 import com.android.contacts.list.OnContactsUnavailableActionListener;
 import com.android.contacts.list.ProviderStatusLoader;
 import com.android.contacts.list.ProviderStatusLoader.ProviderStatusListener;
-import com.android.contacts.list.StrequentContactListFragment;
 import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.preference.ContactsPreferenceActivity;
 import com.android.contacts.util.AccountSelectionUtil;
@@ -94,8 +93,6 @@
     private static final int SUBACTIVITY_EDIT_CONTACT = 4;
     private static final int SUBACTIVITY_CUSTOMIZE_FILTER = 5;
 
-    private static final int DEFAULT_DIRECTORY_RESULT_LIMIT = 20;
-
     private static final String KEY_SEARCH_MODE = "searchMode";
 
     private DialogManager mDialogManager = new DialogManager(this);
@@ -147,8 +144,9 @@
         if (fragment instanceof ContactBrowseListFragment) {
             mListFragment = (ContactBrowseListFragment)fragment;
             mListFragment.setOnContactListActionListener(new ContactBrowserActionListener());
-            if (mContactListFilterController.isLoaded()) {
-                mListFragment.setFilter(mContactListFilterController.getFilter());
+            if (!mHasActionBar) {
+                mListFragment.setContextMenuAdapter(
+                        new ContactBrowseListContextMenuAdapter(mListFragment));
             }
         } else if (fragment instanceof ContactDetailFragment) {
             mDetailFragment = (ContactDetailFragment)fragment;
@@ -165,10 +163,26 @@
     protected void onCreate(Bundle savedState) {
         super.onCreate(savedState);
 
-        if (savedState != null) {
-            mSearchMode = savedState.getBoolean(KEY_SEARCH_MODE);
-        }
+        mAddContactImageView = getLayoutInflater().inflate(
+                R.layout.add_contact_menu_item, null, false);
+        View item = mAddContactImageView.findViewById(R.id.menu_item);
+        item.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                createNewContact();
+            }
+        });
 
+        configureContentView(true, savedState);
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        setIntent(intent);
+        configureContentView(false, null);
+    }
+
+    private void configureContentView(boolean createContentView, Bundle savedState) {
         // Extract relevant information from the intent
         mRequest = mIntentResolver.resolveIntent(getIntent());
         if (!mRequest.isValid()) {
@@ -185,8 +199,10 @@
             return;
         }
 
-        setContentView(R.layout.contact_browser);
-        mContactContentDisplayed = findViewById(R.id.detail_container) != null;
+        if (createContentView) {
+            setContentView(R.layout.contact_browser);
+            mContactContentDisplayed = findViewById(R.id.detail_container) != null;
+        }
 
         if (mRequest.getActionCode() == ContactsRequest.ACTION_VIEW_CONTACT
                 && !mContactContentDisplayed) {
@@ -199,6 +215,7 @@
         }
 
         setTitle(mRequest.getActivityTitle());
+
         mHasActionBar = getWindow().hasFeature(Window.FEATURE_ACTION_BAR);
         if (mHasActionBar) {
             ActionBar actionBar = getActionBar();
@@ -206,41 +223,9 @@
             mActionBarAdapter = new ActionBarAdapter(this);
             mActionBarAdapter.onCreate(savedState, mRequest, actionBar);
             mActionBarAdapter.setContactListFilterController(mContactListFilterController);
-            // TODO: request may ask for FREQUENT - set the filter accordingly
-
-            mAddContactImageView = getLayoutInflater().inflate(
-                    R.layout.add_contact_menu_item, null, false);
-            View item = mAddContactImageView.findViewById(R.id.menu_item);
-            item.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    createNewContact();
-                }
-            });
         }
 
-        configureFragments(true /* from request */);
-    }
-
-    @Override
-    protected void onNewIntent(Intent intent) {
-        super.onNewIntent(intent);
-        setIntent(intent);
-        if (Intent.ACTION_VIEW.equals(intent.getAction())) {
-            mRequest = mIntentResolver.resolveIntent(intent);
-
-            Uri uri = mRequest.getContactUri();
-            if (uri == null) {
-                return;
-            }
-
-            if (mHasActionBar) {
-                mActionBarAdapter.setSearchMode(false);
-                configureFragments(false /* from request */);
-            }
-
-            mListFragment.reloadDataAndSetSelectedUri(uri);
-        }
+        configureFragments(savedState == null);
     }
 
     @Override
@@ -248,6 +233,12 @@
         if (mActionBarAdapter != null) {
             mActionBarAdapter.setListener(null);
         }
+
+        mOptionsMenuContactsAvailable = false;
+        mOptionsMenuCustomFilterChangeable = false;
+        mOptionsMenuGroupActionsEnabled = false;
+
+        mProviderStatus = -1;
         mProviderStatusLoader.setProviderStatusListener(null);
         super.onPause();
     }
@@ -275,7 +266,6 @@
     }
 
     private void configureFragments(boolean fromRequest) {
-        boolean searchMode = mSearchMode;
         if (fromRequest) {
             ContactListFilter filter = null;
             int actionCode = mRequest.getActionCode();
@@ -299,49 +289,35 @@
 
             if (filter != null) {
                 mContactListFilterController.setContactListFilter(filter, false);
-                searchMode = false;
+                mSearchMode = false;
             } else if (mRequest.getActionCode() == ContactsRequest.ACTION_ALL_CONTACTS) {
                 mContactListFilterController.setContactListFilter(new ContactListFilter(
                         ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS), false);
             }
 
             if (mRequest.getContactUri() != null) {
-                searchMode = false;
+                mSearchMode = false;
             }
 
         } else if (mHasActionBar) {
-            searchMode = mActionBarAdapter.isSearchMode();
+            mSearchMode = mActionBarAdapter.isSearchMode();
         }
 
-        boolean replaceList = mListFragment == null || (mSearchMode != searchMode);
-        if (replaceList) {
-            if (mListFragment != null) {
-                mListFragment.setOnContactListActionListener(null);
-            }
+        if (mListFragment == null) {
+            mListFragment = new DefaultContactBrowseListFragment();
+            mListFragment.setContactsRequest(mRequest);
 
-            mSearchMode = searchMode;
-
-            if (mSearchMode) {
-                mListFragment = createContactSearchFragment();
-            } else {
-                mListFragment = createListFragment(ContactsRequest.ACTION_DEFAULT);
-                if (mRequest.getContactUri() != null) {
-                    mListFragment.setSelectedContactUri(mRequest.getContactUri());
-
-                }
-            }
-        }
-
-        if (mSearchMode && mHasActionBar) {
-            mListFragment.setQueryString(mActionBarAdapter.getQueryString());
-        }
-
-        if (replaceList) {
             getFragmentManager().openTransaction()
                     .replace(R.id.list_container, mListFragment)
                     .commit();
         }
 
+        if (fromRequest) {
+            configureListFragmentForRequest();
+        }
+
+        configureListFragment();
+
         if (mContactContentDisplayed && mDetailFragment == null) {
             mDetailFragment = new ContactDetailFragment();
             getFragmentManager().openTransaction()
@@ -349,9 +325,7 @@
                     .commit();
         }
 
-        if (replaceList) {
-            invalidateOptionsMenu();
-        }
+        invalidateOptionsMenu();
     }
 
     @Override
@@ -392,96 +366,38 @@
     @Override
     public void onAction() {
         configureFragments(false /* from request */);
+        mListFragment.setQueryString(mActionBarAdapter.getQueryString());
     }
 
-    /**
-     * Creates the list fragment for the specified mode.
-     */
-    private ContactBrowseListFragment createListFragment(int actionCode) {
-        switch (actionCode) {
-            case ContactsRequest.ACTION_DEFAULT: {
-                DefaultContactBrowseListFragment fragment = new DefaultContactBrowseListFragment();
-                fragment.setContactsRequest(mRequest);
-                fragment.setOnContactListActionListener(new ContactBrowserActionListener());
-                if (!mHasActionBar) {
-                    fragment.setContextMenuAdapter(
-                            new ContactBrowseListContextMenuAdapter(fragment));
-                }
-                fragment.setSearchMode(mRequest.isSearchMode());
-                fragment.setQueryString(mRequest.getQueryString());
-                if (mRequest.isSearchMode() && mRequest.isDirectorySearchEnabled()) {
-                    fragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DEFAULT);
-                } else {
-                    fragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
-                }
-                fragment.setVisibleScrollbarEnabled(!mRequest.isSearchMode());
-                fragment.setVerticalScrollbarPosition(
-                        mContactContentDisplayed
-                                ? View.SCROLLBAR_POSITION_LEFT
-                                : View.SCROLLBAR_POSITION_RIGHT);
-                fragment.setSelectionVisible(mContactContentDisplayed);
-                fragment.setQuickContactEnabled(!mContactContentDisplayed);
-                fragment.setFilterEnabled(!mRequest.isSearchMode());
-                fragment.setPersistentSelectionEnabled(!mRequest.isSearchMode());
-                return fragment;
-            }
+    private void configureListFragmentForRequest() {
+        Uri contactUri = mRequest.getContactUri();
+        if (contactUri != null) {
+            mListFragment.setSelectedContactUri(contactUri);
+        }
 
-            case ContactsRequest.ACTION_GROUP: {
-                throw new UnsupportedOperationException("Not yet implemented");
-            }
+        mListFragment.setQueryString(mRequest.getQueryString());
 
-            case ContactsRequest.ACTION_STARRED: {
-                StrequentContactListFragment fragment = new StrequentContactListFragment();
-                fragment.setOnContactListActionListener(new ContactBrowserActionListener());
-                fragment.setFrequentlyContactedContactsIncluded(false);
-                fragment.setStarredContactsIncluded(true);
-                fragment.setSelectionVisible(mContactContentDisplayed);
-                fragment.setQuickContactEnabled(!mContactContentDisplayed);
-                return fragment;
-            }
+        if (mRequest.isDirectorySearchEnabled()) {
+            mListFragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DEFAULT);
+        } else {
+            mListFragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
+        }
 
-            case ContactsRequest.ACTION_FREQUENT: {
-                StrequentContactListFragment fragment = new StrequentContactListFragment();
-                fragment.setOnContactListActionListener(new ContactBrowserActionListener());
-                fragment.setFrequentlyContactedContactsIncluded(true);
-                fragment.setStarredContactsIncluded(false);
-                fragment.setSelectionVisible(mContactContentDisplayed);
-                fragment.setQuickContactEnabled(!mContactContentDisplayed);
-                return fragment;
-            }
-
-            case ContactsRequest.ACTION_STREQUENT: {
-                StrequentContactListFragment fragment = new StrequentContactListFragment();
-                fragment.setOnContactListActionListener(new ContactBrowserActionListener());
-                fragment.setFrequentlyContactedContactsIncluded(true);
-                fragment.setStarredContactsIncluded(true);
-                fragment.setSelectionVisible(mContactContentDisplayed);
-                fragment.setQuickContactEnabled(!mContactContentDisplayed);
-                return fragment;
-            }
-
-            default:
-                throw new IllegalStateException("Invalid action code: " + actionCode);
+        if (mContactListFilterController.isLoaded()) {
+            mListFragment.setFilter(mContactListFilterController.getFilter());
         }
     }
 
-    private ContactBrowseListFragment createContactSearchFragment() {
-        DefaultContactBrowseListFragment fragment = new DefaultContactBrowseListFragment();
-        fragment.setOnContactListActionListener(new ContactBrowserActionListener());
-        if (!mHasActionBar) {
-            fragment.setContextMenuAdapter(new ContactBrowseListContextMenuAdapter(fragment));
-        }
-        fragment.setSearchMode(true);
-        fragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DEFAULT);
-        fragment.setDirectoryResultLimit(DEFAULT_DIRECTORY_RESULT_LIMIT);
-        fragment.setVisibleScrollbarEnabled(false);
-        fragment.setVerticalScrollbarPosition(
+    private void configureListFragment() {
+        mListFragment.setSearchMode(mSearchMode);
+
+        mListFragment.setVisibleScrollbarEnabled(!mSearchMode);
+        mListFragment.setVerticalScrollbarPosition(
                 mContactContentDisplayed
                         ? View.SCROLLBAR_POSITION_LEFT
                         : View.SCROLLBAR_POSITION_RIGHT);
-        fragment.setSelectionVisible(true);
-        fragment.setQuickContactEnabled(!mContactContentDisplayed);
-        return fragment;
+        mListFragment.setSelectionVisible(mContactContentDisplayed);
+        mListFragment.setQuickContactEnabled(!mContactContentDisplayed);
     }
 
     @Override
@@ -1057,6 +973,15 @@
         }
     }
 
+    @Override
+    protected void onRestoreInstanceState(Bundle inState) {
+        super.onRestoreInstanceState(inState);
+        mSearchMode = inState.getBoolean(KEY_SEARCH_MODE);
+        if (mActionBarAdapter != null) {
+            mActionBarAdapter.onRestoreInstanceState(inState);
+        }
+    }
+
     private PhoneNumberInteraction getPhoneNumberCallInteraction() {
         if (mPhoneNumberCallInteraction == null) {
             mPhoneNumberCallInteraction = new PhoneNumberInteraction(this, false, null);
diff --git a/src/com/android/contacts/activities/ContactsFrontDoor.java b/src/com/android/contacts/activities/ContactsFrontDoor.java
index 214382d..3677cce 100644
--- a/src/com/android/contacts/activities/ContactsFrontDoor.java
+++ b/src/com/android/contacts/activities/ContactsFrontDoor.java
@@ -18,9 +18,9 @@
 
 import com.android.contacts.ContactsActivity;
 import com.android.contacts.DialtactsActivity;
+import com.android.contacts.util.PhoneCapabilityTester;
 
 import android.content.Intent;
-import android.content.res.Configuration;
 import android.os.Bundle;
 
 public class ContactsFrontDoor extends ContactsActivity {
@@ -35,18 +35,16 @@
         intent.setAction(originalIntent.getAction());
         intent.setDataAndType(originalIntent.getData(), originalIntent.getType());
         intent.setFlags(
-                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_FORWARD_RESULT
+                        | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
         intent.putExtra(EXTRA_FRONT_DOOR, true);
 
-        // The user launched the config based front door, pick the right activity to go to
-        Configuration config = getResources().getConfiguration();
-        int screenLayoutSize = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
-        if (screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
-            // XL screen, use two pane UI
-            intent.setClass(this, ContactBrowserActivity.class);
-        } else {
+        if (PhoneCapabilityTester.isPhone(this)) {
             // Default to the normal dialtacts layout
             intent.setClass(this, DialtactsActivity.class);
+        } else {
+            // No tabs, just a contact list
+            intent.setClass(this, ContactBrowserActivity.class);
         }
 
         startActivity(intent);
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index bea9891..3d53da8 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -51,10 +51,8 @@
 
     private static final String KEY_SELECTED_URI = "selectedUri";
     private static final String KEY_SELECTION_VERIFIED = "selectionVerified";
-    private static final String KEY_FILTER_ENABLED = "filterEnabled";
     private static final String KEY_FILTER = "filter";
 
-    private static final String KEY_PERSISTENT_SELECTION_ENABLED = "persistentSelectionEnabled";
     private static final String PERSISTENT_SELECTION_PREFIX = "defaultContactBrowserSelection";
 
     /**
@@ -88,9 +86,7 @@
     private long mSelectedContactId;
     private boolean mSelectionVerified;
     private boolean mRefreshingContactUri;
-    private boolean mFilterEnabled;
     private ContactListFilter mFilter;
-    private boolean mPersistentSelectionEnabled;
     private String mPersistentSelectionPrefix = PERSISTENT_SELECTION_PREFIX;
 
     protected OnContactBrowserActionListener mListener;
@@ -164,8 +160,14 @@
         restoreSelectedUri(false);
     }
 
-    public void setPersistentSelectionEnabled(boolean flag) {
-        this.mPersistentSelectionEnabled = flag;
+    @Override
+    public void setSearchMode(boolean flag) {
+        if (isSearchMode() != flag) {
+            if (!flag) {
+                restoreSelectedUri(true);
+            }
+            super.setSearchMode(flag);
+        }
     }
 
     public void setFilter(ContactListFilter filter) {
@@ -196,14 +198,6 @@
         return mFilter;
     }
 
-    public boolean isFilterEnabled() {
-        return mFilterEnabled;
-    }
-
-    public void setFilterEnabled(boolean flag) {
-        this.mFilterEnabled = flag;
-    }
-
     @Override
     public void restoreSavedState(Bundle savedState) {
         super.restoreSavedState(savedState);
@@ -212,8 +206,6 @@
             return;
         }
 
-        mPersistentSelectionEnabled = savedState.getBoolean(KEY_PERSISTENT_SELECTION_ENABLED);
-        mFilterEnabled = savedState.getBoolean(KEY_FILTER_ENABLED);
         mFilter = savedState.getParcelable(KEY_FILTER);
         mSelectedContactUri = savedState.getParcelable(KEY_SELECTED_URI);
         mSelectionVerified = savedState.getBoolean(KEY_SELECTION_VERIFIED);
@@ -223,8 +215,6 @@
     @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
-        outState.putBoolean(KEY_PERSISTENT_SELECTION_ENABLED, mPersistentSelectionEnabled);
-        outState.putBoolean(KEY_FILTER_ENABLED, mFilterEnabled);
         outState.putParcelable(KEY_FILTER, mFilter);
         outState.putParcelable(KEY_SELECTED_URI, mSelectedContactUri);
         outState.putBoolean(KEY_SELECTION_VERIFIED, mSelectionVerified);
@@ -346,7 +336,8 @@
             if (mSelectedContactUri.toString().startsWith(Contacts.CONTENT_LOOKUP_URI.toString())) {
                 List<String> pathSegments = mSelectedContactUri.getPathSegments();
                 mSelectedContactLookupKey = Uri.encode(pathSegments.get(2));
-            } else if (mSelectedContactUri.toString().startsWith(Contacts.CONTENT_URI.toString())) {
+            } else if (mSelectedContactUri.toString().startsWith(Contacts.CONTENT_URI.toString()) &&
+                    mSelectedContactUri.getPathSegments().size() >= 2) {
                 mSelectedContactLookupKey = null;
                 mSelectedContactId = ContentUris.parseId(mSelectedContactUri);
             } else {
@@ -371,7 +362,7 @@
             return;
         }
 
-        if (mFilterEnabled && mFilter != null) {
+        if (!isSearchMode() && mFilter != null) {
             adapter.setFilter(mFilter);
             if (mSelectionRequired
                     || mFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
@@ -578,26 +569,22 @@
     }
 
     private void saveSelectedUri(Uri contactUri) {
-        if (mFilterEnabled) {
-            ContactListFilter.storeToPreferences(mPrefs, mFilter);
-        }
-
-        if (mPersistentSelectionEnabled) {
-            Editor editor = mPrefs.edit();
-            if (contactUri == null) {
-                editor.remove(getPersistentSelectionKey());
-            } else {
-                editor.putString(getPersistentSelectionKey(), contactUri.toString());
-            }
-            editor.apply();
-        }
-    }
-
-    private void restoreSelectedUri(boolean willReloadData) {
-        if (!mPersistentSelectionEnabled) {
+        if (isSearchMode()) {
             return;
         }
 
+        ContactListFilter.storeToPreferences(mPrefs, mFilter);
+
+        Editor editor = mPrefs.edit();
+        if (contactUri == null) {
+            editor.remove(getPersistentSelectionKey());
+        } else {
+            editor.putString(getPersistentSelectionKey(), contactUri.toString());
+        }
+        editor.apply();
+    }
+
+    private void restoreSelectedUri(boolean willReloadData) {
         // The meaning of mSelectionRequired is that we need to show some
         // selection other than the previous selection saved in shared preferences
         if (mSelectionRequired) {
@@ -613,17 +600,13 @@
     }
 
     private void saveFilter() {
-        if (mFilterEnabled) {
-            ContactListFilter.storeToPreferences(mPrefs, mFilter);
-        }
+        ContactListFilter.storeToPreferences(mPrefs, mFilter);
     }
 
     private void restoreFilter() {
-        if (mFilterEnabled) {
-            mFilter = ContactListFilter.restoreFromPreferences(mPrefs);
-            if (mFilter == null) {
-                mFilter = new ContactListFilter(ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
-            }
+        mFilter = ContactListFilter.restoreFromPreferences(mPrefs);
+        if (mFilter == null) {
+            mFilter = new ContactListFilter(ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
         }
     }
 
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 1b7c9dc..d76ad38 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -424,13 +424,11 @@
                         startLoading();
                     }
                 }
+            } else {
+                mDirectoryListStatus = STATUS_NOT_LOADED;
+                getLoaderManager().destroyLoader(DIRECTORY_LOADER_ID);
             }
         }
-
-// TODO fix the empty view
-//            if (mEmptyView != null && (data == null || data.getCount() == 0)) {
-//                prepareEmptyView();
-//            }
     }
 
     public void onLoaderReset(Loader<Cursor> loader) {
@@ -574,10 +572,24 @@
             mSearchMode = flag;
             setSectionHeaderDisplayEnabled(!mSearchMode);
 
+            if (!flag) {
+                mDirectoryListStatus = STATUS_NOT_LOADED;
+                getLoaderManager().destroyLoader(DIRECTORY_LOADER_ID);
+            }
+
             if (mAdapter != null) {
-                mAdapter.clearPartitions();
-                mAdapter.setSearchMode(flag);
                 mAdapter.setPinnedPartitionHeadersEnabled(flag);
+                mAdapter.setSearchMode(flag);
+
+                mAdapter.clearPartitions();
+                if (!flag) {
+                    // If we are switching from search to regular display,
+                    // remove all directory partitions (except the default one).
+                    int count = mAdapter.getPartitionCount();
+                    for (int i = count; --i >= 1;) {
+                        mAdapter.removePartition(i);
+                    }
+                }
                 mAdapter.configureDefaultPartition(false, flag);
                 reloadData();
             }
diff --git a/src/com/android/contacts/list/DefaultContactListAdapter.java b/src/com/android/contacts/list/DefaultContactListAdapter.java
index 7dcca08..6b4a653 100644
--- a/src/com/android/contacts/list/DefaultContactListAdapter.java
+++ b/src/com/android/contacts/list/DefaultContactListAdapter.java
@@ -191,7 +191,7 @@
     protected void bindView(View itemView, int partition, Cursor cursor, int position) {
         final ContactListItemView view = (ContactListItemView)itemView;
 
-        view.setHighlightedPrefix(getUpperCaseQueryString());
+        view.setHighlightedPrefix(isSearchMode() ? getUpperCaseQueryString() : null);
 
         if (isSelectionVisible()) {
             view.setActivated(isSelectedContact(partition, cursor));
@@ -210,6 +210,8 @@
 
         if (isSearchMode()) {
             bindSearchSnippet(view, cursor);
+        } else {
+            view.setSnippet(null);
         }
     }
 
diff --git a/src/com/android/contacts/list/StrequentContactListFragment.java b/src/com/android/contacts/list/StrequentContactListFragment.java
index 393e698..b88a60d 100644
--- a/src/com/android/contacts/list/StrequentContactListFragment.java
+++ b/src/com/android/contacts/list/StrequentContactListFragment.java
@@ -25,6 +25,8 @@
 /**
  * Fragment containing a list of starred contacts followed by a list of frequently contacted.
  */
+
+// TODO: This class is currently unused.  Bring it back as a mode of ContactBrowserListFragment
 public class StrequentContactListFragment extends ContactBrowseListFragment
         implements OnClickListener {
 
diff --git a/tests/res/values/donottranslate_strings.xml b/tests/res/values/donottranslate_strings.xml
index 660bae2..8557fd6 100644
--- a/tests/res/values/donottranslate_strings.xml
+++ b/tests/res/values/donottranslate_strings.xml
@@ -24,11 +24,8 @@
         <item>LIST_ALL_CONTACTS_ACTION</item>
         <item>LIST_CONTACTS_WITH_PHONES_ACTION</item>
         <item>LIST_STARRED_ACTION</item>
-        <item>LIST_STARRED_ACTION (filter)</item>
         <item>LIST_FREQUENT_ACTION</item>
-        <item>LIST_FREQUENT_ACTION (filter)</item>
         <item>LIST_STREQUENT_ACTION</item>
-        <item>LIST_STREQUENT_ACTION (filter)</item>
         <item>ACTION_PICK: contact</item>
         <item>ACTION_PICK: contact (legacy)</item>
         <item>ACTION_PICK: phone</item>
@@ -36,20 +33,13 @@
         <item>ACTION_PICK: postal</item>
         <item>ACTION_PICK: postal (legacy)</item>
         <item>ACTION_CREATE_SHORTCUT: contact</item>
-        <item>ACTION_CREATE_SHORTCUT: contact (filter)</item>
         <item>ACTION_CREATE_SHORTCUT: dial</item>
-        <item>ACTION_CREATE_SHORTCUT: dial (filter)</item>
         <item>ACTION_CREATE_SHORTCUT: message</item>
-        <item>ACTION_CREATE_SHORTCUT: message (filter)</item>
         <item>ACTION_GET_CONTENT: contact</item>
-        <item>ACTION_GET_CONTENT: contact (filter)</item>
         <item>ACTION_GET_CONTENT: contact (legacy)</item>
-        <item>ACTION_GET_CONTENT: contact (filter, legacy)</item>
         <item>ACTION_GET_CONTENT: phone</item>
-        <item>ACTION_GET_CONTENT: phone (filter)</item>
         <item>ACTION_GET_CONTENT: phone (legacy)</item>
         <item>ACTION_GET_CONTENT: postal</item>
-        <item>ACTION_GET_CONTENT: postal (filter)</item>
         <item>ACTION_GET_CONTENT: postal (legacy)</item>
         <item>ACTION_INSERT_OR_EDIT</item>
         <item>ACTION_SEARCH (call button)</item>
diff --git a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
index 66079ad..50a1f1f 100644
--- a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
+++ b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
@@ -16,7 +16,6 @@
 
 package com.android.contacts.tests.allintents;
 
-import com.android.contacts.list.ContactsRequest;
 import com.android.contacts.tests.R;
 import com.google.android.collect.Lists;
 
@@ -61,74 +60,67 @@
     private static final String CONTACT_LIST_ACTIVITY_CLASS_NAME =
             "com.android.contacts.activities.ContactBrowserActivity";
 
-    private static final int LIST_DEFAULT = 0;
-    private static final int LIST_ALL_CONTACTS_ACTION = 1;
-    private static final int LIST_CONTACTS_WITH_PHONES_ACTION = 2;
-    private static final int LIST_STARRED_ACTION = 3;
-    private static final int LIST_STARRED_ACTION_WITH_FILTER = 4;
-    private static final int LIST_FREQUENT_ACTION = 5;
-    private static final int LIST_FREQUENT_ACTION_WITH_FILTER = 6;
-    private static final int LIST_STREQUENT_ACTION = 7;
-    private static final int LIST_STREQUENT_ACTION_WITH_FILTER = 8;
-    private static final int ACTION_PICK_CONTACT = 9;
-    private static final int ACTION_PICK_CONTACT_LEGACY = 10;
-    private static final int ACTION_PICK_PHONE = 11;
-    private static final int ACTION_PICK_PHONE_LEGACY = 12;
-    private static final int ACTION_PICK_POSTAL = 13;
-    private static final int ACTION_PICK_POSTAL_LEGACY = 14;
-    private static final int ACTION_CREATE_SHORTCUT_CONTACT = 15;
-    private static final int ACTION_CREATE_SHORTCUT_CONTACT_FILTER = 16;
-    private static final int ACTION_CREATE_SHORTCUT_DIAL = 17;
-    private static final int ACTION_CREATE_SHORTCUT_DIAL_FILTER = 18;
-    private static final int ACTION_CREATE_SHORTCUT_MESSAGE = 19;
-    private static final int ACTION_CREATE_SHORTCUT_MESSAGE_FILTER = 20;
-    private static final int ACTION_GET_CONTENT_CONTACT = 21;
-    private static final int ACTION_GET_CONTENT_CONTACT_FILTER = 22;
-    private static final int ACTION_GET_CONTENT_CONTACT_LEGACY = 23;
-    private static final int ACTION_GET_CONTENT_CONTACT_FILTER_LEGACY = 24;
-    private static final int ACTION_GET_CONTENT_PHONE = 25;
-    private static final int ACTION_GET_CONTENT_PHONE_FILTER = 26;
-    private static final int ACTION_GET_CONTENT_PHONE_LEGACY = 27;
-    private static final int ACTION_GET_CONTENT_POSTAL = 28;
-    private static final int ACTION_GET_CONTENT_POSTAL_FILTER = 29;
-    private static final int ACTION_GET_CONTENT_POSTAL_LEGACY = 30;
-    private static final int ACTION_INSERT_OR_EDIT = 31;
-    private static final int ACTION_SEARCH_CALL = 32;
-    private static final int ACTION_SEARCH_CONTACT = 33;
-    private static final int ACTION_SEARCH_EMAIL = 34;
-    private static final int ACTION_SEARCH_PHONE = 35;
-    private static final int SEARCH_SUGGESTION_CLICKED_CALL_BUTTON = 36;
-    private static final int SEARCH_SUGGESTION_CLICKED_CONTACT = 37;
-    private static final int SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED = 38;
-    private static final int SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED = 39;
-    private static final int JOIN_CONTACT = 40;
+    public enum ContactsIntent {
+        LIST_DEFAULT,
+        LIST_ALL_CONTACTS_ACTION,
+        LIST_CONTACTS_WITH_PHONES_ACTION,
+        LIST_STARRED_ACTION,
+        LIST_FREQUENT_ACTION,
+        LIST_STREQUENT_ACTION,
+        ACTION_PICK_CONTACT,
+        ACTION_PICK_CONTACT_LEGACY,
+        ACTION_PICK_PHONE,
+        ACTION_PICK_PHONE_LEGACY,
+        ACTION_PICK_POSTAL,
+        ACTION_PICK_POSTAL_LEGACY,
+        ACTION_CREATE_SHORTCUT_CONTACT,
+        ACTION_CREATE_SHORTCUT_DIAL,
+        ACTION_CREATE_SHORTCUT_MESSAGE,
+        ACTION_GET_CONTENT_CONTACT,
+        ACTION_GET_CONTENT_CONTACT_LEGACY,
+        ACTION_GET_CONTENT_PHONE,
+        ACTION_GET_CONTENT_PHONE_LEGACY,
+        ACTION_GET_CONTENT_POSTAL,
+        ACTION_GET_CONTENT_POSTAL_LEGACY,
+        ACTION_INSERT_OR_EDIT,
+        ACTION_SEARCH_CALL,
+        ACTION_SEARCH_CONTACT,
+        ACTION_SEARCH_EMAIL,
+        ACTION_SEARCH_PHONE,
+        SEARCH_SUGGESTION_CLICKED_CALL_BUTTON,
+        SEARCH_SUGGESTION_CLICKED_CONTACT,
+        SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED,
+        SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED,
+        JOIN_CONTACT,
+        EDIT_CONTACT,
+        EDIT_CONTACT_LOOKUP,
+        EDIT_CONTACT_LOOKUP_ID,
+        EDIT_RAW_CONTACT,
+        EDIT_LEGACY,
+        EDIT_NEW_CONTACT,
+        EDIT_NEW_CONTACT_WITH_DATA,
+        EDIT_NEW_CONTACT_FOR_ACCOUNT,
+        EDIT_NEW_CONTACT_FOR_ACCOUNT_WITH_DATA,
+        EDIT_NEW_RAW_CONTACT,
+        EDIT_NEW_LEGACY,
+        VIEW_CONTACT,
+        VIEW_CONTACT_LOOKUP,
+        VIEW_CONTACT_LOOKUP_ID,
+        VIEW_RAW_CONTACT,
+        VIEW_LEGACY,
+        DIAL,
+        DIAL_phone,
+        DIAL_person,
+        DIAL_voicemail,
+        CALL_BUTTON,
+        DIAL_tel,
+        VIEW_tel,
+        VIEW_calllog;
 
-    private static final int EDIT_CONTACT = 41;
-    private static final int EDIT_CONTACT_LOOKUP = 42;
-    private static final int EDIT_CONTACT_LOOKUP_ID = 43;
-    private static final int EDIT_RAW_CONTACT = 44;
-    private static final int EDIT_LEGACY = 45;
-    private static final int EDIT_NEW_CONTACT = 46;
-    private static final int EDIT_NEW_CONTACT_WITH_DATA = 47;
-    private static final int EDIT_NEW_CONTACT_FOR_ACCOUNT = 48;
-    private static final int EDIT_NEW_CONTACT_FOR_ACCOUNT_WITH_DATA = 49;
-    private static final int EDIT_NEW_RAW_CONTACT = 50;
-    private static final int EDIT_NEW_LEGACY = 51;
-
-    private static final int VIEW_CONTACT = 52;
-    private static final int VIEW_CONTACT_LOOKUP = 53;
-    private static final int VIEW_CONTACT_LOOKUP_ID = 54;
-    private static final int VIEW_RAW_CONTACT = 55;
-    private static final int VIEW_LEGACY = 56;
-
-    private static final int DIAL = 57;
-    private static final int DIAL_phone = 58;
-    private static final int DIAL_person = 59;
-    private static final int DIAL_voicemail = 60;
-    private static final int CALL_BUTTON = 61;
-    private static final int DIAL_tel = 62;
-    private static final int VIEW_tel = 63;
-    private static final int VIEW_calllog = 64;
+        public static ContactsIntent get(int ordinal) {
+            return values()[ordinal];
+        }
+    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -141,7 +133,7 @@
     protected void onListItemClick(ListView l, View v, int position, long id) {
         super.onListItemClick(l, v, position, id);
 
-        switch (position) {
+        switch (ContactsIntent.get(position)) {
             case LIST_DEFAULT: {
                 startContactListActivity(
                         new Intent(Intent.ACTION_VIEW, Contacts.CONTENT_URI));
@@ -162,30 +154,16 @@
                         new Intent(UI.LIST_STARRED_ACTION, Contacts.CONTENT_URI));
                 break;
             }
-            case LIST_STARRED_ACTION_WITH_FILTER: {
-                startContactListActivity(buildFilterIntent(ContactsRequest.ACTION_STARRED, false));
-                break;
-            }
             case LIST_FREQUENT_ACTION: {
                 startContactListActivity(
                         new Intent(UI.LIST_FREQUENT_ACTION, Contacts.CONTENT_URI));
                 break;
             }
-            case LIST_FREQUENT_ACTION_WITH_FILTER: {
-                startContactListActivity(
-                        buildFilterIntent(ContactsRequest.ACTION_FREQUENT, false));
-                break;
-            }
             case LIST_STREQUENT_ACTION: {
                 startContactListActivity(
                         new Intent(UI.LIST_STREQUENT_ACTION, Contacts.CONTENT_URI));
                 break;
             }
-            case LIST_STREQUENT_ACTION_WITH_FILTER: {
-                startContactListActivity(
-                        buildFilterIntent(ContactsRequest.ACTION_STREQUENT, false));
-                break;
-            }
             case ACTION_PICK_CONTACT: {
                 startContactSelectionActivityForResult(
                         new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI));
@@ -222,12 +200,6 @@
                 startContactSelectionActivityForResult(intent);
                 break;
             }
-            case ACTION_CREATE_SHORTCUT_CONTACT_FILTER: {
-                startContactSelectionActivityForResult(
-                        buildFilterIntent(ContactsRequest.ACTION_CREATE_SHORTCUT_CONTACT,
-                                false));
-                break;
-            }
             case ACTION_CREATE_SHORTCUT_DIAL: {
                 Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
                 intent.setComponent(
@@ -235,12 +207,6 @@
                 startActivityForResult(intent, 0);
                 break;
             }
-            case ACTION_CREATE_SHORTCUT_DIAL_FILTER: {
-                startContactSelectionActivityForResult(
-                        buildFilterIntent(ContactsRequest.ACTION_CREATE_SHORTCUT_CALL,
-                                false));
-                break;
-            }
             case ACTION_CREATE_SHORTCUT_MESSAGE: {
                 Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
                 intent.setComponent(
@@ -248,11 +214,6 @@
                 startActivityForResult(intent, 0);
                 break;
             }
-            case ACTION_CREATE_SHORTCUT_MESSAGE_FILTER: {
-                startContactSelectionActivityForResult(
-                        buildFilterIntent(ContactsRequest.ACTION_CREATE_SHORTCUT_CALL, false));
-                break;
-            }
             case ACTION_GET_CONTENT_CONTACT: {
                 Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                 intent.setType(Contacts.CONTENT_ITEM_TYPE);
@@ -265,28 +226,12 @@
                 startContactSelectionActivityForResult(intent);
                 break;
             }
-            case ACTION_GET_CONTENT_CONTACT_FILTER: {
-                startContactSelectionActivityForResult(
-                        buildFilterIntent(ContactsRequest.ACTION_PICK_OR_CREATE_CONTACT, false));
-                break;
-            }
-            case ACTION_GET_CONTENT_CONTACT_FILTER_LEGACY: {
-                startContactSelectionActivityForResult(
-                        buildFilterIntent(ContactsRequest.ACTION_PICK_OR_CREATE_CONTACT,
-                                true));
-                break;
-            }
             case ACTION_GET_CONTENT_PHONE: {
                 Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                 intent.setType(Phone.CONTENT_ITEM_TYPE);
                 startContactSelectionActivityForResult(intent);
                 break;
             }
-            case ACTION_GET_CONTENT_PHONE_FILTER: {
-                startContactSelectionActivityForResult(
-                        buildFilterIntent(ContactsRequest.ACTION_PICK_PHONE, true));
-                break;
-            }
             case ACTION_GET_CONTENT_PHONE_LEGACY: {
                 Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                 intent.setType(Phones.CONTENT_ITEM_TYPE);
@@ -299,11 +244,6 @@
                 startContactSelectionActivityForResult(intent);
                 break;
             }
-            case ACTION_GET_CONTENT_POSTAL_FILTER: {
-                startContactSelectionActivityForResult(
-                        buildFilterIntent(ContactsRequest.ACTION_PICK_POSTAL, false));
-                break;
-            }
             case ACTION_GET_CONTENT_POSTAL_LEGACY: {
                 Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                 intent.setType(ContactMethods.CONTENT_POSTAL_ITEM_TYPE);
@@ -546,9 +486,9 @@
     private Intent buildFilterIntent(int actionCode, boolean legacy) {
         Intent intent = new Intent(UI.FILTER_CONTACTS_ACTION);
         intent.putExtra(UI.FILTER_TEXT_EXTRA_KEY, "A");
-        ContactsRequest request = new ContactsRequest();
-        request.setActionCode(actionCode);
-        intent.putExtra("originalRequest", request);
+//        ContactsRequest request = new ContactsRequest();
+//        request.setActionCode(actionCode);
+//        intent.putExtra("originalRequest", request);
         return intent;
     }
 
@@ -627,7 +567,7 @@
 
     @Override
     public void onAccountChosen(Account account, int tag) {
-        switch (tag) {
+        switch (ContactsIntent.get(tag)) {
             case EDIT_NEW_CONTACT_FOR_ACCOUNT: {
                 final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
                 intent.putExtra(Insert.ACCOUNT, account);
@@ -643,6 +583,8 @@
                 startActivity(intent);
                 break;
             }
+            default:
+                break;
         }
     }