Merge "Fix regression; once again we can apply Gallery photo to contact."
diff --git a/res/menu-sw580dp-w720dp/people_options.xml b/res/menu-sw580dp-w720dp/people_options.xml
index 5f939cc..6974d80 100644
--- a/res/menu-sw580dp-w720dp/people_options.xml
+++ b/res/menu-sw580dp-w720dp/people_options.xml
@@ -43,6 +43,10 @@
         android:title="@string/menu_import_export" />
 
     <item
+        android:id="@+id/menu_clear_frequents"
+        android:title="@string/menu_clear_frequents" />
+
+    <item
         android:id="@+id/menu_accounts"
         android:orderInCategory="3"
         android:title="@string/menu_accounts" />
diff --git a/res/menu-sw580dp/people_options.xml b/res/menu-sw580dp/people_options.xml
index c8c114a..07d9c94 100644
--- a/res/menu-sw580dp/people_options.xml
+++ b/res/menu-sw580dp/people_options.xml
@@ -46,6 +46,10 @@
         android:title="@string/menu_import_export" />
 
     <item
+        android:id="@+id/menu_clear_frequents"
+        android:title="@string/menu_clear_frequents" />
+
+    <item
         android:id="@+id/menu_accounts"
         android:orderInCategory="3"
         android:title="@string/menu_accounts" />
diff --git a/res/menu/people_options.xml b/res/menu/people_options.xml
index 0c82f99..4003038 100644
--- a/res/menu/people_options.xml
+++ b/res/menu/people_options.xml
@@ -41,6 +41,10 @@
         android:title="@string/menu_import_export" />
 
     <item
+        android:id="@+id/menu_clear_frequents"
+        android:title="@string/menu_clear_frequents" />
+
+    <item
         android:id="@+id/menu_accounts"
         android:title="@string/menu_accounts" />
 
diff --git a/res/menu/phone_favorite_options.xml b/res/menu/phone_favorite_options.xml
index ac67d6e..e37759c 100644
--- a/res/menu/phone_favorite_options.xml
+++ b/res/menu/phone_favorite_options.xml
@@ -19,6 +19,10 @@
         android:title="@string/menu_import_export" />
 
     <item
+        android:id="@+id/menu_clear_frequents"
+        android:title="@string/menu_clear_frequents" />
+
+    <item
         android:id="@+id/menu_accounts"
         android:title="@string/menu_accounts" />
 </menu>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b030f43..c5d0703 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -433,6 +433,15 @@
     <!-- Title of the "Clearing call log" progress-dialog [CHAR LIMIT=35] -->
     <string name="clearCallLogProgress_title">Clearing call log\u2026</string>
 
+    <!-- Title of the confirmation dialog for clearing frequents. [CHAR LIMIT=37] -->
+    <string name="clearFrequentsConfirmation_title">Clear frequently contacted?</string>
+
+    <!-- Confirmation dialog for clearing frequents. [CHAR LIMIT=NONE] -->
+    <string name="clearFrequentsConfirmation">You\'ll clear the frequently contacted list in the People and Phone apps, and force email apps to learn your addressing preferences from scratch.</string>
+
+    <!-- Title of the "Clearing frequently contacted" progress-dialog [CHAR LIMIT=35] -->
+    <string name="clearFrequentsProgress_title">Clearing frequently contacted\u2026</string>
+
     <!-- The title of a dialog that displays the IMEI of the phone -->
     <string name="imei">IMEI</string>
 
@@ -1002,6 +1011,9 @@
     <!-- The menu item to open the list of accounts -->
     <string name="menu_accounts">Accounts</string>
 
+    <!--  The menu item to clear frequents [CHAR LIMIT=30] -->
+    <string name="menu_clear_frequents">Clear frequents</string>
+
     <!-- The menu item to filter the list of contacts displayed -->
     <string name="menu_contacts_filter">Contacts to display</string>
 
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index ae8fe09..6f13924 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -569,7 +569,7 @@
             Log.d(TAG, "onStart(). current position: " + mPageChangeListener.getCurrentPosition()
                     + ". Reset all menu visibility state.");
         }
