Merge "Replace list item selection assets"
diff --git a/res/layout-w470dp/contact_detail_fragment.xml b/res/layout-w470dp/contact_detail_fragment.xml
index 56c9f20..d63236d 100644
--- a/res/layout-w470dp/contact_detail_fragment.xml
+++ b/res/layout-w470dp/contact_detail_fragment.xml
@@ -77,7 +77,6 @@
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
         android:background="@android:color/black"
-        android:alpha=".50"
         android:visibility="gone"/>
 
     <View
diff --git a/res/layout-w470dp/contact_detail_updates_fragment.xml b/res/layout-w470dp/contact_detail_updates_fragment.xml
index 92ddd8c..dd7cfbd 100644
--- a/res/layout-w470dp/contact_detail_updates_fragment.xml
+++ b/res/layout-w470dp/contact_detail_updates_fragment.xml
@@ -14,21 +14,45 @@
      limitations under the License.
 -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
     android:id="@+id/contact_detail_updates_fragment"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent">
 
-    <include
-        android:id="@+id/title"
-        layout="@layout/contact_detail_kind_title_entry_view" />
-
-    <ListView android:id="@android:id/list"
+    <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:background="@color/background_social_updates"
-        android:divider="@null"/>
+        android:layout_height="match_parent"
+        android:orientation="vertical">
 
-</LinearLayout>
+        <include
+            android:id="@+id/title"
+            layout="@layout/contact_detail_kind_title_entry_view" />
+
+        <ListView android:id="@android:id/list"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@color/background_social_updates"
+            android:divider="@null"/>
+
+    </LinearLayout>
+
+    <View
+        android:id="@+id/alpha_overlay"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:background="@android:color/black"
+        android:visibility="gone"/>
+
+    <View
+        android:id="@+id/touch_intercept_overlay"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:background="?android:attr/selectableItemBackground"
+        android:visibility="gone"/>
+
+</FrameLayout>
diff --git a/res/layout/call_log_list_item.xml b/res/layout/call_log_list_item.xml
index f28bda1..5447f65 100644
--- a/res/layout/call_log_list_item.xml
+++ b/res/layout/call_log_list_item.xml
@@ -74,24 +74,12 @@
                 android:background="@drawable/ic_divider_dashed_holo_dark"
             />
             <ImageView
-                android:id="@+id/call_icon"
+                android:id="@+id/secondary_action_icon"
                 android:layout_width="@dimen/call_log_call_action_width"
                 android:layout_height="@dimen/call_log_call_action_height"
                 android:layout_gravity="center_vertical"
                 android:scaleType="center"
-                android:src="@drawable/ic_ab_dialer_holo_dark"
                 android:background="@drawable/list_selector"
-                android:contentDescription="@string/description_call_log_call_button"
-            />
-            <ImageView
-                android:id="@+id/play_icon"
-                android:layout_width="@dimen/call_log_call_action_width"
-                android:layout_height="@dimen/call_log_call_action_height"
-                android:layout_gravity="center_vertical"
-                android:scaleType="center"
-                android:src="@drawable/ic_play_holo_dark"
-                android:background="@drawable/list_selector"
-                android:contentDescription="@string/description_call_log_play_button"
             />
         </LinearLayout>
         <LinearLayout
diff --git a/res/layout/group_browse_list_account_header.xml b/res/layout/group_browse_list_account_header.xml
index 7c07497..f739ea2 100644
--- a/res/layout/group_browse_list_account_header.xml
+++ b/res/layout/group_browse_list_account_header.xml
@@ -18,7 +18,10 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:padding="@dimen/group_list_header_padding"
+    android:background="@drawable/list_background_holo"
+    android:paddingLeft="@dimen/group_list_header_padding"
+    android:paddingRight="@dimen/group_list_header_padding"
+    android:paddingTop="@dimen/group_list_header_padding"
     android:orientation="vertical">
 
     <LinearLayout
diff --git a/res/layout/group_browse_list_item.xml b/res/layout/group_browse_list_item.xml
index 6f5fcef..326b413 100644
--- a/res/layout/group_browse_list_item.xml
+++ b/res/layout/group_browse_list_item.xml
@@ -19,16 +19,12 @@
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="@dimen/detail_min_line_item_height"
-    android:paddingRight="20dip"
-    android:paddingBottom="10dip"
-    style="@style/GroupBrowseListItem">
+    android:minHeight="@dimen/detail_min_line_item_height">
 
     <ImageView
         android:id="@+id/divider"
         android:layout_width="match_parent"
         android:layout_height="1dip"
-        android:layout_marginBottom="10dip"
         android:paddingLeft="10dip"
         android:paddingRight="10dip"
         android:scaleType="fitXY"
