Merge "Group list: Don't reset scroll position during sync"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 56bf4e5..e27445f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -315,11 +315,17 @@
             android:label="@string/activity_title_settings"
             android:theme="@style/ContactsPreferencesTheme" />
 
+        <!-- Used to filter contacts list by account -->
+        <activity
+            android:name=".list.AccountFilterActivity"
+            android:label="@string/activity_title_contacts_filter"
+            android:theme="@style/ContactListFilterTheme" />
+
         <!-- Used to select display and sync groups -->
         <activity
             android:name=".list.CustomContactListFilterActivity"
             android:label="@string/custom_list_filter"
-            android:theme="@style/CustomContactListFilterTheme" />
+            android:theme="@style/ContactListFilterTheme" />
 
         <activity
             android:name=".activities.ShowOrCreateActivity"
diff --git a/res/layout-sw580dp/people_activity.xml b/res/layout-sw580dp/people_activity.xml
index 7301d24..a6d9a37 100644
--- a/res/layout-sw580dp/people_activity.xml
+++ b/res/layout-sw580dp/people_activity.xml
@@ -45,9 +45,9 @@
                 android:layout_marginLeft="40dip"
                 android:layout_marginTop="24dip" />
 
-            <!-- Contacts -->
+            <!-- All -->
             <fragment
-                android:id="@+id/contacts_fragment"
+                android:id="@+id/all_fragment"
                 class="com.android.contacts.list.DefaultContactBrowseListFragment"
                 android:layout_height="0dip"
                 android:layout_width="match_parent"
diff --git a/res/layout/contact_list_filter.xml b/res/layout/contact_list_filter.xml
new file mode 100644
index 0000000..de05cf8
--- /dev/null
+++ b/res/layout/contact_list_filter.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:fillViewport="true">
+
+    <ListView
+        android:id="@android:id/list"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dip"
+        android:layout_marginLeft="16dip"
+        android:layout_marginRight="16dip"
+        android:background="?android:attr/dividerHorizontal" />
+</LinearLayout>
diff --git a/res/layout/contact_list_filter_phones_only.xml b/res/layout/contact_list_filter_phones_only.xml
deleted file mode 100644
index 35965da..0000000
--- a/res/layout/contact_list_filter_phones_only.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
-    android:gravity="center_vertical"
-    android:paddingRight="?android:attr/scrollbarSize"
->
-
-    <RelativeLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginLeft="14dip"
-        android:layout_marginRight="6dip"
-        android:layout_marginTop="6dip"
-        android:layout_marginBottom="6dip"
-        android:layout_weight="1"
-    >
-
-        <TextView
-            android:id="@android:id/text1"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-        />
-
-        <TextView
-            android:id="@android:id/text2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/text1"
-            android:layout_alignLeft="@android:id/text1"
-            android:maxLines="2"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-        />
-
-    </RelativeLayout>
-
-    <CheckBox
-        android:id="@android:id/checkbox"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginRight="4dip"
-        android:focusable="false"
-        android:clickable="false"
-        android:gravity="center_vertical"
-        android:orientation="vertical" />
-
-</LinearLayout>
diff --git a/res/layout/contacts_list_content.xml b/res/layout/contacts_list_content.xml
index 6792f9c..b92929b 100644
--- a/res/layout/contacts_list_content.xml
+++ b/res/layout/contacts_list_content.xml
@@ -21,6 +21,19 @@
     android:layout_height="match_parent"
     android:orientation="vertical">
 
+    <TextView
+        android:id="@+id/account_filter_header"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:gravity="center"
+        android:padding="5dip"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textColor="@android:color/white"
+        android:background="@android:color/black"
+        android:visibility="gone" />
+
     <view
         class="com.android.contacts.list.ContactEntryListView"
         android:id="@android:id/list"
diff --git a/res/layout/custom_action_bar.xml b/res/layout/custom_action_bar.xml
index 2357756..f749586 100644
--- a/res/layout/custom_action_bar.xml
+++ b/res/layout/custom_action_bar.xml
@@ -14,11 +14,20 @@
      limitations under the License.
 -->
 
+<!-- Dimensions are set at runtime in ActionBarAdapter -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent" >
+    android:layout_width="0dip"
+    android:layout_height="0dip" >
 
+    <!-- To prevent the search view from getting the initial focus.  -->
+    <View
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        android:layout_width="1px"
+        android:layout_height="1px" >
+        <requestFocus />
+    </View>
     <SearchView
         android:id="@+id/search_view"
         android:layout_width="match_parent"
diff --git a/res/layout/people_activity.xml b/res/layout/people_activity.xml
index bcf218b..11431b3 100644
--- a/res/layout/people_activity.xml
+++ b/res/layout/people_activity.xml
@@ -26,9 +26,9 @@
         android:layout_height="match_parent"
         android:layout_width="match_parent" />
 
-    <!-- Contacts -->
+    <!-- All -->
     <fragment
-        android:id="@+id/contacts_fragment"
+        android:id="@+id/all_fragment"
         class="com.android.contacts.list.DefaultContactBrowseListFragment"
         android:layout_height="match_parent"
         android:layout_width="match_parent"
diff --git a/res/menu-sw580dp-w720dp/actions.xml b/res/menu-sw580dp-w720dp/actions.xml
index 081065c..d87b091 100644
--- a/res/menu-sw580dp-w720dp/actions.xml
+++ b/res/menu-sw580dp-w720dp/actions.xml
@@ -15,11 +15,6 @@
 -->
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:id="@+id/menu_search"
-        android:showAsAction="always"
-        android:actionViewClass="android.widget.SearchView" />
-
-    <item
         android:id="@+id/menu_add_contact"
         android:icon="@drawable/ic_menu_add_contact_holo_light"
         android:title="@string/menu_new_contact_action_bar"
diff --git a/res/menu-sw580dp/actions.xml b/res/menu-sw580dp/actions.xml
index 1d955c1..fea883e 100644
--- a/res/menu-sw580dp/actions.xml
+++ b/res/menu-sw580dp/actions.xml
@@ -15,11 +15,6 @@
 -->
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:id="@+id/menu_search"
-        android:showAsAction="always"
-        android:actionViewClass="android.widget.SearchView" />
-
-    <item
         android:id="@+id/menu_add_contact"
         android:icon="@drawable/ic_menu_add_contact_holo_light"
         android:title="@string/menu_new_contact_action_bar"
diff --git a/res/values-sw580dp/dimens.xml b/res/values-sw580dp/dimens.xml
index 0c1e5fb..bcaf1d2 100644
--- a/res/values-sw580dp/dimens.xml
+++ b/res/values-sw580dp/dimens.xml
@@ -33,4 +33,5 @@
     <dimen name="list_section_height">37dip</dimen>
     <dimen name="directory_header_height">56dip</dimen>
     <dimen name="detail_tab_carousel_height">256dip</dimen>
+    <dimen name="search_view_width">400dip</dimen>
 </resources>
diff --git a/res/values-sw580dp/donottranslate_config.xml b/res/values-sw580dp/donottranslate_config.xml
index fcb7da9..5ca1af6 100644
--- a/res/values-sw580dp/donottranslate_config.xml
+++ b/res/values-sw580dp/donottranslate_config.xml
@@ -19,4 +19,5 @@
 
 <resources>
     <bool name="config_use_two_panes">true</bool>
+    <bool name="always_show_search_view">true</bool>
 </resources>
diff --git a/res/values-sw580dp/styles.xml b/res/values-sw580dp/styles.xml
index 32d02be..4f2b073 100644
--- a/res/values-sw580dp/styles.xml
+++ b/res/values-sw580dp/styles.xml
@@ -60,10 +60,11 @@
         <item name="list_item_header_text_size">14sp</item>
     </style>
 
-    <style name="CustomContactListFilterTheme" parent="@android:Theme.Holo.Light.Dialog">
+    <style name="ContactListFilterTheme" parent="@android:Theme.Holo.Light.Dialog">
+        <item name="android:windowCloseOnTouchOutside">true</item>
     </style>
 
-    <style name="CustomContactListFilterView" parent="CustomContactListFilterTheme">
+    <style name="CustomContactListFilterView" parent="ContactListFilterTheme">
         <item name="android:layout_width">400dip</item>
         <item name="android:layout_height">400dip</item>
     </style>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a0c4845..948d357 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -148,7 +148,7 @@
     <!-- Spacing on the left the search field in the action bar -->
     <dimen name="action_bar_search_spacing">12dip</dimen>
 
-    <!-- Size of the shortcut icon. 0dip means: use the system default -->    
+    <!-- Size of the shortcut icon. 0dip means: use the system default -->
     <dimen name="shortcut_icon_size">0dip</dimen>
 
     <!-- Height of list sections (A, B, C) that show the first character of the contacts -->
@@ -181,4 +181,7 @@
     <dimen name="dialpad_digits_margin_top">1dip</dimen>
     <!-- Just used in landscape mode -->
     <dimen name="dialpad_digits_margin_bottom">50dip</dimen>
+
+    <!-- Width of search view in action bar.  Use 0dip for MATCH_PARENT -->
+    <dimen name="search_view_width">0dip</dimen>
 </resources>
diff --git a/res/values/donottranslate_config.xml b/res/values/donottranslate_config.xml
index e310953..c778212 100644
--- a/res/values/donottranslate_config.xml
+++ b/res/values/donottranslate_config.xml
@@ -103,4 +103,8 @@
     <!-- If true, Contacts uses two panes: List and Detail. If false, Details are
          shown in their own screens. This flag must be in sync with the layout definitions. -->
     <bool name="config_use_two_panes">false</bool>
+
+    <!-- If true, search view on action bar will always be visible.  If false, it'll only be
+         visible in search mode.  -->
+    <bool name="always_show_search_view">false</bool>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6e88440..e17648a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -296,12 +296,6 @@
     <!-- The text displayed when the contacts list is empty while displaying only contacts that have phone numbers -->
     <string name="noContactsWithPhoneNumbers">No contacts with phone numbers.</string>
 
-    <!-- The title of the filter to only show contacts with phone numbers -->
-    <string name="showFilterPhones">Only contacts with phones</string>
-
-    <!-- The description of the filter to only show contacts with phone numbers -->
-    <string name="showFilterPhonesDescrip">Only display contacts that have phone numbers</string>
-
     <!-- The header over the list of all contacts groups -->
     <string name="headerContactGroups">Choose contacts to display</string>
 
@@ -366,6 +360,9 @@
     <!-- Displayed at the top of the contacts showing the zero total number of contacts visible when a group or account is selected  [CHAR LIMIT=64]-->
     <string name="listTotalAllContactsZeroGroup">No contacts in <xliff:g id="name" example="Friends">%s</xliff:g></string>
 
+    <!-- Displayed at the top of the contacts showing the account filter selected  [CHAR LIMIT=64] -->
+    <string name="listAllContactsInAccount">Contacts in <xliff:g id="name" example="abc@gmail.com">%s</xliff:g></string>
+
     <!-- Displayed at the top of the contacts showing the total number of contacts found when "Only contacts with phones" not selected -->
     <plurals name="listFoundAllContacts">
         <item quantity="one">1 found</item>