-        updateFakeMenuButtonsVisibility(currentPosition == TAB_INDEX_DIALER);
+        updateFakeMenuButtonsVisibility(currentPosition == TAB_INDEX_DIALER && !mInSearchUi);
         for (int i = 0; i < TAB_INDEX_COUNT; i++) {
             sendFragmentVisibilityChange(i, i == currentPosition);
         }
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 5915a7a..95e7d3b 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -27,6 +27,7 @@
 import com.android.contacts.detail.ContactDetailUpdatesFragment;
 import com.android.contacts.detail.ContactLoaderFragment;
 import com.android.contacts.detail.ContactLoaderFragment.ContactLoaderFragmentListener;
+import com.android.contacts.dialog.ClearFrequentsDialog;
 import com.android.contacts.group.GroupBrowseListFragment;
 import com.android.contacts.group.GroupBrowseListFragment.OnGroupBrowserActionListener;
 import com.android.contacts.group.GroupDetailFragment;
@@ -1390,6 +1391,7 @@
             return false;
         }
 
+        // Get references to individual menu items in the menu
         final MenuItem addContactMenu = menu.findItem(R.id.menu_add_contact);
         final MenuItem contactsFilterMenu = menu.findItem(R.id.menu_contacts_filter);
 
@@ -1398,22 +1400,27 @@
             addGroupMenu = menu.findItem(R.id.menu_custom_add_group);
         }
 
+        final MenuItem clearFrequentsMenu = menu.findItem(R.id.menu_clear_frequents);
+
         final boolean isSearchMode = mActionBarAdapter.isSearchMode();
         if (isSearchMode) {
             addContactMenu.setVisible(false);
             addGroupMenu.setVisible(false);
             contactsFilterMenu.setVisible(false);
+            clearFrequentsMenu.setVisible(false);
         } else {
             switch (mActionBarAdapter.getCurrentTab()) {
                 case TabState.FAVORITES:
                     addContactMenu.setVisible(false);
                     addGroupMenu.setVisible(false);
                     contactsFilterMenu.setVisible(false);
+                    clearFrequentsMenu.setVisible(hasFrequents());
                     break;
                 case TabState.ALL:
                     addContactMenu.setVisible(true);
                     addGroupMenu.setVisible(false);
                     contactsFilterMenu.setVisible(true);
+                    clearFrequentsMenu.setVisible(false);
                     break;
                 case TabState.GROUPS:
                     // Do not display the "new group" button if no accounts are available
@@ -1424,6 +1431,7 @@
                     }
                     addContactMenu.setVisible(false);
                     contactsFilterMenu.setVisible(false);
+                    clearFrequentsMenu.setVisible(false);
                     break;
             }
         }
@@ -1437,6 +1445,18 @@
         return true;
     }
 
+    /**
+     * Returns whether there are any frequently contacted people being displayed
+     * @return
+     */
+    private boolean hasFrequents() {
+        if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
+            return mFrequentFragment.hasFrequents();
+        } else {
+            return mFavoritesFragment.hasFrequents();
+        }
+    }
+
     private void makeMenuItemVisible(Menu menu, int itemId, boolean visible) {
         MenuItem item =menu.findItem(itemId);
         if (item != null) {
@@ -1504,6 +1524,10 @@
                 ImportExportDialogFragment.show(getFragmentManager(), areContactsAvailable());
                 return true;
             }
+            case R.id.menu_clear_frequents: {
+                ClearFrequentsDialog.show(getFragmentManager());
+                return true;
+            }
             case R.id.menu_accounts: {
                 final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
                 intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {
diff --git a/src/com/android/contacts/dialog/ClearFrequentsDialog.java b/src/com/android/contacts/dialog/ClearFrequentsDialog.java
new file mode 100644
index 0000000..ecb1a27
--- /dev/null
+++ b/src/com/android/contacts/dialog/ClearFrequentsDialog.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 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.dialog;
+
+import com.android.contacts.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.ContentResolver;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+
+/**
+ * Dialog that clears the frequently contacted list after confirming with the user.
+ */
+public class ClearFrequentsDialog extends DialogFragment {
+    /** Preferred way to show this dialog */
+    public static void show(FragmentManager fragmentManager) {
+        ClearFrequentsDialog dialog = new ClearFrequentsDialog();
+        dialog.show(fragmentManager, "clearFrequents");
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final ContentResolver resolver = getActivity().getContentResolver();
+        final OnClickListener okListener = new OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
+                    @Override
+                    protected Void doInBackground(Void... params) {
+                        resolver.delete(ContactsContract.DataUsageFeedback.DELETE_USAGE_URI,
+                                null, null);
+                        return null;
+                    }
+                };
+                task.execute();
+            }
+        };
+        return new AlertDialog.Builder(getActivity())
+            .setTitle(R.string.clearFrequentsConfirmation_title)
+            .setMessage(R.string.clearFrequentsConfirmation)
+            .setNegativeButton(android.R.string.cancel, null)
+            .setPositiveButton(android.R.string.ok, okListener)
+            .setCancelable(true)
+            .create();
+    }
+}
diff --git a/src/com/android/contacts/list/ContactTileAdapter.java b/src/com/android/contacts/list/ContactTileAdapter.java
index 9ea0468..ddf88b0 100644
--- a/src/com/android/contacts/list/ContactTileAdapter.java
+++ b/src/com/android/contacts/list/ContactTileAdapter.java
@@ -53,6 +53,7 @@
     private Resources mResources;
     private Cursor mContactCursor = null;
     private ContactPhotoManager mPhotoManager;