@@ -37,11 +33,17 @@
     <include
         android:id="@+id/group_list_header"
         layout="@layout/group_browse_list_account_header"
+        android:paddingRight="20dip"
+        android:paddingBottom="10dip"
         android:visibility="gone" />
 
     <RelativeLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="wrap_content"
+        android:paddingTop="10dip"
+        android:paddingRight="20dip"
+        android:paddingBottom="10dip"
+        style="@style/GroupBrowseListItem">
 
         <LinearLayout
             android:layout_width="match_parent"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8030194..2e8983f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -129,13 +129,13 @@
     <string name="menu_splitAggregate">Separate</string>
 
     <!-- Menu item that edits the currently selected group [CHAR LIMIT=30] -->
-    <string name="menu_editGroup">Edit group</string>
+    <string name="menu_editGroup">Edit</string>
 
     <!-- Menu item that renames the currently selected group [CHAR LIMIT=30] -->
     <string name="menu_renameGroup">Rename group</string>
 
     <!-- Menu item that deletes the currently selected group [CHAR LIMIT=30] -->
-    <string name="menu_deleteGroup">Delete group</string>
+    <string name="menu_deleteGroup">Delete</string>
 
     <!-- Menu item (in the action bar) that creates a new contacts [CHAR LIMIT=12] -->
     <string name="menu_new_contact_action_bar">New</string>
@@ -182,7 +182,7 @@
     <string name="menu_set_ring_tone">Set ringtone</string>
 
     <!-- Menu item that opens the Options activity for a given contact [CHAR LIMIT=30] -->
-    <string name="menu_redirect_calls_to_vm">Redirect calls to voicemail</string>
+    <string name="menu_redirect_calls_to_vm">All calls to voicemail</string>
 
     <!-- Warning dialog contents after users selects to delete a ReadOnly contact. -->
     <string name="readOnlyContactWarning">You cannot delete contacts from read-only accounts, but you can hide them in your contacts lists.</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a137361..763a600 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -76,7 +76,6 @@
 
     <style name="ContactDetailActivityTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
         <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
-        <item name="android:windowContentOverlay">@null</item>
         <item name="android:textColorPrimary">@color/primary_text_color</item>
         <item name="android:textColorSecondary">@color/secondary_text_color</item>
     </style>
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index 43e6fc7..80219d9 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -116,6 +116,7 @@
         CallLog.Calls.NUMBER,
         CallLog.Calls.TYPE,
         CallLog.Calls.COUNTRY_ISO,
+        CallLog.Calls.GEOCODED_LOCATION,
     };
 
     static final int DATE_COLUMN_INDEX = 0;
@@ -123,6 +124,7 @@
     static final int NUMBER_COLUMN_INDEX = 2;
     static final int CALL_TYPE_COLUMN_INDEX = 3;
     static final int COUNTRY_ISO_COLUMN_INDEX = 4;
+    static final int GEOCODED_LOCATION_COLUMN_INDEX = 5;
 
     static final String[] PHONES_PROJECTION = new String[] {
         PhoneLookup._ID,
@@ -403,6 +405,8 @@
             long duration = callCursor.getLong(DURATION_COLUMN_INDEX);
             int callType = callCursor.getInt(CALL_TYPE_COLUMN_INDEX);
             String countryIso = callCursor.getString(COUNTRY_ISO_COLUMN_INDEX);
+            final String geocode = callCursor.getString(GEOCODED_LOCATION_COLUMN_INDEX);
+
             if (TextUtils.isEmpty(countryIso)) {
                 countryIso = mDefaultCountryIso;
             }
@@ -448,7 +452,7 @@
                     numberText = candidateNumberText;
                 }
             }