@@ -384,8 +381,8 @@
         <item quantity="other"><xliff:g id="count">%d</xliff:g> found</item>
     </plurals>
 
-    <!-- The description text for the contacts tab. Space is limited for this string, so the shorter the better -->
-    <string name="contactsIconLabel">Contacts</string>
+    <!-- The description text for the "all contacts" tab. Space is limited for this string, so the shorter the better -->
+    <string name="contactsAllLabel">All</string>
 
     <!-- The description text for the groups tab. Space is limited for this string, so the shorter the better -->
     <string name="contactsGroupsLabel">Groups</string>
@@ -1490,6 +1487,9 @@
     <!-- Title of the settings activity [CHAR LIMIT=64] -->
     <string name="activity_title_settings">Settings</string>
 
+    <!-- Title of the activity that allows the uesr to filter the list of contacts displayed according to account [CHAR LIMIT=25] -->
+    <string name="activity_title_contacts_filter">Contacts to display</string>
+
     <!-- Menu item for the settings activity [CHAR LIMIT=64] -->
     <string name="menu_settings">Settings</string>
 
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 067a730..914532c 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -227,7 +227,7 @@
     <style name="ContactsPreferencesTheme" parent="@android:Theme.Holo.Light">
     </style>
 
-    <style name="CustomContactListFilterTheme" parent="@android:Theme">
+    <style name="ContactListFilterTheme" parent="@android:Theme.Holo.Light">
     </style>
 
     <style name="ContactPickerLayout" parent="ContactPickerTheme">
@@ -235,7 +235,7 @@
         <item name="android:layout_height">match_parent</item>
     </style>
 
-    <style name="CustomContactListFilterView" parent="CustomContactListFilterTheme">
+    <style name="CustomContactListFilterView" parent="ContactListFilterTheme">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">match_parent</item>
     </style>
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index a4a578f..7f01481 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -169,7 +169,7 @@
      *
      * @param callUri Uri into {@link CallLog.Calls}
      */
-    private void updateData(Uri callUri) {
+    private void updateData(final Uri callUri) {
         ContentResolver resolver = getContentResolver();
         Cursor callCursor = resolver.query(callUri, CALL_LOG_PROJECTION, null, null, null);
         try {
@@ -261,15 +261,42 @@
                     // Build list of various available actions
                     List<ViewEntry> actions = new ArrayList<ViewEntry>();
 
-                    Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                            Uri.fromParts("tel", mNumber, null));
-                    actions.add(new ViewEntry(android.R.drawable.sym_action_call,
-                            getString(R.string.menu_callNumber, mNumber), callIntent));
+                    final boolean isSipNumber = PhoneNumberUtils.isUriNumber(mNumber);
+                    final Uri numberCallUri;
+                    if (isSipNumber) {
+                        numberCallUri = Uri.fromParts("sip", mNumber, null);
+                    } else {
+                        numberCallUri = Uri.fromParts("tel", mNumber, null);
+                    }
 
-                    Intent smsIntent = new Intent(Intent.ACTION_SENDTO,
-                            Uri.fromParts("sms", mNumber, null));
-                    actions.add(new ViewEntry(R.drawable.sym_action_sms,
-                            getString(R.string.menu_sendTextMessage), smsIntent));
+                    actions.add(new ViewEntry(android.R.drawable.sym_action_call,
+                            getString(R.string.menu_callNumber, mNumber),
+                            new Intent(Intent.ACTION_CALL_PRIVILEGED, numberCallUri)));
+
+                    if (!isSipNumber) {
+                        Intent smsIntent = new Intent(Intent.ACTION_SENDTO,
+                                Uri.fromParts("sms", mNumber, null));
+                        actions.add(new ViewEntry(R.drawable.sym_action_sms,
+                                getString(R.string.menu_sendTextMessage), smsIntent));
+                    }
+
+                    actions.add(new ViewEntry(android.R.drawable.ic_menu_close_clear_cancel,
+                            getString(R.string.recentCalls_removeFromRecentList),
+                            new View.OnClickListener() {
+                                @Override
+                                public void onClick(View v) {
+                                    long id = ContentUris.parseId(callUri);
+                                    getContentResolver().delete(Calls.CONTENT_URI_WITH_VOICEMAIL,
+                                            Calls._ID + " = ?", new String[]{Long.toString(id)});
+                                    finish();
+                                }
+                            }));
+
+                    if (!isSipNumber) {
+                        actions.add(new ViewEntry(android.R.drawable.sym_action_call,
+                                getString(R.string.recentCalls_editNumberBeforeCall),
+                                new Intent(Intent.ACTION_DIAL, numberCallUri)));
+                    }
 
                     ViewAdapter adapter = new ViewAdapter(this, actions);
                     setListAdapter(adapter);
@@ -317,9 +344,11 @@
     }
 
     static final class ViewEntry {
-        public int icon = -1;
-        public String text = null;
-        public Intent intent = null;
+        public final int icon;
+        public final String text;
+        public final Intent intent;
+        public final View.OnClickListener action;
+
         public String label = null;
         public String number = null;
 
@@ -327,6 +356,14 @@
             this.icon = icon;
             this.text = text;
             this.intent = intent;
+            this.action = null;
+        }
+
+        public ViewEntry(int icon, String text, View.OnClickListener listener) {
+            this.icon = icon;
+            this.text = text;
+            this.intent = null;
+            this.action = listener;
         }
     }
 
@@ -404,6 +441,8 @@
             ViewEntry entry = (ViewEntry) view.getTag();
             if (entry.intent != null) {
                 startActivity(entry.intent);
+            } else if (entry.action != null) {
+                entry.action.onClick(view);
             }
         }
     }
diff --git a/src/com/android/contacts/ContactPhotoManager.java b/src/com/android/contacts/ContactPhotoManager.java
index e61d379..fe73fbe 100644
--- a/src/com/android/contacts/ContactPhotoManager.java
+++ b/src/com/android/contacts/ContactPhotoManager.java
@@ -66,11 +66,12 @@
      * the available authenticators. This method can safely be called from the UI thread.
      */
     public static ContactPhotoManager getInstance(Context context) {
+        Context applicationContext = context.getApplicationContext();
         ContactPhotoManager service =
-                (ContactPhotoManager) context.getSystemService(CONTACT_PHOTO_SERVICE);
+                (ContactPhotoManager) applicationContext.getSystemService(CONTACT_PHOTO_SERVICE);
         if (service == null) {
-            service = createContactPhotoManager(context);
-            Log.e(TAG, "No contact photo service in context: " + context);
+            service = createContactPhotoManager(applicationContext);
+            Log.e(TAG, "No contact photo service in context: " + applicationContext);
         }
         return service;
     }
diff --git a/src/com/android/contacts/GroupMetaDataLoader.java b/src/com/android/contacts/GroupMetaDataLoader.java
index d900825..8533bb6 100644
--- a/src/com/android/contacts/GroupMetaDataLoader.java
+++ b/src/com/android/contacts/GroupMetaDataLoader.java
@@ -34,6 +34,7 @@
         Groups.AUTO_ADD,
         Groups.FAVORITES,
         Groups.GROUP_IS_READ_ONLY,
+        Groups.DELETED,
     };
 
     public final static int ACCOUNT_NAME = 0;
@@ -43,6 +44,7 @@
     public final static int AUTO_ADD = 4;
     public final static int FAVORITES = 5;
     public final static int IS_READ_ONLY = 6;