+    private int mNumFrequents;
 
     /**
      * Index of the first NON starred contact in the {@link Cursor}
@@ -119,6 +120,7 @@
         mResources = context.getResources();
         mColumnCount = (displayType == DisplayType.FREQUENT_ONLY ? 1 : numCols);
         mDisplayType = displayType;
+        mNumFrequents = 0;
 
         // Converting padding in dips to padding in pixels
         mPaddingInPixels = mContext.getResources()
@@ -184,6 +186,25 @@
     public void setContactCursor(Cursor cursor) {
         mContactCursor = cursor;
         mDividerPosition = getDividerPosition(cursor);
+
+        // count the number of frequents
+        switch (mDisplayType) {
+            case STARRED_ONLY:
+            case GROUP_MEMBERS:
+                mNumFrequents = 0;
+                break;
+            case STREQUENT:
+            case STREQUENT_PHONE_ONLY:
+                mNumFrequents = mContactCursor.getCount() - mDividerPosition;
+                break;
+            case FREQUENT_ONLY:
+                mNumFrequents = mContactCursor.getCount();
+                break;
+            default:
+                throw new IllegalArgumentException("Unrecognized DisplayType " + mDisplayType);
+        }
+
+        // cause a refresh of any views that rely on this data
         notifyDataSetChanged();
     }
 
@@ -274,6 +295,13 @@
         return contact;
     }
 
+    /**
+     * Returns the number of frequents that will be displayed in the list.
+     */
+    public int getNumFrequents() {
+        return mNumFrequents;
+    }
+
     @Override
     public int getCount() {
         if (mContactCursor == null || mContactCursor.isClosed()) {
@@ -289,11 +317,9 @@
                 // Takes numbers of rows the Starred Contacts Occupy
                 int starredRowCount = getRowCount(mDividerPosition);
 
-                // Calculates the number of frequent contacts
-                int frequentRowCount = mContactCursor.getCount() - mDividerPosition ;
-
-                // If there are any frequent contacts add one for the divider
-                frequentRowCount += frequentRowCount == 0 ? 0 : 1;
+                // Compute the frequent row count which is 1 plus the number of frequents
+                // (to account for the divider) or 0 if there are no frequents.
+                int frequentRowCount = mNumFrequents == 0 ? 0 : mNumFrequents + 1;
 
                 // Return the number of starred plus frequent rows
                 return starredRowCount + frequentRowCount;
diff --git a/src/com/android/contacts/list/ContactTileListFragment.java b/src/com/android/contacts/list/ContactTileListFragment.java
index 92ff41d..9f34c54 100644
--- a/src/com/android/contacts/list/ContactTileListFragment.java
+++ b/src/com/android/contacts/list/ContactTileListFragment.java
@@ -61,6 +61,8 @@
     private TextView mEmptyView;
     private ListView mListView;
 
+    private boolean mOptionsMenuHasFrequents;
+
     @Override
     public void onAttach(Activity activity) {
         super.onAttach(activity);
@@ -98,6 +100,24 @@
         getLoaderManager().initLoader(LOADER_CONTACTS, null, mContactTileLoaderListener);
     }
 
+    /**
+     * Returns whether there are any frequents with the side effect of setting the
+     * internal flag mOptionsMenuHasFrequents to the value.  This should be called externally
+     * by the activity that is about to prepare the options menu with the clear frequents
+     * menu item.
+     */
+    public boolean hasFrequents() {
+        mOptionsMenuHasFrequents = internalHasFrequents();
+        return mOptionsMenuHasFrequents;
+    }
+
+    /**
+     * Returns whether there are any frequents.
+     */
+    private boolean internalHasFrequents() {
+        return mAdapter.getNumFrequents() > 0;
+    }
+
     public void setColumnCount(int columnCount) {
         mAdapter.setColumnCount(columnCount);
     }
@@ -136,12 +156,25 @@
             mAdapter.setContactCursor(data);
             mEmptyView.setText(getEmptyStateText());
             mListView.setEmptyView(mEmptyView);
+
+            // invalidate the menu options if needed
+            invalidateOptionsMenuIfNeeded();
         }
 
         @Override
         public void onLoaderReset(Loader<Cursor> loader) {}
     };
 