-            return new PhoneCallDetails(number, numberText, countryIso,
+            return new PhoneCallDetails(number, numberText, countryIso, geocode,
                     new int[]{ callType }, date, duration,
                     nameText, numberType, numberLabel, personId, photoUri);
         } finally {
diff --git a/src/com/android/contacts/PhoneCallDetails.java b/src/com/android/contacts/PhoneCallDetails.java
index 347a303..5718091 100644
--- a/src/com/android/contacts/PhoneCallDetails.java
+++ b/src/com/android/contacts/PhoneCallDetails.java
@@ -30,6 +30,8 @@
     public final CharSequence formattedNumber;
     /** The country corresponding with the phone number. */
     public final String countryIso;
+    /** The geocoded location for the phone number. */
+    public final String geocode;
     /**
      * The type of calls, as defined in the call log table, e.g., {@link Calls#INCOMING_TYPE}.
      * <p>
@@ -56,18 +58,20 @@
 
     /** Create the details for a call with a number not associated with a contact. */
     public PhoneCallDetails(CharSequence number, CharSequence formattedNumber,
-            String countryIso, int[] callTypes, long date, long duration) {
-        this(number, formattedNumber, countryIso, callTypes, date, duration, "", 0, "", -1L, null);
+            String countryIso, String geocode, int[] callTypes, long date, long duration) {
+        this(number, formattedNumber, countryIso, geocode, callTypes, date, duration, "", 0, "",
+                -1L, null);
     }
 
     /** Create the details for a call with a number associated with a contact. */
     public PhoneCallDetails(CharSequence number, CharSequence formattedNumber,
-            String countryIso, int[] callTypes, long date, long duration,
+            String countryIso, String geocode, int[] callTypes, long date, long duration,
             CharSequence name, int numberType, CharSequence numberLabel, long personId,
             Uri photoUri) {
         this.number = number;
         this.formattedNumber = formattedNumber;
         this.countryIso = countryIso;
+        this.geocode = geocode;
         this.callTypes = callTypes;
         this.date = date;
         this.duration = duration;
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
index 3101aee..e970fcc 100644
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ b/src/com/android/contacts/PhoneCallDetailsHelper.java
@@ -107,12 +107,10 @@
             mPhoneNumberHelper.getDisplayNumber(details.number, details.formattedNumber);
         if (TextUtils.isEmpty(details.name)) {
             nameText = displayNumber;
-            String geocode = mPhoneNumberHelper.getGeocodeForNumber(
-                    details.number.toString(), details.countryIso);
-            if (TextUtils.isEmpty(geocode)) {
+            if (TextUtils.isEmpty(details.geocode)) {
                 numberText = mResources.getString(R.string.call_log_empty_gecode);
             } else {
-                numberText = geocode;
+                numberText = details.geocode;
             }
         } else {
             nameText = details.name;
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index 3cd07ca..c863b23 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -152,7 +152,6 @@
         }
 
         mDetailFragment.setListener(mFragmentListener);
-        TabCarouselScrollManager.bind(mTabCarousel, mDetailFragment, mUpdatesFragment);
         mDetailFragment.setData(mLookupUri, mContactData);
         mUpdatesFragment.setData(mLookupUri, mContactData);
 
@@ -348,6 +347,7 @@
             mTabCarousel = (ContactDetailTabCarousel) findViewById(R.id.tab_carousel);
             if (mTabCarousel != null) {
                 mTabCarousel.setListener(mTabCarouselListener);
+                TabCarouselScrollManager.bind(mTabCarousel, mDetailFragment, mUpdatesFragment);
             }
 
             mViewPager = (ViewPager) findViewById(R.id.pager);
diff --git a/src/com/android/contacts/activities/GroupEditorActivity.java b/src/com/android/contacts/activities/GroupEditorActivity.java
index e1c878d..b397c19 100644
--- a/src/com/android/contacts/activities/GroupEditorActivity.java
+++ b/src/com/android/contacts/activities/GroupEditorActivity.java
@@ -71,7 +71,7 @@
             saveMenuItem.setOnClickListener(new OnClickListener() {
                 @Override
                 public void onClick(View v) {
-                    mFragment.doSaveAction();
+                    mFragment.onDoneClicked();
                 }
             });
             // Show the custom action bar but hide the home icon and title
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 58dcc8b..328faf2 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -89,6 +89,7 @@
                 Calls.TYPE,
                 Calls.COUNTRY_ISO,
                 Calls.VOICEMAIL_URI,
+                Calls.GEOCODED_LOCATION,
         };
 
         public static final int ID = 0;
@@ -98,6 +99,7 @@
         public static final int CALL_TYPE = 4;
         public static final int COUNTRY_ISO = 5;
         public static final int VOICEMAIL_URI = 6;
+        public static final int GEOCODED_LOCATION = 7;
 
         /**
          * The name of the synthetic "section" column.
@@ -107,7 +109,7 @@
          */
         public static final String SECTION_NAME = "section";
         /** The index of the "section" column in the projection. */
-        public static final int SECTION = 7;
+        public static final int SECTION = 8;
         /** The value of the "section" column for the header of the new section. */
         public static final int SECTION_NEW_HEADER = 0;
         /** The value of the "section" column for the items of the new section. */
@@ -327,7 +329,8 @@
             PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
                     resources, callTypeHelper, mPhoneNumberHelper);
             mCallLogViewsHelper =
-                    new CallLogListItemHelper(phoneCallDetailsHelper, mPhoneNumberHelper);
+                    new CallLogListItemHelper(
+                            phoneCallDetailsHelper, mPhoneNumberHelper, resources);
             mCallLogGroupBuilder = new CallLogGroupBuilder(this);
         }
 