+    public final static int DELETED = 7;
 
     public GroupMetaDataLoader(Context context, Uri groupUri) {
         super(context, ensureIsGroupUri(groupUri), COLUMNS, Groups.ACCOUNT_TYPE + " NOT NULL AND "
diff --git a/src/com/android/contacts/activities/ActionBarAdapter.java b/src/com/android/contacts/activities/ActionBarAdapter.java
index 073f665..51ed1e8 100644
--- a/src/com/android/contacts/activities/ActionBarAdapter.java
+++ b/src/com/android/contacts/activities/ActionBarAdapter.java
@@ -18,8 +18,6 @@
 
 import com.android.contacts.R;
 import com.android.contacts.activities.ActionBarAdapter.Listener.Action;
-import com.android.contacts.list.ContactListFilterController;
-import com.android.contacts.list.ContactListFilterController.ContactListFilterListener;
 import com.android.contacts.list.ContactsRequest;
 
 import android.app.ActionBar;
@@ -36,8 +34,7 @@
 /**
  * Adapter for the action bar at the top of the Contacts activity.
  */
-public class ActionBarAdapter
-        implements OnQueryTextListener, OnCloseListener, ContactListFilterListener {
+public class ActionBarAdapter implements OnQueryTextListener, OnCloseListener {
 
     public interface Listener {
         public enum Action {
@@ -58,27 +55,23 @@
     private SearchView mSearchView;
 
     private final Context mContext;
+    private final boolean mAlwaysShowSearchView;
 
     private Listener mListener;
-    private ContactListFilterController mFilterController;
 
     private ActionBar mActionBar;
 
-    private View mCustomSearchView;
-    private LayoutParams mLayoutParams;
-    private boolean mIsSearchInOverflowMenu;
 
     public ActionBarAdapter(Context context, Listener listener) {
         mContext = context;
         mListener = listener;
         mSearchLabelText = mContext.getString(R.string.search_label);
+        mAlwaysShowSearchView = mContext.getResources().getBoolean(R.bool.always_show_search_view);
     }
 
-    public void onCreate(Bundle savedState, ContactsRequest request, ActionBar actionBar,
-            boolean searchInOverflowMenu) {
+    public void onCreate(Bundle savedState, ContactsRequest request, ActionBar actionBar) {
         mActionBar = actionBar;
         mQueryString = null;
-        mIsSearchInOverflowMenu = searchInOverflowMenu;
 
         if (savedState != null) {
             mSearchMode = savedState.getBoolean(EXTRA_KEY_SEARCH_MODE);
@@ -88,33 +81,29 @@
             mQueryString = request.getQueryString();
         }
 
-        if (mSearchView != null) {
-            mSearchView.setQuery(mQueryString, false);
+        // Set up search view.
+        View customSearchView = LayoutInflater.from(mContext).inflate(R.layout.custom_action_bar,
+                null);
+        int searchViewWidth = mContext.getResources().getDimensionPixelSize(
+                R.dimen.search_view_width);
+        if (searchViewWidth == 0) {
+            searchViewWidth = LayoutParams.MATCH_PARENT;
         }
+        LayoutParams layoutParams = new LayoutParams(searchViewWidth, LayoutParams.WRAP_CONTENT);
+        mSearchView = (SearchView) customSearchView.findViewById(R.id.search_view);
+        mSearchView.setQueryHint(mContext.getString(R.string.hint_findContacts));
+        mSearchView.setOnQueryTextListener(this);
+        mSearchView.setOnCloseListener(this);
+        mSearchView.setQuery(mQueryString, false);
+        mActionBar.setCustomView(customSearchView, layoutParams);
 
         update();
     }
 
-    public void setSearchView(SearchView searchView) {
-        mSearchView = searchView;
-        mSearchView.setOnQueryTextListener(this);
-        mSearchView.setOnCloseListener(this);
-        mSearchView.setQuery(mQueryString, false);
-    }
-
     public void setListener(Listener listener) {
         mListener = listener;
     }
 
-    public void setContactListFilterController(ContactListFilterController controller) {
-        mFilterController = controller;
-        mFilterController.addListener(this);
-    }
-
-    public boolean isSearchInOverflowMenu() {
-        return mIsSearchInOverflowMenu;
-    }
-
     public boolean isSearchMode() {
         return mSearchMode;
     }
@@ -127,7 +116,7 @@
                 return;
             }
             if (mSearchMode) {
-                mSearchView.requestFocus();
+                setFocusOnSearchView();
             } else {
                 mSearchView.setQuery(null, false);
             }
@@ -147,31 +136,20 @@
 
     public void update() {
         if (mSearchMode) {
-            // If the search icon was in the overflow menu, then inflate a custom view containing
-            // a search view for the action bar (and hide the tabs).
-            if (mIsSearchInOverflowMenu) {
-                if (mCustomSearchView == null) {
-                    mCustomSearchView = LayoutInflater.from(mContext).inflate(
-                            R.layout.custom_action_bar, null);
-                    mLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,
-                            LayoutParams.WRAP_CONTENT);
-                    SearchView searchView = (SearchView) mCustomSearchView.
-                            findViewById(R.id.search_view);
-                    searchView.setQueryHint(mContext.getString(R.string.hint_findContacts));
-                    setSearchView(searchView);
-                }
-                mActionBar.setDisplayShowCustomEnabled(true);
-                mActionBar.setCustomView(mCustomSearchView, mLayoutParams);
-                mSearchView.requestFocus();
-            } else {
+            mActionBar.setDisplayShowCustomEnabled(true);
+            if (mAlwaysShowSearchView) {
+                // Tablet -- change the app title for the search mode
                 mActionBar.setTitle(mSearchLabelText);
+            } else {
+                // Phone -- search view gets focus
+                setFocusOnSearchView();
             }
             mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
             if (mListener != null) {
                 mListener.onAction(Action.START_SEARCH_MODE);
             }
         } else {
-            mActionBar.setDisplayShowCustomEnabled(false);
+            mActionBar.setDisplayShowCustomEnabled(mAlwaysShowSearchView);
             mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
             mActionBar.setTitle(null);
             if (mListener != null) {
@@ -223,17 +201,8 @@
         mActionBar.setSelectedNavigationItem(savedState.getInt(EXTRA_KEY_SELECTED_TAB));
     }
 
-    @Override
-    public void onContactListFiltersLoaded() {
-        update();
-    }
-
-    @Override
-    public void onContactListFilterChanged() {
-        update();
-    }
-
-    @Override
-    public void onContactListFilterCustomizationRequest() {
+    private void setFocusOnSearchView() {
+        mSearchView.requestFocus();
+        mSearchView.setIconified(false); // Workaround for the "IME not popping up" issue.
     }
 }
diff --git a/src/com/android/contacts/activities/GroupDetailActivity.java b/src/com/android/contacts/activities/GroupDetailActivity.java
index 21900c6..c8f511b 100644
--- a/src/com/android/contacts/activities/GroupDetailActivity.java
+++ b/src/com/android/contacts/activities/GroupDetailActivity.java
@@ -43,6 +43,7 @@
                 R.id.group_detail_fragment);
         fragment.setListener(mFragmentListener);
         fragment.loadGroup(getIntent().getData());
+        fragment.closeActivityAfterDelete(true);
 
         ActionBar actionBar =  getActionBar();
         if (actionBar != null) {
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index d5bdd61..3488bed 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -32,6 +32,7 @@
 import com.android.contacts.interactions.ContactDeletionInteraction;
 import com.android.contacts.interactions.ImportExportDialogFragment;
 import com.android.contacts.interactions.PhoneNumberInteraction;
+import com.android.contacts.list.AccountFilterActivity;
 import com.android.contacts.list.ContactBrowseListContextMenuAdapter;
 import com.android.contacts.list.ContactBrowseListFragment;
 import com.android.contacts.list.ContactEntryListFragment;
@@ -108,7 +109,8 @@
     private static final int SUBACTIVITY_EDIT_CONTACT = 3;
     private static final int SUBACTIVITY_NEW_GROUP = 4;
     private static final int SUBACTIVITY_EDIT_GROUP = 5;
-    private static final int SUBACTIVITY_CUSTOMIZE_FILTER = 6;
+    private static final int SUBACTIVITY_ACCOUNT_FILTER = 6;
+    private static final int SUBACTIVITY_CUSTOMIZE_FILTER = 7;
 
     private static final String KEY_SEARCH_MODE = "searchMode";
 
@@ -121,8 +123,6 @@
 
     private boolean mSearchMode;
 
-    private ContactBrowseListFragment mListFragment;
-
     /**
      * Whether we have a right-side contact or group detail pane for displaying info on that
      * contact or group while browsing. Generally means "this is a tablet".
@@ -155,7 +155,10 @@
 
     private boolean mOptionsMenuContactsAvailable;
 
-    private DefaultContactBrowseListFragment mContactsFragment;
+    /**
+     * Showing a list of Contacts. Also used for showing search results in search mode.
+     */
+    private DefaultContactBrowseListFragment mAllFragment;
     private StrequentContactListFragment mFavoritesFragment;
     private StrequentContactListFragment mFrequentFragment;
     private GroupBrowseListFragment mGroupsFragment;
@@ -168,18 +171,39 @@
 
     private ContactDetailLayoutController mContactDetailLayoutController;
 
-    private Handler mHandler = new Handler();
+    private final Handler mHandler = new Handler();
+
+    /**
+     * TODO: Use ViewPager so that tabs can be swiped left and right. Figure out how to use the
+     * support library in our app.
+     */
+    private final TabListener mTabListener = new TabListener() {
+        @Override
+        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
+            hideFragmentOnTabUnselect((TabState) tab.getTag(), ft);
+        }
+
+        @Override
+        public void onTabSelected(Tab tab, FragmentTransaction ft) {
+            final TabState tabState = (TabState) tab.getTag();
+            setSelectedTab(tabState);
+            showFragmentOnTabSelect(tabState, ft);
+            invalidateOptionsMenu();
+        }
+
+        @Override
+        public void onTabReselected(Tab tab, FragmentTransaction ft) {
+        }
+    };
 
     private enum TabState {
-        FAVORITES, CONTACTS, GROUPS
+        FAVORITES, ALL, GROUPS
     }
 
     private TabState mSelectedTab;
 
     public PeopleActivity() {
         mIntentResolver = new ContactsIntentResolver(this);
-        // TODO: Get rid of the ContactListFilterController class because there aren't any
-        // dropdown filters anymore. Just store the selected filter as a member variable.
         mContactListFilterController = new ContactListFilterController(this);
         mContactListFilterController.addListener(this);
         mProviderStatusLoader = new ProviderStatusLoader(this);
@@ -191,12 +215,12 @@
 
     @Override
     public void onAttachFragment(Fragment fragment) {
-        if (fragment instanceof ContactBrowseListFragment) {
-            mListFragment = (ContactBrowseListFragment)fragment;
-            mListFragment.setOnContactListActionListener(new ContactBrowserActionListener());
+        if (fragment instanceof DefaultContactBrowseListFragment) {
+            mAllFragment = (DefaultContactBrowseListFragment)fragment;
+            mAllFragment.setOnContactListActionListener(new ContactBrowserActionListener());
             if (!getWindow().hasFeature(Window.FEATURE_ACTION_BAR)) {
-                mListFragment.setContextMenuAdapter(
-                        new ContactBrowseListContextMenuAdapter(mListFragment));
+                mAllFragment.setContextMenuAdapter(
+                        new ContactBrowseListContextMenuAdapter(mAllFragment));
             }
         } else if (fragment instanceof GroupBrowseListFragment) {
             mGroupsFragment = (GroupBrowseListFragment) fragment;
@@ -269,13 +293,13 @@
                     .findFragmentById(R.id.favorites_fragment);
             mFrequentFragment = (StrequentContactListFragment) fragmentManager
                     .findFragmentById(R.id.frequent_fragment);
-            mContactsFragment = (DefaultContactBrowseListFragment) fragmentManager
-                    .findFragmentById(R.id.contacts_fragment);
+            mAllFragment = (DefaultContactBrowseListFragment) fragmentManager
+                    .findFragmentById(R.id.all_fragment);
             mGroupsFragment = (GroupBrowseListFragment) fragmentManager
                     .findFragmentById(R.id.groups_fragment);
             // Hide all tabs (the current tab will later be reshown once a tab is selected)
             final FragmentTransaction transaction = fragmentManager.beginTransaction();
-            transaction.hide(mContactsFragment);
+            transaction.hide(mAllFragment);
             transaction.hide(mGroupsFragment);
 
             if (mFrequentFragment != null) {
@@ -303,8 +327,7 @@
         setTitle(mRequest.getActivityTitle());
         ActionBar actionBar = getActionBar();
         mActionBarAdapter = new ActionBarAdapter(this, this);
-        mActionBarAdapter.onCreate(savedState, mRequest, getActionBar(), !mContentPaneDisplayed);
-        mActionBarAdapter.setContactListFilterController(mContactListFilterController);
+        mActionBarAdapter.onCreate(savedState, mRequest, getActionBar());
 
         ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
         ContactDetailTabCarousel tabCarousel = (ContactDetailTabCarousel)
@@ -316,21 +339,21 @@
         if (createContentView) {
             actionBar.removeAllTabs();
             Tab favoritesTab = actionBar.newTab();
-            favoritesTab.setText(getString(R.string.strequentList));
-            favoritesTab.setTabListener(new TabChangeListener(mFavoritesFragment,
-                    mFrequentFragment, TabState.FAVORITES));
+            favoritesTab.setTag(TabState.FAVORITES);
+            favoritesTab.setText(getString(R.string.contactsFavoritesLabel));
+            favoritesTab.setTabListener(mTabListener);
             actionBar.addTab(favoritesTab);
 
-            Tab peopleTab = actionBar.newTab();
-            peopleTab.setText(getString(R.string.people));
-            peopleTab.setTabListener(new TabChangeListener(mContactsFragment,
-                    mContactDetailLoaderFragment, TabState.CONTACTS));
-            actionBar.addTab(peopleTab);
+            Tab allTab = actionBar.newTab();
+            allTab.setTag(TabState.ALL);
+            allTab.setText(getString(R.string.contactsAllLabel));
+            allTab.setTabListener(mTabListener);
+            actionBar.addTab(allTab);
 
             Tab groupsTab = actionBar.newTab();
+            groupsTab.setTag(TabState.GROUPS);
             groupsTab.setText(getString(R.string.contactsGroupsLabel));
-            groupsTab.setTabListener(new TabChangeListener(mGroupsFragment,
-                    mGroupDetailFragment, TabState.GROUPS));
+            groupsTab.setTabListener(mTabListener);
             actionBar.addTab(groupsTab);
             actionBar.setDisplayShowTitleEnabled(true);
 
@@ -344,47 +367,61 @@
         configureFragments(savedState == null);
     }
 
-    /**
-     * Tab change listener that is instantiated once for each tab. Handles showing/hiding fragments.
-     * TODO: Use ViewPager so that tabs can be swiped left and right. Figure out how to use the
-     * support library in our app.
-     */
-    private class TabChangeListener implements TabListener {
-        private final Fragment mBrowseListFragment;
-
-        /**
-         * Right pane fragment that is present on larger screen sizes (can be
-         * null for smaller screen sizes).
-         */
-        private final Fragment mDetailFragment;
-        private final TabState mTabState;
-
-        public TabChangeListener(Fragment listFragment, Fragment detailFragment, TabState state) {
-            mBrowseListFragment = listFragment;
-            mDetailFragment = detailFragment;
-            mTabState = state;
-        }
-
-        @Override
-        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
-            ft.hide(mBrowseListFragment);
-            if (mDetailFragment != null) {
-                ft.hide(mDetailFragment);
+    private void hideFragmentOnTabUnselect(TabState newTabState, FragmentTransaction ft) {
+        switch (newTabState) {
+            case FAVORITES: {
+                ft.hide(mFavoritesFragment);
+                if (mFrequentFragment != null) {
+                    ft.hide(mFrequentFragment);
+                }
+                break;
+            }
+            case ALL: {
+                ft.hide(mAllFragment);
+                if (mContactDetailFragment != null) {
+                    ft.hide(mContactDetailFragment);
+                }
+                break;
+            }
+            case GROUPS: {
+                ft.hide(mGroupsFragment);
+                if (mGroupDetailFragment != null) {
+                    ft.hide(mGroupDetailFragment);
+                }
+                break;
+            }
+            default: {
+                throw new IllegalStateException("Unexpected tab state: " + newTabState);
             }
         }
+    }
 
-        @Override
-        public void onTabSelected(Tab tab, FragmentTransaction ft) {
-            ft.show(mBrowseListFragment);
-            if (mDetailFragment != null) {
-                ft.show(mDetailFragment);
+    private void showFragmentOnTabSelect(TabState newTabState, FragmentTransaction ft) {
+        switch (newTabState) {
+            case FAVORITES: {
+                ft.show(mFavoritesFragment);
+                if (mFrequentFragment != null) {
+                    ft.show(mFrequentFragment);
+                }
+                break;
             }
-            setSelectedTab(mTabState);
-            invalidateOptionsMenu();
-        }
-
-        @Override
-        public void onTabReselected(Tab tab, FragmentTransaction ft) {
+            case ALL: {
+                ft.show(mAllFragment);
+                if (mContactDetailFragment != null) {
+                    ft.show(mContactDetailFragment);
+                }
+                break;
+            }
+            case GROUPS: {
+                ft.show(mGroupsFragment);
+                if (mGroupDetailFragment != null) {
+                    ft.show(mGroupDetailFragment);
+                }
+                break;
+            }
+            default: {
+                throw new IllegalStateException("Unexpected tab state: " + newTabState);
+            }
         }
     }
 
@@ -399,7 +436,7 @@
                     mDetailsView.setVisibility(View.GONE);
                     break;
                 case GROUPS:
-                case CONTACTS:
+                case ALL:
                     mFavoritesView.setVisibility(View.GONE);
                     mBrowserView.setVisibility(View.VISIBLE);
                     mDetailsView.setVisibility(View.VISIBLE);
@@ -475,7 +512,7 @@
                 mSearchMode = false;
             }
 
-            mListFragment.setContactsRequest(mRequest);
+            mAllFragment.setContactsRequest(mRequest);
             configureContactListFragmentForRequest();
 
         } else {
@@ -489,33 +526,16 @@
     }
 
     @Override
-    public void onContactListFiltersLoaded() {
-        if (mListFragment == null || !mListFragment.isAdded()) {
-            return;
-        }
-
-        mListFragment.setFilter(mContactListFilterController.getFilter());
-
-        invalidateOptionsMenuIfNeeded();
-    }
-
-    @Override
     public void onContactListFilterChanged() {
-        if (mListFragment == null || !mListFragment.isAdded()) {
+        if (mAllFragment == null || !mAllFragment.isAdded()) {
             return;
         }
 
-        mListFragment.setFilter(mContactListFilterController.getFilter());
+        mAllFragment.setFilter(mContactListFilterController.getFilter());
 
         invalidateOptionsMenuIfNeeded();
     }
 
-    @Override
-    public void onContactListFilterCustomizationRequest() {
-        startActivityForResult(new Intent(this, CustomContactListFilterActivity.class),
-                SUBACTIVITY_CUSTOMIZE_FILTER);
-    }
-
     private void setupContactDetailFragment(final Uri contactLookupUri) {
         mContactDetailLoaderFragment.loadUri(contactLookupUri);
         invalidateOptionsMenuIfNeeded();
@@ -541,7 +561,7 @@
                 }
                 // Bring the contact list fragment (and detail fragment if applicable) to the front
                 FragmentTransaction ft = getFragmentManager().beginTransaction();
-                ft.show(mContactsFragment);
+                ft.show(mAllFragment);
                 if (mContactDetailFragment != null) ft.show(mContactDetailFragment);
                 ft.commit();
                 clearSearch();
@@ -553,9 +573,9 @@
 
                 // If the last selected tab was not the "All contacts" tab, then hide these
                 // fragments because we need to show favorites or groups.
-                if (mSelectedTab != null && !mSelectedTab.equals(TabState.CONTACTS)) {
+                if (mSelectedTab != null && !mSelectedTab.equals(TabState.ALL)) {
                     FragmentTransaction transaction = getFragmentManager().beginTransaction();
-                    transaction.hide(mContactsFragment);
+                    transaction.hide(mAllFragment);
                     if (mContactDetailFragment != null) transaction.hide(mContactDetailFragment);
                     transaction.commit();
                 }
@@ -575,39 +595,39 @@
 
     private void loadSearch(String query) {
         configureFragments(false /* from request */);
-        mListFragment.setQueryString(query, true);
+        mAllFragment.setQueryString(query, true);
     }
 
     private void configureContactListFragmentForRequest() {
         Uri contactUri = mRequest.getContactUri();
         if (contactUri != null) {
-            mListFragment.setSelectedContactUri(contactUri);
+            mAllFragment.setSelectedContactUri(contactUri);
         }
 
-        mListFragment.setSearchMode(mRequest.isSearchMode());
-        mListFragment.setQueryString(mRequest.getQueryString(), false);
+        mAllFragment.setSearchMode(mRequest.isSearchMode());
+        mAllFragment.setQueryString(mRequest.getQueryString(), false);
 
         if (mRequest.isDirectorySearchEnabled()) {
-            mListFragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DEFAULT);
+            mAllFragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DEFAULT);
         } else {
-            mListFragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
+            mAllFragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
         }
 
-        if (mContactListFilterController.isLoaded()) {
-            mListFragment.setFilter(mContactListFilterController.getFilter());
+        if (mContactListFilterController.isInitialized()) {
+            mAllFragment.setFilter(mContactListFilterController.getFilter());
         }
     }
 
     private void configureContactListFragment() {
-        mListFragment.setSearchMode(mSearchMode);
+        mAllFragment.setSearchMode(mSearchMode);
 
-        mListFragment.setVisibleScrollbarEnabled(!mSearchMode);
-        mListFragment.setVerticalScrollbarPosition(
+        mAllFragment.setVisibleScrollbarEnabled(!mSearchMode);
+        mAllFragment.setVerticalScrollbarPosition(
                 mContentPaneDisplayed
                         ? View.SCROLLBAR_POSITION_LEFT
                         : View.SCROLLBAR_POSITION_RIGHT);
-        mListFragment.setSelectionVisible(mContentPaneDisplayed);
-        mListFragment.setQuickContactEnabled(!mContentPaneDisplayed);
+        mAllFragment.setSelectionVisible(mContentPaneDisplayed);
+        mAllFragment.setQuickContactEnabled(!mContentPaneDisplayed);
     }
 
     private void configureGroupListFragment() {
@@ -639,12 +659,12 @@
             if (mainView != null) {
                 mainView.setVisibility(View.VISIBLE);
             }
-            if (mListFragment != null) {
-                mListFragment.setEnabled(true);
+            if (mAllFragment != null) {
+                mAllFragment.setEnabled(true);
             }
         } else {
-            if (mListFragment != null) {
-                mListFragment.setEnabled(false);
+            if (mAllFragment != null) {
+                mAllFragment.setEnabled(false);
             }
             if (mContactsUnavailableFragment == null) {
                 mContactsUnavailableFragment = new ContactsUnavailableFragment();
@@ -671,7 +691,7 @@
         @Override
         public void onSelectionChange() {
             if (mContentPaneDisplayed) {
-                setupContactDetailFragment(mListFragment.getSelectedContactUri());
+                setupContactDetailFragment(mAllFragment.getSelectedContactUri());
             }
         }
 
@@ -741,16 +761,16 @@
         @Override
         public void onInvalidSelection() {
             ContactListFilter filter;
-            ContactListFilter currentFilter = mListFragment.getFilter();
+            ContactListFilter currentFilter = mAllFragment.getFilter();
             if (currentFilter != null
                     && currentFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
                 filter = ContactListFilter.createFilterWithType(
                         ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
-                mListFragment.setFilter(filter);
+                mAllFragment.setFilter(filter);
             } else {
                 filter = ContactListFilter.createFilterWithType(
                         ContactListFilter.FILTER_TYPE_SINGLE_CONTACT);
-                mListFragment.setFilter(filter, false);
+                mAllFragment.setFilter(filter, false);
             }
             mContactListFilterController.setContactListFilter(filter, true);
         }
@@ -935,16 +955,6 @@
 
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.actions, menu);
-        MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
-        if (searchMenuItem != null && searchMenuItem.getActionView() instanceof SearchView) {
-            SearchView searchView = (SearchView) searchMenuItem.getActionView();
-            searchView.setQueryHint(getString(R.string.hint_findContacts));
-            searchView.setIconifiedByDefault(false);
-
-            if (mActionBarAdapter != null) {
-                mActionBarAdapter.setSearchView(searchView);
-            }
-        }
 
         // On narrow screens we specify a NEW group button in the {@link ActionBar}, so that
         // it can be in the overflow menu. On wide screens, we use a custom view because we need
@@ -976,7 +986,7 @@
             return true;
         }
 
-        if (mListFragment != null && mListFragment.isOptionsMenuChanged()) {
+        if (mAllFragment != null && mAllFragment.isOptionsMenuChanged()) {
             return true;
         }
 
@@ -1009,17 +1019,15 @@
         if (mActionBarAdapter.isSearchMode()) {
             addContactMenu.setVisible(false);
             addGroupMenu.setVisible(false);
-            // If search is normally in the overflow menu, when we are in search
-            // mode, hide this option.
-            if (mActionBarAdapter.isSearchInOverflowMenu()) {
-                searchMenu.setVisible(false);
+            if (searchMenu != null) {
+                searchMenu.setVisible(false); // Don't show the search menu in search mode.
             }
         } else {
             switch (mSelectedTab) {
                 case FAVORITES:
                     // TODO: Fall through until we determine what the menu items should be for
                     // this tab
-                case CONTACTS:
+                case ALL:
                     addContactMenu.setVisible(true);
                     addGroupMenu.setVisible(false);
                     break;
@@ -1047,8 +1055,8 @@
                 return true;
             }
             case R.id.menu_contacts_filter: {
-                final Intent intent = new Intent(this, CustomContactListFilterActivity.class);
-                startActivityForResult(intent, SUBACTIVITY_CUSTOMIZE_FILTER);
+                final Intent intent = new Intent(this, AccountFilterActivity.class);
+                startActivityForResult(intent, SUBACTIVITY_ACCOUNT_FILTER);
                 return true;
             }
             case R.id.menu_search: {
@@ -1117,8 +1125,8 @@
     @Override
     public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
             boolean globalSearch) {
-        if (mListFragment != null && mListFragment.isAdded() && !globalSearch) {
-            mListFragment.startSearch(initialQuery);
+        if (mAllFragment != null && mAllFragment.isAdded() && !globalSearch) {
+            mAllFragment.startSearch(initialQuery);
         } else {
             super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
         }
@@ -1127,18 +1135,35 @@
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         switch (requestCode) {
+            case SUBACTIVITY_ACCOUNT_FILTER: {
+                if (resultCode == Activity.RESULT_OK) {
+                    ContactListFilter filter = (ContactListFilter) data.getParcelableExtra(
+                            AccountFilterActivity.KEY_EXTRA_CONTACT_LIST_FILTER);
+                    if (filter == null) {
+                        return;
+                    }
+                    // If this is a custom filter, launch the activity to customize the display list
+                    if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
+                        final Intent intent = new Intent(this,
+                                CustomContactListFilterActivity.class);
+                        startActivityForResult(intent, SUBACTIVITY_CUSTOMIZE_FILTER);
+                    } else {
+                        mContactListFilterController.setContactListFilter(filter, true);
+                    }
+                }
+                break;
+            }
             case SUBACTIVITY_CUSTOMIZE_FILTER: {
                 if (resultCode == Activity.RESULT_OK) {
                     mContactListFilterController.selectCustomFilter();
                 }
                 break;
             }
-
             case SUBACTIVITY_EDIT_CONTACT:
             case SUBACTIVITY_NEW_CONTACT: {
                 if (resultCode == RESULT_OK && mContentPaneDisplayed) {
                     mRequest.setActionCode(ContactsRequest.ACTION_VIEW_CONTACT);
-                    mListFragment.reloadDataAndSetSelectedUri(data.getData());
+                    mAllFragment.reloadDataAndSetSelectedUri(data.getData());
                 }
                 break;
             }
@@ -1156,7 +1181,7 @@
             // anymore
             case ContactEntryListFragment.ACTIVITY_REQUEST_CODE_PICKER:
                 if (resultCode == RESULT_OK) {
-                    mListFragment.onPickerResult(data);
+                    mAllFragment.onPickerResult(data);
                 }
 
 // TODO fix or remove multipicker code
@@ -1171,7 +1196,7 @@
 
     @Override
     public boolean onContextItemSelected(MenuItem item) {
-        ContextMenuAdapter menuAdapter = mListFragment.getContextMenuAdapter();
+        ContextMenuAdapter menuAdapter = mAllFragment.getContextMenuAdapter();
         if (menuAdapter != null) {
             return menuAdapter.onContextItemSelected(item);
         }
@@ -1274,7 +1299,7 @@
 
     // Visible for testing
     public ContactBrowseListFragment getListFragment() {
-        return mListFragment;
+        return mAllFragment;
     }
 
     // Visible for testing
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 9dc50f2..84e6a8a 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -176,8 +176,25 @@
     /** Adapter class to fill in data for the Call Log */
     public final class CallLogAdapter extends GroupingListAdapter
             implements Runnable, ViewTreeObserver.OnPreDrawListener, View.OnClickListener {
+        /** The time in millis to delay starting the thread processing requests. */
+        private static final int START_PROCESSING_REQUESTS_DELAY_MILLIS = 1000;
+
+        /**
+         * A cache of the contact details for the phone numbers in the call log.
+         * <p>
+         * The content of the cache is expired (but not purged) whenever the application comes to
+         * the foreground.
+         */
         private ExpirableCache<String, ContactInfo> mContactInfoCache;
+
+        /**
+         * List of requests to update contact details.
+         * <p>
+         * The requests are added when displaying the contacts and are processed by a background
+         * thread.
+         */
         private final LinkedList<CallerInfoQuery> mRequests;
+
         private volatile boolean mDone;
         private boolean mLoading = true;
         private ViewTreeObserver.OnPreDrawListener mPreDrawListener;
@@ -220,7 +237,8 @@
         @Override
         public boolean onPreDraw() {
             if (mFirst) {
-                mHandler.sendEmptyMessageDelayed(START_THREAD, 1000);
+                mHandler.sendEmptyMessageDelayed(START_THREAD,
+                        START_PROCESSING_REQUESTS_DELAY_MILLIS);
                 mFirst = false;
             }
             return true;
@@ -234,9 +252,7 @@
                         notifyDataSetChanged();
                         break;
                     case START_THREAD:
-                        if (!mRequestProcessingDisabled) {
-                            startRequestProcessing();
-                        }
+                        startRequestProcessing();
                         break;
                 }
             }
@@ -296,6 +312,10 @@
         }
 
         public void startRequestProcessing() {
+            if (mRequestProcessingDisabled) {
+                return;
+            }
+
             mDone = false;
             mCallerIdThread = new Thread(this);
             mCallerIdThread.setPriority(Thread.MIN_PRIORITY);
@@ -346,7 +366,7 @@
             }
         }
 
-        private void enqueueRequest(String number, int position,
+        private void enqueueRequest(String number, boolean immediate, int position,
                 String name, int numberType, String numberLabel, long photoId, String lookupKey) {
             CallerInfoQuery ciq = new CallerInfoQuery();
             ciq.number = number;
@@ -360,6 +380,10 @@
                 mRequests.add(ciq);
                 mRequests.notifyAll();
             }
+            if (mFirst && immediate) {
+                startRequestProcessing();
+                mFirst = false;
+            }
         }
 
         private boolean queryContactInfo(CallerInfoQuery ciq) {
@@ -675,7 +699,8 @@
                 info = ContactInfo.EMPTY;
                 mContactInfoCache.put(number, info);
                 Log.d(TAG, "Contact info missing: " + number);
-                enqueueRequest(number, c.getPosition(),
+                // Request the contact details immediately since they are currently missing.
+                enqueueRequest(number, true, c.getPosition(),
                         callerName, callerNumberType, callerNumberLabel, 0L, "");
             } else if (info != ContactInfo.EMPTY) { // Has been queried
                 // Check if any data is different from the data cached in the
@@ -686,7 +711,8 @@
                         || !TextUtils.equals(info.label, callerNumberLabel)) {
                     // Something is amiss, so sync up.
                     Log.w(TAG, "Contact info inconsistent: " + number);
-                    enqueueRequest(number, c.getPosition(),
+                    // Request the contact details immediately since they are probably wrong.
+                    enqueueRequest(number, true, c.getPosition(),
                             callerName, callerNumberType, callerNumberLabel, info.photoId,
                             info.lookupKey);
                 } else if (cachedInfo.isExpired()) {
@@ -694,8 +720,9 @@
                     // Put it back in the cache, therefore marking it as not expired, so that other
                     // entries with the same number will not re-request it.
                     mContactInfoCache.put(number, info);
-                    // The contact info is no longer up to date, we should request it.
-                    enqueueRequest(number, c.getPosition(), info.name, info.type, info.label,
+                    // The contact info is no longer up to date, we should request it. However, we
+                    // do not need to request them immediately.
+                    enqueueRequest(number, false, c.getPosition(), info.name, info.type, info.label,
                             info.photoId, info.lookupKey);
                 }
 
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 2cd7b3c..ece2a29 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -110,6 +110,7 @@
     private static final String KEY_VIEW_ID_GENERATOR = "viewidgenerator";
     private static final String KEY_CURRENT_PHOTO_FILE = "currentphotofile";
     private static final String KEY_CONTACT_ID_FOR_JOIN = "contactidforjoin";
+    private static final String KEY_CONTACT_WRITABLE_FOR_JOIN = "contactwritableforjoin";
     private static final String KEY_SHOW_JOIN_SUGGESTIONS = "showJoinSuggestions";
     private static final String KEY_ENABLED = "enabled";
     private static final String KEY_STATUS = "status";
@@ -222,6 +223,7 @@
     private Listener mListener;
 
     private long mContactIdForJoin;
+    private boolean mContactWritableForJoin;
 
     private LinearLayout mContent;
     private EntityDeltaList mState;
@@ -274,9 +276,7 @@
 
         // If anything was left unsaved, save it now but keep the editor open.
         if (!getActivity().isChangingConfigurations() && mStatus == Status.EDITING) {
-            if (mStatus != SaveMode.JOIN) {
-                save(SaveMode.RELOAD);
-            }
+            save(SaveMode.RELOAD);
         }
     }
 
@@ -373,6 +373,7 @@
                 mCurrentPhotoFile = new File(fileName);
             }
             mContactIdForJoin = savedState.getLong(KEY_CONTACT_ID_FOR_JOIN);
+            mContactWritableForJoin = savedState.getBoolean(KEY_CONTACT_WRITABLE_FOR_JOIN);
             mAggregationSuggestionsRawContactId = savedState.getLong(KEY_SHOW_JOIN_SUGGESTIONS);
             mEnabled = savedState.getBoolean(KEY_ENABLED);
             mStatus = savedState.getInt(KEY_STATUS);
@@ -981,17 +982,17 @@
             case SaveMode.RELOAD:
             case SaveMode.JOIN:
                 if (success && contactLookupUri != null) {
+                    // If it was a JOIN, we are now ready to bring up the join activity.
+                    if (saveMode == SaveMode.JOIN) {
+                        showJoinAggregateActivity(contactLookupUri);
+                    }
+
                     // If this was in INSERT, we are changing into an EDIT now.
                     // If it already was an EDIT, we are changing to the new Uri now
                     mState = null;
                     load(Intent.ACTION_EDIT, contactLookupUri, null);
                     mStatus = Status.LOADING;
                     getLoaderManager().restartLoader(LOADER_DATA, null, mDataLoaderListener);
-
-                    // If it was a JOIN, we are now ready to bring up the join activity.
-                    if (saveMode == SaveMode.JOIN) {
-                        showJoinAggregateActivity(contactLookupUri);
-                    }
                 }
                 break;
 
@@ -1017,6 +1018,7 @@
         }
 
         mContactIdForJoin = ContentUris.parseId(contactLookupUri);
+        mContactWritableForJoin = isContactWritable();
         final Intent intent = new Intent(JoinContactActivity.JOIN_CONTACT);
         intent.putExtra(JoinContactActivity.EXTRA_TARGET_CONTACT_ID, mContactIdForJoin);
         startActivityForResult(intent, REQUEST_CODE_JOIN);
@@ -1027,7 +1029,7 @@
      */
     private void joinAggregate(final long contactId) {
         Intent intent = ContactSaveService.createJoinContactsIntent(mContext, mContactIdForJoin,
-                contactId, isContactWritable(),
+                contactId, mContactWritableForJoin,
                 ContactEditorActivity.class, ContactEditorActivity.ACTION_JOIN_COMPLETED);
         mContext.startService(intent);
     }
@@ -1460,6 +1462,7 @@
             outState.putString(KEY_CURRENT_PHOTO_FILE, mCurrentPhotoFile.toString());
         }
         outState.putLong(KEY_CONTACT_ID_FOR_JOIN, mContactIdForJoin);
+        outState.putBoolean(KEY_CONTACT_WRITABLE_FOR_JOIN, mContactWritableForJoin);
         outState.putLong(KEY_SHOW_JOIN_SUGGESTIONS, mAggregationSuggestionsRawContactId);
         outState.putBoolean(KEY_ENABLED, mEnabled);
         outState.putInt(KEY_STATUS, mStatus);
@@ -1586,6 +1589,7 @@
             Log.v(TAG, "Time needed for setting UI: " + (setDataEndTime-setDataStartTime));
         }
 
+        @Override
         public void onLoaderReset(Loader<ContactLoader.Result> loader) {
         }
     };
diff --git a/src/com/android/contacts/group/GroupBrowseListFragment.java b/src/com/android/contacts/group/GroupBrowseListFragment.java
index db16502..0b53acf 100644
--- a/src/com/android/contacts/group/GroupBrowseListFragment.java
+++ b/src/com/android/contacts/group/GroupBrowseListFragment.java
@@ -197,6 +197,8 @@
             String accountType = mGroupListCursor.getString(GroupMetaDataLoader.ACCOUNT_TYPE);
             long groupId = mGroupListCursor.getLong(GroupMetaDataLoader.GROUP_ID);
             String title = mGroupListCursor.getString(GroupMetaDataLoader.TITLE);
+            boolean deleted =
+                    (mGroupListCursor.getInt(GroupMetaDataLoader.DELETED) == 1);
             boolean defaultGroup = mGroupListCursor.isNull(GroupMetaDataLoader.AUTO_ADD)
                     ? false
                     : mGroupListCursor.getInt(GroupMetaDataLoader.AUTO_ADD) != 0;
@@ -205,8 +207,8 @@
                     : mGroupListCursor.getInt(GroupMetaDataLoader.FAVORITES) != 0;
 
             // Don't show the "auto-added" (i.e. My Contacts) or "favorites" groups because
-            // they show up elsewhere in the app
-            if (defaultGroup || favorites) {
+            // they show up elsewhere in the app. Also skip groups that are marked as "deleted"
+            if (defaultGroup || favorites || deleted) {
                 continue;
             }
 
diff --git a/src/com/android/contacts/group/GroupDetailFragment.java b/src/com/android/contacts/group/GroupDetailFragment.java
index c4824ae..fe2605e 100644
--- a/src/com/android/contacts/group/GroupDetailFragment.java
+++ b/src/com/android/contacts/group/GroupDetailFragment.java
@@ -90,6 +90,7 @@
     private String mGroupName;
 
     private boolean mOptionsMenuEditable;
+    private boolean mCloseActivityAfterDelete;
 
     public GroupDetailFragment() {
     }
@@ -190,11 +191,20 @@
 
         @Override
         public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
-            bindGroupMetaData(data);
+            data.moveToPosition(-1);
+            if (data.moveToNext()) {
+                boolean deleted = data.getInt(GroupMetaDataLoader.DELETED) == 1;
+                if (!deleted) {
+                    bindGroupMetaData(data);
 
-            // Retrieve the list of members
-            configureAdapter(mGroupId);
-            startGroupMembersLoader();
+                    // Retrieve the list of members
+                    configureAdapter(mGroupId);
+                    startGroupMembersLoader();
+                    return;
+                }
+            }
+            updateSize(null);
+            updateTitle(null);
         }
 
         @Override
@@ -295,10 +305,15 @@
                 break;
             }
             case R.id.menu_delete_group: {
-                GroupDeletionDialogFragment.show(getFragmentManager(), mGroupId, mGroupName);
+                GroupDeletionDialogFragment.show(getFragmentManager(), mGroupId, mGroupName,
+                        mCloseActivityAfterDelete);
                 return true;
             }
         }
         return false;
     }
+
+    public void closeActivityAfterDelete(boolean closeActivity) {
+        mCloseActivityAfterDelete = closeActivity;
+    }
 }
diff --git a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
index 44d31be..c9c1342 100644
--- a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
@@ -33,8 +33,15 @@
     private static final String ARG_GROUP_ID = "groupId";
     private static final String ARG_LABEL = "label";
 
-    public static void show(FragmentManager fragmentManager, long groupId, String label) {
-        GroupDeletionDialogFragment dialog = new GroupDeletionDialogFragment();
+    private boolean mEndActivity;
+
+    public GroupDeletionDialogFragment(boolean endActivity) {
+        mEndActivity = endActivity;
+    }
+
+    public static void show(FragmentManager fragmentManager, long groupId, String label,
+            boolean endActivity) {
+        GroupDeletionDialogFragment dialog = new GroupDeletionDialogFragment(endActivity);
         Bundle args = new Bundle();
         args.putLong(ARG_GROUP_ID, groupId);
         args.putString(ARG_LABEL, label);
@@ -69,5 +76,8 @@
 
         getActivity().startService(ContactSaveService.createGroupDeletionIntent(
                 getActivity(), groupId));
+        if (mEndActivity) {
+            getActivity().finish();
+        }
     }
 }
diff --git a/src/com/android/contacts/list/AccountFilterActivity.java b/src/com/android/contacts/list/AccountFilterActivity.java
new file mode 100644
index 0000000..c38599e
--- /dev/null
+++ b/src/com/android/contacts/list/AccountFilterActivity.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2011 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.list;
+
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.ContactsSearchManager;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountType;
+import com.android.contacts.model.AccountTypeManager;
+
+import android.accounts.Account;
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Shows a list of all available accounts, letting the user select under which account to view
+ * contacts.
+ */
+public class AccountFilterActivity extends ContactsActivity
+        implements AdapterView.OnItemClickListener {
+
+    private static final String TAG = AccountFilterActivity.class.getSimpleName();
+
+    public static final String KEY_EXTRA_CONTACT_LIST_FILTER = "contactListFilter";
+
+    private ListView mListView;
+
+    private List<ContactListFilter> mFilters = new ArrayList<ContactListFilter>();
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.contact_list_filter);
+
+        mListView = (ListView) findViewById(com.android.internal.R.id.list);
+        mListView.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                finishAndSetResult(mFilters.get(position));
+            }
+        });
+
+        ActionBar actionBar =  getActionBar();
+        if (actionBar != null) {
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
+
+        loadAccountFilters();
+    }
+
+    private void loadAccountFilters() {
+        ArrayList<ContactListFilter> accountFilters = new ArrayList<ContactListFilter>();
+        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
+        ArrayList<Account> accounts = accountTypes.getAccounts(false);
+        for (Account account : accounts) {
+            AccountType accountType = accountTypes.getAccountType(account.type);
+            Drawable icon = accountType != null ? accountType.getDisplayIcon(this) : null;
+            accountFilters.add(ContactListFilter.createAccountFilter(account.type, account.name,
+                    icon, account.name));
+        }
+        int count = accountFilters.size();
+
+        if (count >= 1) {
+            // If we only have one account, don't show it as "account", instead show it as "all"
+            mFilters.add(ContactListFilter.createFilterWithType(
+                    ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS));
+            if (count > 1) {
+                mFilters.addAll(accountFilters);
+                mFilters.add(ContactListFilter.createFilterWithType(
+                    ContactListFilter.FILTER_TYPE_CUSTOM));
+            }
+        }
+
+        mListView.setAdapter(new FilterListAdapter(this));
+    }
+
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        finishAndSetResult(mFilters.get(position));
+    }
+
+    private void finishAndSetResult(ContactListFilter filter) {
+        final Intent intent = new Intent();
+        intent.putExtra(KEY_EXTRA_CONTACT_LIST_FILTER, filter);
+        setResult(Activity.RESULT_OK, intent);
+        finish();
+    }
+
+    @Override
+    public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
+            boolean globalSearch) {
+        if (globalSearch) {
+            super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
+        } else {
+            ContactsSearchManager.startSearch(this, initialQuery);
+        }
+    }
+
+    private class FilterListAdapter extends BaseAdapter {
+        private LayoutInflater mLayoutInflater;
+
+        public FilterListAdapter(Context context) {
+            mLayoutInflater = (LayoutInflater) context.getSystemService
+                    (Context.LAYOUT_INFLATER_SERVICE);
+        }
+
+        @Override
+        public int getCount() {
+            return mFilters.size();
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public ContactListFilter getItem(int position) {
+            return mFilters.get(position);
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ContactListFilterView view;
+            if (convertView != null) {
+                view = (ContactListFilterView) convertView;
+            } else {
+                view = (ContactListFilterView) mLayoutInflater.inflate(
+                        R.layout.filter_spinner_item, parent, false);
+            }
+            view.setSingleAccount(mFilters.size() == 1);
+            ContactListFilter filter = mFilters.get(position);
+            view.setContactListFilter(filter);
+            view.bindView(true);
+            return view;
+        }
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case android.R.id.home:
+                finish();
+                return true;
+            default:
+                break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/src/com/android/contacts/list/ContactListFilterController.java b/src/com/android/contacts/list/ContactListFilterController.java
index 533f24a..28b62ca 100644
--- a/src/com/android/contacts/list/ContactListFilterController.java
+++ b/src/com/android/contacts/list/ContactListFilterController.java
@@ -15,67 +15,43 @@
  */
 package com.android.contacts.list;
 
-import com.android.contacts.R;
-
 import android.app.Activity;
-import android.app.LoaderManager;
-import android.app.LoaderManager.LoaderCallbacks;
 import android.content.Context;
-import android.content.Loader;
 import android.content.SharedPreferences;
-import android.content.res.TypedArray;
-import android.os.Bundle;
 import android.preference.PreferenceManager;
-import android.text.TextUtils;
-import android.util.SparseArray;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.BaseAdapter;
-import android.widget.ListPopupWindow;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * Controls a list of {@link ContactListFilter}'s.
+ * Stores the {@link ContactListFilter} selected by the user and saves it to
+ * {@link SharedPreferences} if necessary.
  */
-// TODO: Remove the extra functionality dealing with loading and displaying a list of filters in
-// the action bar.
-public class ContactListFilterController
-        implements LoaderCallbacks<List<ContactListFilter>>, OnClickListener, OnItemClickListener {
+public class ContactListFilterController {
 
     public interface ContactListFilterListener {
-        void onContactListFiltersLoaded();
         void onContactListFilterChanged();
-        void onContactListFilterCustomizationRequest();
     }
 
     private Context mContext;
-    private LoaderManager mLoaderManager;
-    private boolean mEnabled = true;
     private List<ContactListFilterListener> mListeners = new ArrayList<ContactListFilterListener>();
-    private ListPopupWindow mPopup;
-    private int mPopupWidth = -1;
-    private List<ContactListFilter> mCachedFilters;
-    private SparseArray<ContactListFilter> mFilters;
-    private int mNextFilterId = 1;
-    private View mAnchor;
-    private FilterListAdapter mFilterListAdapter;
     private ContactListFilter mFilter;
-    private boolean mFiltersLoaded;
-    private int mAccountCount;
+
+    private boolean mIsInitialized;
 
     public ContactListFilterController(Activity activity) {
         mContext = activity;
-        mLoaderManager = activity.getLoaderManager();
     }
 
-    public void setEnabled(boolean flag) {
-        mEnabled = flag;
+    public void onStart() {
+        if (mFilter == null) {
+            mFilter = ContactListFilter.restoreFromPreferences(getSharedPreferences());
+            mIsInitialized = true;
+        }
+    }
+
+    public boolean isInitialized() {
+        return mIsInitialized;
     }
 
     public void addListener(ContactListFilterListener listener) {
@@ -90,157 +66,10 @@
         return mFilter;
     }
 
-    public int getFilterCount() {
-        return mFilters != null ? mFilters.size() : 0;
-    }
-
-    public boolean isLoaded() {
-        return mFiltersLoaded;
-    }
-
-    public void onStart() {
-        if (mFilter == null) {
-            mFilter = ContactListFilter.restoreFromPreferences(getSharedPreferences());
-        }
-    }
-
     private SharedPreferences getSharedPreferences() {
         return PreferenceManager.getDefaultSharedPreferences(mContext);
     }
 
-    @Override
-    public ContactListFilterLoader onCreateLoader(int id, Bundle args) {
-        return new ContactListFilterLoader(mContext);
-    }
-
-    @Override
-    public void onLoadFinished(
-            Loader<List<ContactListFilter>> loader, List<ContactListFilter> filters) {
-        int count = filters.size();
-        if (mCachedFilters != null && mCachedFilters.size() == count) {
-            boolean changed = false;
-            for (int i = 0; i < filters.size(); i++) {
-                ContactListFilter filter1 = mCachedFilters.get(i);
-                ContactListFilter filter2 = filters.get(i);
-                if (!filter1.equals(filter2)) {
-                    changed = true;
-                    break;
-                }
-
-                // Group title is intentionally not included in the "equals" algorithm for
-                // ContactListFilter, because we want stability of filter identity
-                // across label changes.  However, here we do care about the label changes.
-                if (filter1.filterType == ContactListFilter.FILTER_TYPE_GROUP &&
-                        !TextUtils.equals(filter1.title, filter2.title)) {
-                    changed = true;
-                    break;
-                }
-            }
-
-            if (!changed) {
-                return;
-            }
-        }
-
-        mCachedFilters = filters;
-
-        if (mFilters == null) {
-            mFilters = new SparseArray<ContactListFilter>(filters.size());
-        } else {
-            mFilters.clear();
-        }
-
-        boolean filterValid = mFilter != null && !mFilter.isValidationRequired();
-
-        mAccountCount = 0;
-        for (int index = 0; index < count; index++) {
-            if (filters.get(index).filterType == ContactListFilter.FILTER_TYPE_ACCOUNT) {
-                mAccountCount++;
-            }
-        }
-
-        if (mAccountCount != 1) {
-            mFilters.append(mNextFilterId++, ContactListFilter.createFilterWithType(
-                    ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS));
-            mFilters.append(mNextFilterId++, ContactListFilter.createFilterWithType(
-                    ContactListFilter.FILTER_TYPE_STARRED));
-        }
-
-        for (int index = 0; index < count; index++) {
-            ContactListFilter filter = filters.get(index);
-
-            boolean firstAndOnly = mAccountCount == 1
-                    && filter.filterType == ContactListFilter.FILTER_TYPE_ACCOUNT;
-
-            // If we only have one account, don't show it as "account", instead show it as "all"
-            if (firstAndOnly) {
-                filter = ContactListFilter.createFilterWithType(
-                        ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
-            }
-
-            mFilters.append(mNextFilterId++, filter);
-
-            if (filter.equals(mFilter)) {
-                // Refresh the filter in case the title got changed
-                mFilter = filter;
-                filterValid = true;
-            }
-
-            if (firstAndOnly) {
-                mFilters.append(mNextFilterId++, ContactListFilter.createFilterWithType(
-                        ContactListFilter.FILTER_TYPE_STARRED));
-            }
-        }
-
-        if (mAccountCount > 0) {
-            mFilters.append(mNextFilterId++, ContactListFilter.createFilterWithType(
-                    ContactListFilter.FILTER_TYPE_CUSTOM));
-        }
-
-        boolean filterChanged = false;
-        if (mFilter == null  || !filterValid) {
-            filterChanged = mFilter != null;
-            mFilter = getDefaultFilter();
-        }
-
-        if (mFilterListAdapter == null) {
-            mFilterListAdapter = new FilterListAdapter();
-        } else {
-            mFilterListAdapter.notifyDataSetChanged();
-        }
-
-        mFiltersLoaded = true;
-        notifyContacListFiltersLoaded();
-
-        if (filterChanged) {
-            notifyContactListFilterChanged();
-        }
-    }
-
-    public void onLoaderReset(Loader<List<ContactListFilter>> loader) {
-    }
-
-    private void setContactListFilter(int filterId) {
-        ContactListFilter filter;
-        if (filterId == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
-            filter = ContactListFilter.createFilterWithType(
-                    ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
-        } else if (filterId == ContactListFilter.FILTER_TYPE_CUSTOM) {
-            filter = ContactListFilter.createFilterWithType(
-                    ContactListFilter.FILTER_TYPE_CUSTOM);
-        } else if (filterId == ContactListFilter.FILTER_TYPE_STARRED) {
-            filter = ContactListFilter.createFilterWithType(
-                    ContactListFilter.FILTER_TYPE_STARRED);
-        } else {
-            filter = mFilters.get(filterId);
-            if (filter == null) {
-                filter = getDefaultFilter();
-            }
-        }
-
-        setContactListFilter(filter, true);
-    }
-
     public void setContactListFilter(ContactListFilter filter, boolean persistent) {
         if (!filter.equals(mFilter)) {
             mFilter = filter;
@@ -253,59 +82,9 @@
         }
     }
 
-    @Override
-    public void onClick(View v) {
-        if (!mFiltersLoaded || !mEnabled) {
-            return;
-        }
-
-        if (mPopupWidth == -1) {
-            TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ContactBrowser);
-            mPopupWidth = a.getDimensionPixelSize(
-                    R.styleable.ContactBrowser_contact_filter_popup_width, -1);
-            a.recycle();
-
-            if (mPopupWidth == -1) {
-                mPopupWidth = mAnchor.getWidth();
-            }
-        }
-
-        mPopup = new ListPopupWindow(mContext, null);
-        mPopup.setWidth(mPopupWidth);
-        mPopup.setAdapter(mFilterListAdapter);
-        mPopup.setAnchorView(mAnchor);
-        mPopup.setOnItemClickListener(this);
-        mPopup.setModal(true);
-        mPopup.show();
-    }
-
-    @Override
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        mPopup.dismiss();
-        if (mFilters.get((int) id).filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
-            notifyContactListFilterCustomizationRequest();
-        } else {
-            setContactListFilter((int) id);
-        }
-    }
-
     public void selectCustomFilter() {
-        mFilter = ContactListFilter.createFilterWithType(ContactListFilter.FILTER_TYPE_CUSTOM);
-        notifyContactListFilterChanged();
-    }
-
-    public int getAccountCount() {
-        return mAccountCount;
-    }
-
-    private ContactListFilter getDefaultFilter() {
-        return mFilters.size() > 0 ? mFilters.valueAt(0) : null;
-    }
-
-    private void notifyContacListFiltersLoaded() {
-        for (ContactListFilterListener listener : mListeners) {
-            listener.onContactListFiltersLoaded();
-        }
+        setContactListFilter(ContactListFilter.createFilterWithType(
+                ContactListFilter.FILTER_TYPE_CUSTOM), true);
     }
 
     private void notifyContactListFilterChanged() {
@@ -314,48 +93,4 @@
         }
     }
 
-    private void notifyContactListFilterCustomizationRequest() {
-        for (ContactListFilterListener listener : mListeners) {
-            listener.onContactListFilterCustomizationRequest();
-        }
-    }
-
-    private class FilterListAdapter extends BaseAdapter {
-        private LayoutInflater mLayoutInflater;
-
-        public FilterListAdapter() {
-            mLayoutInflater = LayoutInflater.from(mContext);
-        }
-
-        @Override
-        public int getCount() {
-            return mFilters.size();
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return mFilters.keyAt(position);
-        }
-
-        @Override
-        public Object getItem(int position) {
-            return mFilters.valueAt(position);
-        }
-
-        public View getView(int position, View convertView, ViewGroup parent) {
-            ContactListFilterView view;
-            if (convertView != null) {
-                view = (ContactListFilterView) convertView;
-            } else {
-                view = (ContactListFilterView) mLayoutInflater.inflate(
-                        R.layout.filter_spinner_item, parent, false);
-            }
-            view.setSingleAccount(mAccountCount == 1);
-            ContactListFilter filter = mFilters.valueAt(position);
-            view.setContactListFilter(filter);
-            view.setActivated(filter.equals(mFilter));
-            view.bindView(true);
-            return view;
-        }
-    }
 }
diff --git a/src/com/android/contacts/list/ContactListFilterLoader.java b/src/com/android/contacts/list/ContactListFilterLoader.java
deleted file mode 100644
index 07c11bc..0000000
--- a/src/com/android/contacts/list/ContactListFilterLoader.java
+++ /dev/null
@@ -1,174 +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.list;
-
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-
-import android.accounts.Account;
-import android.content.AsyncTaskLoader;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Groups;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A loader for the data needed for the group selector.
- */
-public class ContactListFilterLoader extends AsyncTaskLoader<List<ContactListFilter>> {
-
-    private static final class GroupQuery {
-        public static final String[] COLUMNS = {
-            Groups._ID,
-            Groups.ACCOUNT_TYPE,
-            Groups.ACCOUNT_NAME,
-            Groups.TITLE,
-            Groups.AUTO_ADD,
-            Groups.SOURCE_ID,
-            Groups.GROUP_IS_READ_ONLY,
-        };
-
-        public static final int ID = 0;
-        public static final int ACCOUNT_TYPE = 1;
-        public static final int ACCOUNT_NAME = 2;
-        public static final int TITLE = 3;
-        public static final int IS_DEFAULT_GROUP = 4;       // Using the AUTO_ADD group as default
-        public static final int SOURCE_ID = 5;
-        public static final int GROUP_IS_READ_ONLY = 6;
-
-        public static final String SELECTION =
-                Groups.DELETED + "=0" +
-                " AND " + Groups.FAVORITES + "=0" +
-                " AND " + Groups.ACCOUNT_TYPE + " NOT NULL" +
-                " AND " + Groups.ACCOUNT_NAME + " NOT NULL";
-    }
-
-    private boolean mStopped;
-    private ForceLoadContentObserver mObserver;
-    private ArrayList<ContactListFilter> mResults;
-
-    public ContactListFilterLoader(Context context) {
-        super(context);
-    }
-
-    @Override
-    public List<ContactListFilter> loadInBackground() {
-
-        ArrayList<ContactListFilter> results = new ArrayList<ContactListFilter>();
-        Context context = getContext();
-        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context);
-        ArrayList<Account> accounts = accountTypes.getAccounts(false);
-        for (Account account : accounts) {
-            AccountType accountType = accountTypes.getAccountType(account.type);
-            Drawable icon = accountType != null ? accountType.getDisplayIcon(getContext()) : null;
-            results.add(ContactListFilter.createAccountFilter(account.type, account.name, icon,
-                    account.name));
-        }
-
-        ContentResolver resolver = context.getContentResolver();
-
-        Cursor cursor = resolver.query(
-                Groups.CONTENT_URI, GroupQuery.COLUMNS, GroupQuery.SELECTION, null, null);
-        try {
-            while (cursor.moveToNext()) {
-                long groupId = cursor.getLong(GroupQuery.ID);
-                String groupSourceId = cursor.getString(GroupQuery.SOURCE_ID);
-                boolean groupReadOnly = cursor.getInt(GroupQuery.GROUP_IS_READ_ONLY) != 0;
-                String accountType = cursor.getString(GroupQuery.ACCOUNT_TYPE);
-                String accountName = cursor.getString(GroupQuery.ACCOUNT_NAME);
-                boolean defaultGroup = false;
-                if (!cursor.isNull(GroupQuery.IS_DEFAULT_GROUP)) {
-                    defaultGroup = cursor.getInt(GroupQuery.IS_DEFAULT_GROUP) != 0;
-                }
-                if (defaultGroup) {
-                    // Find the filter for this account and set the default group ID
-                    for (ContactListFilter filter : results) {
-                        if (filter.accountName.equals(accountName)
-                                && filter.accountType.equals(accountType)) {
-                            filter.groupId = groupId;
-                            filter.groupSourceId = groupSourceId;
-                            break;
-                        }
-                    }
-                } else {
-                    String title = cursor.getString(GroupQuery.TITLE);
-                    results.add(ContactListFilter.createGroupFilter(accountType, accountName,
-                            groupId, groupSourceId, groupReadOnly, title));
-                }
-            }
-        } finally {
-            cursor.close();
-        }
-
-        Collections.sort(results);
-
-        mResults = results;
-        return results;
-    }
-
-    /* Runs on the UI thread */
-    @Override
-    public void deliverResult(List<ContactListFilter> results) {
-        if (!mStopped) {
-            super.deliverResult(results);
-        }
-    }
-
-    @Override
-    protected void onStartLoading() {
-        if (mObserver == null) {
-            mObserver = new ForceLoadContentObserver();
-            getContext().getContentResolver().registerContentObserver(
-                    Contacts.CONTENT_URI, true, mObserver);
-        }
-
-        mStopped = false;
-
-        if (mResults != null) {
-            deliverResult(mResults);
-        } else {
-            forceLoad();
-        }
-    }
-
-    @Override
-    protected void onStopLoading() {
-        if (mObserver != null) {
-            getContext().getContentResolver().unregisterContentObserver(mObserver);
-            mObserver = null;
-        }
-
-        mResults = null;
-
-        // Attempt to cancel the current load task if possible.
-        cancelLoad();
-
-        // Make sure that any outstanding loads clean themselves up properly
-        mStopped = true;
-    }
-
-    @Override
-    protected void onReset() {
-        stopLoading();
-    }
-}
diff --git a/src/com/android/contacts/list/CustomContactListFilterActivity.java b/src/com/android/contacts/list/CustomContactListFilterActivity.java
index dae7233..0f6aaad 100644
--- a/src/com/android/contacts/list/CustomContactListFilterActivity.java
+++ b/src/com/android/contacts/list/CustomContactListFilterActivity.java
@@ -23,10 +23,8 @@
 import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.model.EntityDelta.ValuesDelta;
 import com.android.contacts.model.GoogleAccountType;
-import com.android.contacts.preference.ContactsPreferences;
 import com.android.contacts.util.EmptyService;
 import com.android.contacts.util.LocalizedNameResolver;
-import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.contacts.util.WeakAsyncTask;
 import com.google.android.collect.Lists;
 
@@ -46,7 +44,6 @@
 import android.content.Loader;
 import android.content.OperationApplicationException;
 import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
@@ -62,7 +59,6 @@
 import android.view.MenuItem.OnMenuItemClickListener;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.AdapterView;
 import android.widget.BaseExpandableListAdapter;
 import android.widget.CheckBox;
 import android.widget.ExpandableListAdapter;
@@ -80,8 +76,7 @@
  * select which ones they want to be visible.
  */
 public class CustomContactListFilterActivity extends ContactsActivity
-        implements AdapterView.OnItemClickListener, View.OnClickListener,
-        ExpandableListView.OnChildClickListener,
+        implements View.OnClickListener, ExpandableListView.OnChildClickListener,
         LoaderCallbacks<CustomContactListFilterActivity.AccountSet>
 {
     private static final String TAG = "CustomContactListFilterActivity";
@@ -93,11 +88,6 @@
 
     private SharedPreferences mPrefs;
 
-    private CheckBox mDisplayPhones;
-
-    private View mHeaderPhones;
-    private View mHeaderSeparator;
-
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -111,50 +101,14 @@
 
         final LayoutInflater inflater = getLayoutInflater();
 
-        createWithPhonesOnlyPreferenceView(inflater);
-        createDisplayGroupHeader(inflater);
-
-        if (mHeaderPhones != null) {
-            mList.addHeaderView(mHeaderPhones, null, true);
-            mList.addHeaderView(mHeaderSeparator, null, false);
-        }
-
         findViewById(R.id.btn_done).setOnClickListener(this);
         findViewById(R.id.btn_discard).setOnClickListener(this);
 
-        // Catch clicks on the header views
-        mList.setOnItemClickListener(this);
         mList.setOnCreateContextMenuListener(this);
 
         mList.setAdapter(mAdapter);
     }
 
-    private void createWithPhonesOnlyPreferenceView(LayoutInflater inflater) {
-        boolean optionSelected = mPrefs.getBoolean(ContactsPreferences.PREF_DISPLAY_ONLY_PHONES,
-                ContactsPreferences.PREF_DISPLAY_ONLY_PHONES_DEFAULT);
-
-        if (!optionSelected && !PhoneCapabilityTester.isPhone(this)) {
-            return;
-        }
-
-        // Add the "Only contacts with phones" header modifier.
-        mHeaderPhones = inflater.inflate(R.layout.contact_list_filter_phones_only, mList, false);
-        mHeaderPhones.setId(R.id.header_phones);
-        mDisplayPhones = (CheckBox) mHeaderPhones.findViewById(android.R.id.checkbox);
-        mDisplayPhones.setChecked(optionSelected);
-        final TextView text1 = (TextView) mHeaderPhones.findViewById(android.R.id.text1);
-        text1.setText(R.string.showFilterPhones);
-        final TextView text2 = (TextView) mHeaderPhones.findViewById(android.R.id.text2);
-        text2.setText(R.string.showFilterPhonesDescrip);
-    }
-
-    private void createDisplayGroupHeader(LayoutInflater inflater) {
-        // Add the separator before showing the detailed group list.
-        mHeaderSeparator = inflater.inflate(R.layout.list_separator, mList, false);
-        final TextView text1 = (TextView) mHeaderSeparator;
-        text1.setText(R.string.headerContactGroups);
-    }
-
     public static class CustomFilterConfigurationLoader extends AsyncTaskLoader<AccountSet> {
 
         private AccountSet mAccountSet;
@@ -696,18 +650,6 @@
         }
     }
 
-    /**
-     * Handle any clicks on header views added to our {@link #mAdapter}, which
-     * are usually the global modifier checkboxes.
-     */
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        Log.d(TAG, "OnItemClick, position=" + position + ", id=" + id);
-        if (view == mHeaderPhones) {
-            mDisplayPhones.toggle();
-            return;
-        }
-    }
-
     /** {@inheritDoc} */
     public void onClick(View view) {
         switch (view.getId()) {
@@ -723,21 +665,6 @@
     }
 
     /**
-     * Assign a specific value to {@link ContactsPreferences#PREF_DISPLAY_ONLY_PHONES}, refreshing
-     * the visible list as needed.
-     */
-    protected void setDisplayOnlyPhones(boolean displayOnlyPhones) {
-        mDisplayPhones.setChecked(displayOnlyPhones);
-
-        Editor editor = mPrefs.edit();
-        editor.putBoolean(ContactsPreferences.PREF_DISPLAY_ONLY_PHONES, displayOnlyPhones);
-        editor.apply();
-
-        mAdapter.setChildDescripWithPhones(displayOnlyPhones);
-        mAdapter.notifyDataSetChanged();
-    }
-
-    /**
      * Handle any clicks on {@link ExpandableListAdapter} children, which
      * usually mean toggling its visible state.
      */
@@ -880,10 +807,6 @@
             return;
         }
 
-        if (mDisplayPhones != null) {
-            setDisplayOnlyPhones(mDisplayPhones.isChecked());
-        }
-
         setResult(RESULT_OK);
 
         final ArrayList<ContentProviderOperation> diff = mAdapter.mAccounts.buildDiff();
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index f95c4af..88531e1 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -34,6 +34,7 @@
 
     private View mCounterHeaderView;
     private View mSearchHeaderView;
+    private TextView mAccountFilterHeaderView;
 
     public DefaultContactBrowseListFragment() {
         setPhotoLoaderEnabled(true);
@@ -63,6 +64,8 @@
     protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
         super.onCreateView(inflater, container);
 
+        mAccountFilterHeaderView = (TextView) getView().findViewById(R.id.account_filter_header);
+
         // Putting the header view inside a container will allow us to make
         // it invisible later. See checkHeaderViewVisibility()
         FrameLayout headerContainer = new FrameLayout(inflater.getContext());
@@ -92,6 +95,19 @@
     }
 
     @Override
+    public void setFilter(ContactListFilter filter) {
+        super.setFilter(filter);
+        if (filter != null && filter.filterType != ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS &&
+                filter.filterType != ContactListFilter.FILTER_TYPE_CUSTOM) {
+            mAccountFilterHeaderView.setText(getContext().getString(
+                    R.string.listAllContactsInAccount, filter.accountName));
+            mAccountFilterHeaderView.setVisibility(View.VISIBLE);
+        } else {
+            mAccountFilterHeaderView.setVisibility(View.GONE);
+        }
+    }
+
+    @Override
     protected void showCount(int partitionIndex, Cursor data) {
         if (!isSearchMode() && data != null) {
             int count = data.getCount();
diff --git a/tests/src/com/android/contacts/activities/CallLogActivityTests.java b/tests/src/com/android/contacts/activities/CallLogActivityTests.java
index adc1838..6421a9e 100644
--- a/tests/src/com/android/contacts/activities/CallLogActivityTests.java
+++ b/tests/src/com/android/contacts/activities/CallLogActivityTests.java
@@ -113,6 +113,7 @@
         // Do not process requests for details during tests. This would start a background thread,
         // which makes the tests flaky.
         mAdapter.disableRequestProcessingForTest();
+        mAdapter.stopRequestProcessing();
         mParentView = new FrameLayout(mActivity);
         mCursor = new MatrixCursor(CALL_LOG_PROJECTION);
         buildIconMap();