+    private boolean isOptionsMenuChanged() {
+        return mOptionsMenuHasFrequents != internalHasFrequents();
+    }
+
+    private void invalidateOptionsMenuIfNeeded() {
+        if (isOptionsMenuChanged()) {
+            getActivity().invalidateOptionsMenu();
+        }
+    }
+
     private String getEmptyStateText() {
         String emptyText;
         switch (mDisplayType) {
diff --git a/src/com/android/contacts/list/PhoneFavoriteFragment.java b/src/com/android/contacts/list/PhoneFavoriteFragment.java
index 011a811..6ed846d 100644
--- a/src/com/android/contacts/list/PhoneFavoriteFragment.java
+++ b/src/com/android/contacts/list/PhoneFavoriteFragment.java
@@ -18,6 +18,7 @@
 import com.android.contacts.ContactPhotoManager;
 import com.android.contacts.ContactTileLoaderFactory;
 import com.android.contacts.R;
+import com.android.contacts.dialog.ClearFrequentsDialog;
 import com.android.contacts.interactions.ImportExportDialogFragment;
 import com.android.contacts.preference.ContactsPreferences;
 import com.android.contacts.util.AccountFilterUtil;
@@ -106,6 +107,9 @@
             // Show the filter header with "loading" state.
             updateFilterHeaderView();
             mAccountFilterHeader.setVisibility(View.VISIBLE);
+
+            // invalidate the options menu if needed
+            invalidateOptionsMenuIfNeeded();
         }
 
         @Override
@@ -236,6 +240,8 @@
             new ContactsPreferenceChangeListener();
     private final ScrollListener mScrollListener = new ScrollListener();
 
+    private boolean mOptionsMenuHasFrequents;
+
     @Override
     public void onAttach(Activity activity) {
         if (DEBUG) Log.d(TAG, "onAttach()");
@@ -337,6 +343,16 @@
         return listLayout;
     }
 
+    private boolean isOptionsMenuChanged() {
+        return mOptionsMenuHasFrequents != hasFrequents();
+    }
+
+    private void invalidateOptionsMenuIfNeeded() {
+        if (isOptionsMenuChanged()) {
+            getActivity().invalidateOptionsMenu();
+        }
+    }
+
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
@@ -344,6 +360,17 @@
     }
 
     @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        final MenuItem clearFrequents = menu.findItem(R.id.menu_clear_frequents);
+        mOptionsMenuHasFrequents = hasFrequents();
+        clearFrequents.setVisible(mOptionsMenuHasFrequents);
+    }
+
+    private boolean hasFrequents() {
+        return mContactTileAdapter.getNumFrequents() > 0;
+    }
+
+    @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.menu_import_export:
@@ -361,6 +388,9 @@
                 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                 startActivity(intent);
                 return true;
+            case R.id.menu_clear_frequents:
+                ClearFrequentsDialog.show(getFragmentManager());
+                return true;
         }
         return false;
     }