@@ -660,8 +663,7 @@
         private void findAndCacheViews(View view) {
             // Get the views to bind to.
             CallLogListItemViews views = CallLogListItemViews.fromView(view);
-            views.callView.setOnClickListener(mCallPlayOnClickListener);
-            views.playView.setOnClickListener(mCallPlayOnClickListener);
+            views.secondaryActionView.setOnClickListener(mCallPlayOnClickListener);
             view.setTag(views);
         }
 
@@ -703,17 +705,15 @@
             if (callType == Calls.VOICEMAIL_TYPE) {
                 String voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI);
                 final long rowId = c.getLong(CallLogQuery.ID);
-                views.playView.setTag(
+                views.secondaryActionView.setTag(
                         IntentProvider.getPlayVoicemailIntentProvider(rowId, voicemailUri));
-                views.callView.setTag(null);
             } else if (!TextUtils.isEmpty(number)) {
                 // Store away the number so we can call it directly if you click on the call icon.
-                views.callView.setTag(IntentProvider.getReturnCallIntentProvider(number));
-                views.playView.setTag(null);
+                views.secondaryActionView.setTag(
+                        IntentProvider.getReturnCallIntentProvider(number));
             } else {
                 // No action enabled.
-                views.callView.setTag(null);
-                views.playView.setTag(null);
+                views.secondaryActionView.setTag(null);
             }
 
             // Lookup contacts with this number
@@ -756,12 +756,13 @@
             final Uri thumbnailUri = info.thumbnailUri;
             final String lookupKey = info.lookupKey;
             final int[] callTypes = getCallTypes(c, count);
+            final String geocode = c.getString(CallLogQuery.GEOCODED_LOCATION);
             final PhoneCallDetails details;
             if (TextUtils.isEmpty(name)) {
-                details = new PhoneCallDetails(number, formattedNumber, countryIso,
+                details = new PhoneCallDetails(number, formattedNumber, countryIso, geocode,
                         callTypes, date, duration);
             } else {
-                details = new PhoneCallDetails(number, formattedNumber, countryIso,
+                details = new PhoneCallDetails(number, formattedNumber, countryIso, geocode,
                         callTypes, date, duration, name, ntype, label, personId, thumbnailUri);
             }
 
diff --git a/src/com/android/contacts/calllog/CallLogListItemHelper.java b/src/com/android/contacts/calllog/CallLogListItemHelper.java
index a973d49..5951ea3 100644
--- a/src/com/android/contacts/calllog/CallLogListItemHelper.java
+++ b/src/com/android/contacts/calllog/CallLogListItemHelper.java
@@ -18,7 +18,9 @@
 
 import com.android.contacts.PhoneCallDetails;
 import com.android.contacts.PhoneCallDetailsHelper;
+import com.android.contacts.R;
 
+import android.content.res.Resources;
 import android.provider.CallLog.Calls;
 import android.view.View;
 
@@ -30,6 +32,8 @@
     private final PhoneCallDetailsHelper mPhoneCallDetailsHelper;
     /** Helper for handling phone numbers. */
     private final PhoneNumberHelper mPhoneNumberHelper;
+    /** Resources to look up strings. */
+    private final Resources mResources;
 
     /**
      * Creates a new helper instance.
@@ -38,9 +42,10 @@
      * @param phoneNumberHelper used to process phone number
      */
     public CallLogListItemHelper(PhoneCallDetailsHelper phoneCallDetailsHelper,
-            PhoneNumberHelper phoneNumberHelper) {
+            PhoneNumberHelper phoneNumberHelper, Resources resources) {
         mPhoneCallDetailsHelper = phoneCallDetailsHelper;
         mPhoneNumberHelper= phoneNumberHelper;
+        mResources = resources;
     }
 
     /**
@@ -59,22 +64,35 @@
 
         if (canPlay) {
             // Playback action takes preference.
-            views.callView.setVisibility(View.GONE);
-            views.playView.setVisibility(View.VISIBLE);
+            configurePlaySecondaryAction(views);
             views.unheardView.setVisibility(isHighlighted ? View.VISIBLE : View.GONE);
             views.dividerView.setVisibility(View.VISIBLE);
         } else if (canCall) {
-            // Call is the main action.
-            views.callView.setVisibility(View.VISIBLE);
-            views.playView.setVisibility(View.GONE);
+            // Call is the secondary action.
+            configureCallSecondaryAction(views);
             views.unheardView.setVisibility(View.GONE);
             views.dividerView.setVisibility(View.VISIBLE);
         } else {
             // No action available.
-            views.callView.setVisibility(View.GONE);
-            views.playView.setVisibility(View.GONE);
+            views.secondaryActionView.setVisibility(View.GONE);
             views.unheardView.setVisibility(View.GONE);
             views.dividerView.setVisibility(View.GONE);
         }
     }
+
+    /** Sets the secondary action to correspond to the call button. */
+    private void configureCallSecondaryAction(CallLogListItemViews views) {
+        views.secondaryActionView.setVisibility(View.VISIBLE);
+        views.secondaryActionView.setImageResource(R.drawable.ic_ab_dialer_holo_dark);
+        views.secondaryActionView.setContentDescription(
+                mResources.getString(R.string.description_call_log_call_button));
+    }
+
+    /** Sets the secondary action to correspond to the play button. */
+    private void configurePlaySecondaryAction(CallLogListItemViews views) {
+        views.secondaryActionView.setVisibility(View.VISIBLE);
+        views.secondaryActionView.setImageResource(R.drawable.ic_play_holo_dark);
+        views.secondaryActionView.setContentDescription(
+                mResources.getString(R.string.description_call_log_play_button));
+    }
 }
diff --git a/src/com/android/contacts/calllog/CallLogListItemViews.java b/src/com/android/contacts/calllog/CallLogListItemViews.java
index 21f2dc5..040d0ad 100644
--- a/src/com/android/contacts/calllog/CallLogListItemViews.java
+++ b/src/com/android/contacts/calllog/CallLogListItemViews.java
@@ -21,6 +21,7 @@
 
 import android.content.Context;
 import android.view.View;
+import android.widget.ImageView;
 import android.widget.QuickContactBadge;
 import android.widget.TextView;
 
@@ -30,13 +31,11 @@
 public final class CallLogListItemViews {
     /** The quick contact badge for the contact. */
     public final QuickContactBadge quickContactView;
-    /** The main action button on the entry. */
-    public final View callView;
-    /** The play action button used for voicemail. */
-    public final View playView;
+    /** The secondary action button on the entry. */
+    public final ImageView secondaryActionView;
     /** The icon used for unheard voicemail. */
     public final View unheardView;
-    /** The divider between callView and playView. */
+    /** The divider between the primary and secondary actions. */
     public final View dividerView;
     /** The details of the phone call. */
     public final PhoneCallDetailsViews phoneCallDetailsViews;
@@ -46,12 +45,11 @@
     public final TextView listHeaderTextView;
 
     private CallLogListItemViews(QuickContactBadge quickContactView,
-            View callView, View playView, View unheardView, View dividerView,
+            ImageView secondaryActionView, View unheardView, View dividerView,
             PhoneCallDetailsViews phoneCallDetailsViews, View listItemView,
             TextView listHeaderTextView) {
         this.quickContactView = quickContactView;
-        this.callView = callView;
-        this.playView = playView;
+        this.secondaryActionView = secondaryActionView;
         this.unheardView = unheardView;
         this.dividerView = dividerView;
         this.phoneCallDetailsViews = phoneCallDetailsViews;
@@ -62,8 +60,7 @@
     public static CallLogListItemViews fromView(View view) {
         return new CallLogListItemViews(
                 (QuickContactBadge) view.findViewById(R.id.quick_contact_photo),
-                view.findViewById(R.id.call_icon),
-                view.findViewById(R.id.play_icon),
+                (ImageView) view.findViewById(R.id.secondary_action_icon),
                 view.findViewById(R.id.unheard_icon),
                 view.findViewById(R.id.divider),
                 PhoneCallDetailsViews.fromView(view),
@@ -74,8 +71,7 @@
     public static CallLogListItemViews createForTest(Context context) {
         return new CallLogListItemViews(
                 new QuickContactBadge(context),
-                new View(context),
-                new View(context),
+                new ImageView(context),
                 new View(context),
                 new View(context),
                 PhoneCallDetailsViews.createForTest(context),
diff --git a/src/com/android/contacts/calllog/CallLogQueryHandler.java b/src/com/android/contacts/calllog/CallLogQueryHandler.java
index 394599f..68ac63a 100644
--- a/src/com/android/contacts/calllog/CallLogQueryHandler.java
+++ b/src/com/android/contacts/calllog/CallLogQueryHandler.java
@@ -103,7 +103,7 @@
                 new MatrixCursor(CallLogFragment.CallLogQuery.EXTENDED_PROJECTION);
         // The values in this row correspond to default values for _PROJECTION from CallLogQuery
         // plus the section value.
-        matrixCursor.addRow(new Object[]{ -1L, "", 0L, 0L, 0, "", "", section });
+        matrixCursor.addRow(new Object[]{ -1L, "", 0L, 0L, 0, "", "", "", section });
         return matrixCursor;
     }
 
diff --git a/src/com/android/contacts/calllog/PhoneNumberHelper.java b/src/com/android/contacts/calllog/PhoneNumberHelper.java
index bf493f5..4d96f4f 100644
--- a/src/com/android/contacts/calllog/PhoneNumberHelper.java
+++ b/src/com/android/contacts/calllog/PhoneNumberHelper.java
@@ -18,10 +18,6 @@
 
 import com.android.contacts.R;
 import com.android.internal.telephony.CallerInfo;
-import com.google.i18n.phonenumbers.NumberParseException;
-import com.google.i18n.phonenumbers.PhoneNumberUtil;
-import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
-import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
 
 import android.content.res.Resources;
 import android.net.Uri;
@@ -34,14 +30,10 @@
 public class PhoneNumberHelper {
     private final Resources mResources;
     private final String mVoicemailNumber;
-    private final PhoneNumberUtil mPhoneNumberUtil;
-    private final PhoneNumberOfflineGeocoder mPhoneNumberOfflineGeocoder;
 
     public PhoneNumberHelper(Resources resources, String voicemailNumber) {
         mResources = resources;
         mVoicemailNumber = voicemailNumber;
-        mPhoneNumberUtil = PhoneNumberUtil.getInstance();
-        mPhoneNumberOfflineGeocoder = PhoneNumberOfflineGeocoder.getInstance();
     }
 
     /** Returns true if it is possible to place a call to the given number. */
@@ -106,35 +98,4 @@
     public boolean isSipNumber(CharSequence number) {
         return PhoneNumberUtils.isUriNumber(number.toString());
     }
-
-    /**
-     * Returns a structured phone number from the given text representation, or null if the number
-     * cannot be parsed.
-     */
-    private PhoneNumber parsePhoneNumber(String number, String countryIso) {
-        try {
-            return mPhoneNumberUtil.parse(number, countryIso);
-        } catch (NumberParseException e) {
-            return null;
-        }
-    }
-
-    /** Returns the geocode associated with a phone number or the empty string if not available. */
-    public String getGeocodeForNumber(String number, String countryIso) {
-        if (!canGeocode(number)) {
-            return "";
-        }
-        PhoneNumber structuredPhoneNumber = parsePhoneNumber(number, countryIso);
-        if (structuredPhoneNumber != null) {
-            return mPhoneNumberOfflineGeocoder.getDescriptionForNumber(
-                    structuredPhoneNumber, mResources.getConfiguration().locale);
-        } else {
-            return "";
-        }
-    }
-
-    /** Returns true if it is possible to compute a geocode for the given number. */
-    private boolean canGeocode(CharSequence number) {
-        return canPlaceCallsTo(number) && !isVoicemailNumber(number);
-    }
 }
diff --git a/src/com/android/contacts/group/GroupEditorFragment.java b/src/com/android/contacts/group/GroupEditorFragment.java
index e8122ef..b060541 100644
--- a/src/com/android/contacts/group/GroupEditorFragment.java
+++ b/src/com/android/contacts/group/GroupEditorFragment.java
@@ -345,13 +345,27 @@
         }
     }
 
+    private AccountType getAccountType() {
+        return AccountTypeManager.getInstance(mContext).getAccountType(mAccountType, mDataSet);
+    }
+
+    /**
+     * @return true if the group membership is editable on this account type.  false otherwise,
+     *         or account is not set yet.
+     */
+    private boolean isGroupMembershipEditable() {
+        if (mAccountType == null) {
+            return false;
+        }
+        return getAccountType().isGroupMembershipEditable();
+    }
+
     /**
      * Sets up the editor based on the group's account name and type.
      */
     private void setupEditorForAccount() {
-        final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(mContext);
-        final AccountType accountType = accountTypeManager.getAccountType(mAccountType, mDataSet);
-        final boolean editable = accountType.isGroupMembershipEditable();
+        final AccountType accountType = getAccountType();
+        final boolean editable = isGroupMembershipEditable();
         mMemberListAdapter.setIsGroupMembershipEditable(editable);
 
         View editorView = mLayoutInflater.inflate(editable ?
@@ -449,8 +463,13 @@
         mListener = value;
     }
 
-    public void doSaveAction() {
-        save(SaveMode.CLOSE);
+    public void onDoneClicked() {
+        if (isGroupMembershipEditable()) {
+            save(SaveMode.CLOSE);
+        } else {
+            // Just revert it.
+            doRevertAction();
+        }
     }
 
     @Override
diff --git a/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java b/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
index 487a13f..40a33b6 100644
--- a/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
+++ b/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
@@ -50,6 +50,8 @@
     private static final String TEST_FORMATTED_NUMBER = "1-412-255-5555";
     /** The country ISO name used in the tests. */
     private static final String TEST_COUNTRY_ISO = "US";
+    /** The geocoded location used in the tests. */
+    private static final String TEST_GEOCODE = "United States";
 
     /** The object under test. */
     private PhoneCallDetailsHelper mHelper;
@@ -268,7 +270,7 @@
     /** Sets the phone call details with default values and the given number. */
     private void setPhoneCallDetailsWithNumber(String number, String formattedNumber) {
         mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(number, formattedNumber, TEST_COUNTRY_ISO,
+                new PhoneCallDetails(number, formattedNumber, TEST_COUNTRY_ISO, TEST_GEOCODE,
                         new int[]{ Calls.VOICEMAIL_TYPE }, TEST_DATE, TEST_DURATION),
                 true);
     }
@@ -277,7 +279,7 @@
     private void setPhoneCallDetailsWithDate(long date) {
         mHelper.setPhoneCallDetails(mViews,
                 new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        new int[]{ Calls.INCOMING_TYPE }, date, TEST_DURATION),
+                        TEST_GEOCODE, new int[]{ Calls.INCOMING_TYPE }, date, TEST_DURATION),
                 false);
     }
 
@@ -285,20 +287,20 @@
     private void setPhoneCallDetailsWithCallTypeIcons(int... callTypes) {
         mHelper.setPhoneCallDetails(mViews,
                 new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        callTypes, TEST_DATE, TEST_DURATION),
+                        TEST_GEOCODE, callTypes, TEST_DATE, TEST_DURATION),
                 false);
     }
 
     private void setPhoneCallNameWithNumberOnly() {
         mHelper.setPhoneCallName(mNameView,
                 new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION));
+                        TEST_GEOCODE, new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION));
     }
 
     private void setPhoneCallName(String name) {
         mHelper.setPhoneCallName(mNameView,
                 new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION,
+                        TEST_GEOCODE, new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION,
                         name, 0, "", 1, null));
     }
 }
diff --git a/tests/src/com/android/contacts/activities/CallLogActivityTests.java b/tests/src/com/android/contacts/activities/CallLogActivityTests.java
index 7043eb0..ce2418f 100644
--- a/tests/src/com/android/contacts/activities/CallLogActivityTests.java
+++ b/tests/src/com/android/contacts/activities/CallLogActivityTests.java
@@ -174,7 +174,7 @@
         insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
         View view = mAdapter.newGroupView(getActivity(), mParentView);
         mAdapter.bindGroupView(view, getActivity(), mCursor, 3, false);
-        assertNotNull(view.findViewById(R.id.call_icon));
+        assertNotNull(view.findViewById(R.id.secondary_action_icon));
     }
 
     @MediumTest
@@ -183,7 +183,7 @@
         insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
         View view = mAdapter.newStandAloneView(getActivity(), mParentView);
         mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-        assertNotNull(view.findViewById(R.id.call_icon));
+        assertNotNull(view.findViewById(R.id.secondary_action_icon));
     }
 
     @MediumTest
@@ -192,7 +192,7 @@
         insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
         View view = mAdapter.newChildView(getActivity(), mParentView);
         mAdapter.bindChildView(view, getActivity(), mCursor);
-        assertNotNull(view.findViewById(R.id.call_icon));
+        assertNotNull(view.findViewById(R.id.secondary_action_icon));
     }
 
     @MediumTest
@@ -303,7 +303,7 @@
         mAdapter.bindStandAloneView(view, getActivity(), mCursor);
 
         CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        IntentProvider intentProvider = (IntentProvider) views.callView.getTag();
+        IntentProvider intentProvider = (IntentProvider) views.secondaryActionView.getTag();
         Intent intent = intentProvider.getIntent(mActivity);
         // Starts a call.
         assertEquals(Intent.ACTION_CALL_PRIVILEGED, intent.getAction());
@@ -319,7 +319,7 @@
         mAdapter.bindStandAloneView(view, getActivity(), mCursor);
 
         CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        IntentProvider intentProvider = (IntentProvider) views.playView.getTag();
+        IntentProvider intentProvider = (IntentProvider) views.secondaryActionView.getTag();
         Intent intent = intentProvider.getIntent(mActivity);
         // Starts the call detail activity.
         assertEquals(new ComponentName(mActivity, CallDetailActivity.class),
@@ -357,9 +357,9 @@
             String number = getPhoneNumberForListEntry(i);
             if (CallerInfo.PRIVATE_NUMBER.equals(number) ||
                 CallerInfo.UNKNOWN_NUMBER.equals(number)) {
-                assertFalse(View.VISIBLE == mItem.callView.getVisibility());
+                assertFalse(View.VISIBLE == mItem.secondaryActionView.getVisibility());
             } else {
-                assertEquals(View.VISIBLE, mItem.callView.getVisibility());
+                assertEquals(View.VISIBLE, mItem.secondaryActionView.getVisibility());
             }
         }
     }
diff --git a/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java
index 1cf7da9..2c29608 100644
--- a/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java
+++ b/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java
@@ -42,6 +42,8 @@
     private static final String TEST_VOICEMAIL_NUMBER = "123";
     /** The country ISO name used in the tests. */
     private static final String TEST_COUNTRY_ISO = "US";
+    /** The geocoded location used in the tests. */
+    private static final String TEST_GEOCODE = "United States";
 
     /** The object under test. */
     private CallLogListItemHelper mHelper;
@@ -59,7 +61,7 @@
         mPhoneNumberHelper = new PhoneNumberHelper(resources, TEST_VOICEMAIL_NUMBER);
         PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
                 resources, callTypeHelper, mPhoneNumberHelper);
-        mHelper = new CallLogListItemHelper(phoneCallDetailsHelper, mPhoneNumberHelper);
+        mHelper = new CallLogListItemHelper(phoneCallDetailsHelper, mPhoneNumberHelper, resources);
         mViews = CallLogListItemViews.createForTest(context);
     }
 
@@ -72,8 +74,7 @@
 
     public void testSetPhoneCallDetails() {
         setPhoneCallDetailsWithNumber("12125551234", "1-212-555-1234");
-        assertEquals(View.VISIBLE, mViews.callView.getVisibility());
-        assertEquals(View.GONE, mViews.playView.getVisibility());
+        assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
         assertEquals(View.GONE, mViews.unheardView.getVisibility());
     }
 
@@ -94,37 +95,32 @@
 
     public void testSetPhoneCallDetails_VoicemailNumber() {
         setPhoneCallDetailsWithNumber(TEST_VOICEMAIL_NUMBER, TEST_VOICEMAIL_NUMBER);
-        assertEquals(View.VISIBLE, mViews.callView.getVisibility());
-        assertEquals(View.GONE, mViews.playView.getVisibility());
+        assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
         assertEquals(View.GONE, mViews.unheardView.getVisibility());
     }
 
     public void testSetPhoneCallDetails_ReadVoicemail() {
         setPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
-        assertEquals(View.GONE, mViews.callView.getVisibility());
-        assertEquals(View.VISIBLE, mViews.playView.getVisibility());
+        assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
         assertEquals(View.GONE, mViews.unheardView.getVisibility());
     }
 
     public void testSetPhoneCallDetails_UnreadVoicemail() {
         setUnreadPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
-        assertEquals(View.GONE, mViews.callView.getVisibility());
-        assertEquals(View.VISIBLE, mViews.playView.getVisibility());
+        assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
         assertEquals(View.VISIBLE, mViews.unheardView.getVisibility());
     }
 
     public void testSetPhoneCallDetails_VoicemailFromUnknown() {
         setPhoneCallDetailsWithNumberAndType(CallerInfo.UNKNOWN_NUMBER, CallerInfo.UNKNOWN_NUMBER,
                 Calls.VOICEMAIL_TYPE);
-        assertEquals(View.GONE, mViews.callView.getVisibility());
-        assertEquals(View.VISIBLE, mViews.playView.getVisibility());
+        assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
         assertEquals(View.GONE, mViews.unheardView.getVisibility());
     }
 
     /** Asserts that the whole call area is gone. */
     private void assertNoCallButton() {
-        assertEquals(View.GONE, mViews.callView.getVisibility());
-        assertEquals(View.GONE, mViews.playView.getVisibility());
+        assertEquals(View.GONE, mViews.secondaryActionView.getVisibility());
         assertEquals(View.GONE, mViews.unheardView.getVisibility());
         assertEquals(View.GONE, mViews.dividerView.getVisibility());
     }
@@ -138,7 +134,7 @@
     private void setPhoneCallDetailsWithNumberAndType(String number, String formattedNumber,
             int callType) {
         mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(number, formattedNumber, TEST_COUNTRY_ISO,
+                new PhoneCallDetails(number, formattedNumber, TEST_COUNTRY_ISO, TEST_GEOCODE,
                         new int[]{ callType }, TEST_DATE, TEST_DURATION),
                 false);
     }
@@ -147,7 +143,7 @@
     private void setPhoneCallDetailsWithTypes(int... types) {
         mHelper.setPhoneCallDetails(mViews,
                 new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        types, TEST_DATE, TEST_DURATION),
+                        TEST_GEOCODE, types, TEST_DATE, TEST_DURATION),
                 false);
     }
 
@@ -155,7 +151,7 @@
     private void setUnreadPhoneCallDetailsWithTypes(int... types) {
         mHelper.setPhoneCallDetails(mViews,
                 new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        types, TEST_DATE, TEST_DURATION),
+                        TEST_GEOCODE, types, TEST_DATE, TEST_DURATION),
                 true);
     }
 }