Merge "Import translations. DO NOT MERGE" into lmp-dev
diff --git a/res/drawable-hdpi/ic_person_add_24dp.png b/res/drawable-hdpi/ic_person_add_24dp.png
deleted file mode 100644
index 1b71ff1..0000000
--- a/res/drawable-hdpi/ic_person_add_24dp.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_person_add_24dp.png b/res/drawable-mdpi/ic_person_add_24dp.png
deleted file mode 100644
index b6cf02d..0000000
--- a/res/drawable-mdpi/ic_person_add_24dp.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_person_add_24dp.png b/res/drawable-xhdpi/ic_person_add_24dp.png
deleted file mode 100644
index 2d265e1..0000000
--- a/res/drawable-xhdpi/ic_person_add_24dp.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_person_add_24dp.png b/res/drawable-xxhdpi/ic_person_add_24dp.png
deleted file mode 100644
index 6091312..0000000
--- a/res/drawable-xxhdpi/ic_person_add_24dp.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/ic_person_add_tinted_24dp.xml b/res/drawable/ic_person_add_tinted_24dp.xml
deleted file mode 100644
index 6d79663..0000000
--- a/res/drawable/ic_person_add_tinted_24dp.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2014 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
-  -->
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_person_add_24dp"
-    android:autoMirrored="true"
-    android:tint="@color/actionbar_icon_color" />
\ No newline at end of file
diff --git a/res/layout/contact_picker.xml b/res/layout/contact_picker.xml
index b6741cf..2efe471 100644
--- a/res/layout/contact_picker.xml
+++ b/res/layout/contact_picker.xml
@@ -14,16 +14,9 @@
      limitations under the License.
 -->
 
-<RelativeLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     style="@style/ContactPickerLayout"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent">
-
-    <FrameLayout
-        android:id="@+id/list_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-
-    <include layout="@layout/floating_action_button" />
-</RelativeLayout>
+    android:id="@+id/list_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" />
diff --git a/res/layout/quickcontact_content.xml b/res/layout/quickcontact_content.xml
index e98e599..bab8b6d 100644
--- a/res/layout/quickcontact_content.xml
+++ b/res/layout/quickcontact_content.xml
@@ -25,7 +25,9 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical"
-        android:id="@+id/card_container">
+        android:id="@+id/card_container"
+        android:paddingTop="@dimen/first_card_marginTop"
+        android:background="@color/card_margin_color"  >
 
         <!-- We cannot set the border directly on ExpandingEntryCardView without it looking
              funny because of the card's elevation value. So we need a parent FrameLayout -->
@@ -36,7 +38,6 @@
             <com.android.contacts.quickcontact.ExpandingEntryCardView
                 style="@style/ExpandingEntryCardStyle"
                 android:id="@+id/no_contact_data_card"
-                android:layout_marginTop="@dimen/communication_card_marginTop"
                 android:visibility="gone" />
         </FrameLayout>
 
@@ -47,7 +48,6 @@
             <com.android.contacts.quickcontact.ExpandingEntryCardView
                 style="@style/ExpandingEntryCardStyle"
                 android:id="@+id/communication_card"
-                android:layout_marginTop="@dimen/communication_card_marginTop"
                 android:visibility="gone" />
         </FrameLayout>
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 877a68f..40adc95 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -152,7 +152,7 @@
     <dimen name="expanding_entry_card_border_width">12dp</dimen>
 
     <!-- Top margin for the communication card, used to add space from header. -->
-    <dimen name="communication_card_marginTop">12dp</dimen>
+    <dimen name="first_card_marginTop">12dp</dimen>
 
     <!-- Elevation of an ExpandingEntryCard, for the sake of shadow casting -->
     <dimen name="expanding_entry_card_elevation">1dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 494e115..9583fcb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -46,6 +46,9 @@
     <!-- Activity title when the user is selecting a contact.  [CHAR LIMIT=128] -->
     <string name="contactPickerActivityTitle">Choose a contact</string>
 
+    <!-- Activity title when the user is selecting a contact.  [CHAR LIMIT=30] -->
+    <string name="header_entry_contact_list_adapter_header_title">Select new contact</string>
+
     <!-- Title for the activity that shows only starred contacts -->
     <string name="starredList">Starred</string>
 
@@ -93,6 +96,11 @@
     <!-- Menu item used to remove a star from a contact, making the contact no longer show up at the top of favorites -->
     <string name="menu_removeStar">Remove from favorites</string>
 
+    <!-- Description of what happens when you click on the unstar MenuItem. [CHAR LIMIT=NONE] -->
+    <string name="description_action_menu_remove_star">Removed from favorites</string>
+    <!-- Description of what happens when you click on the star MenuItem. [CHAR LIMIT=NONE] -->
+    <string name="description_action_menu_add_star">Added to favorites</string>
+
     <!-- Menu item used to edit a specific contact -->
     <string name="menu_editContact">Edit</string>
 
diff --git a/src/com/android/contacts/activities/ContactSelectionActivity.java b/src/com/android/contacts/activities/ContactSelectionActivity.java
index 4375cb7..c67a50e 100644
--- a/src/com/android/contacts/activities/ContactSelectionActivity.java
+++ b/src/com/android/contacts/activities/ContactSelectionActivity.java
@@ -35,7 +35,6 @@
 import android.view.View.OnClickListener;
 import android.view.View.OnFocusChangeListener;
 import android.view.inputmethod.InputMethodManager;
-import android.widget.ImageButton;
 import android.widget.SearchView;
 import android.widget.SearchView.OnCloseListener;
 import android.widget.SearchView.OnQueryTextListener;
@@ -44,7 +43,6 @@
 import com.android.contacts.ContactsActivity;
 import com.android.contacts.R;
 import com.android.contacts.common.list.ContactEntryListFragment;
-import com.android.contacts.common.util.ViewUtil;
 import com.android.contacts.list.ContactPickerFragment;
 import com.android.contacts.list.ContactsIntentResolver;
 import com.android.contacts.list.ContactsRequest;
@@ -129,33 +127,19 @@
         }
 
         prepareSearchViewAndActionBar();
-
-        // Configure action button
-        final View floatingActionButtonContainer = findViewById(
-                R.id.floating_action_button_container);
-        if (shouldShowCreateNewContactButton()) {
-            ViewUtil.setupFloatingActionButton(floatingActionButtonContainer, getResources());
-            final ImageButton floatingActionButton
-                    = (ImageButton) findViewById(R.id.floating_action_button);
-            floatingActionButton.setOnClickListener(this);
-        } else {
-            floatingActionButtonContainer.setVisibility(View.GONE);
-        }
-    }
-
-    private boolean shouldShowCreateNewContactButton() {
-        return (mActionCode == ContactsRequest.ACTION_INSERT_OR_EDIT_CONTACT
-                || (mActionCode == ContactsRequest.ACTION_PICK_OR_CREATE_CONTACT
-                        && !mRequest.isSearchMode()));
     }
 
     private void prepareSearchViewAndActionBar() {
+        final ActionBar actionBar = getActionBar();
+        final View searchViewContainer = LayoutInflater.from(actionBar.getThemedContext())
+                .inflate(R.layout.custom_action_bar, null);
+        mSearchView = (SearchView) searchViewContainer.findViewById(R.id.search_view);
+
         // Postal address pickers (and legacy pickers) don't support search, so just show
         // "HomeAsUp" button and title.
         if (mRequest.getActionCode() == ContactsRequest.ACTION_PICK_POSTAL ||
                 mRequest.isLegacyCompatibilityMode()) {
-            findViewById(R.id.search_view).setVisibility(View.GONE);
-            final ActionBar actionBar = getActionBar();
+            mSearchView.setVisibility(View.GONE);
             if (actionBar != null) {
                 actionBar.setDisplayShowHomeEnabled(true);
                 actionBar.setDisplayHomeAsUpEnabled(true);
@@ -164,11 +148,6 @@
             return;
         }
 
-        final ActionBar actionBar = getActionBar();
-        final View searchViewContainer = LayoutInflater.from(actionBar.getThemedContext())
-                .inflate(R.layout.custom_action_bar, null);
-        mSearchView = (SearchView) searchViewContainer.findViewById(R.id.search_view);
-
         // In order to make the SearchView look like "shown via search menu", we need to
         // manually setup its state. See also DialtactsActivity.java and ActionBarAdapter.java.
         mSearchView.setIconifiedByDefault(true);
@@ -272,6 +251,7 @@
                 ContactPickerFragment fragment = new ContactPickerFragment();
                 fragment.setEditMode(true);
                 fragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
+                fragment.setCreateContactEnabled(!mRequest.isSearchMode());
                 mListFragment = fragment;
                 break;
             }
@@ -286,6 +266,7 @@
 
             case ContactsRequest.ACTION_PICK_OR_CREATE_CONTACT: {
                 ContactPickerFragment fragment = new ContactPickerFragment();
+                fragment.setCreateContactEnabled(!mRequest.isSearchMode());
                 mListFragment = fragment;
                 break;
             }
diff --git a/src/com/android/contacts/list/ContactPickerFragment.java b/src/com/android/contacts/list/ContactPickerFragment.java
index 3dc4330..442f5c7 100644
--- a/src/com/android/contacts/list/ContactPickerFragment.java
+++ b/src/com/android/contacts/list/ContactPickerFragment.java
@@ -28,7 +28,6 @@
 import com.android.contacts.common.list.ContactEntryListFragment;
 import com.android.contacts.common.list.ContactListAdapter;
 import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.common.list.DefaultContactListAdapter;
 import com.android.contacts.common.list.DirectoryListLoader;
 import com.android.contacts.common.list.ShortcutIntentBuilder;
 import com.android.contacts.common.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
@@ -105,7 +104,9 @@
     @Override
     protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
         super.onCreateView(inflater, container);
-        if (mCreateContactEnabled) {
+        if (mCreateContactEnabled && isLegacyCompatibilityMode()) {
+            // Since we are using the legacy adapter setShowCreateContact(true) isn't supported.
+            // So we need to add an ugly header above the list.
             getListView().addHeaderView(inflater.inflate(R.layout.create_new_contact, null, false));
         }
     }
@@ -152,12 +153,14 @@
     @Override
     protected ContactEntryListAdapter createListAdapter() {
         if (!isLegacyCompatibilityMode()) {
-            DefaultContactListAdapter adapter = new DefaultContactListAdapter(getActivity());
+            HeaderEntryContactListAdapter adapter
+                    = new HeaderEntryContactListAdapter(getActivity());
             adapter.setFilter(ContactListFilter.createFilterWithType(
                     ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS));
             adapter.setSectionHeaderDisplayEnabled(true);
             adapter.setDisplayPhotos(true);
             adapter.setQuickContactEnabled(false);
+            adapter.setShowCreateContact(mCreateContactEnabled);
             return adapter;
         } else {
             LegacyContactListAdapter adapter = new LegacyContactListAdapter(getActivity());
diff --git a/src/com/android/contacts/list/HeaderEntryContactListAdapter.java b/src/com/android/contacts/list/HeaderEntryContactListAdapter.java
new file mode 100644
index 0000000..6d6c3c3
--- /dev/null
+++ b/src/com/android/contacts/list/HeaderEntryContactListAdapter.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2014 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.R;
+import com.android.contacts.common.list.ContactListItemView;
+import com.android.contacts.common.list.DefaultContactListAdapter;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Equivalent to DefaultContactListAdapter, except with an optional header entry that has the same
+ * formatting as the other entries in the list.
+ *
+ * This header entry is hidden when in search mode. Should not be used with lists that contain a
+ * "Me" contact.
+ */
+public class HeaderEntryContactListAdapter extends DefaultContactListAdapter {
+
+    private boolean mShowCreateContact;
+
+    public HeaderEntryContactListAdapter(Context context) {
+        super(context);
+    }
+
+    private int getHeaderEntryCount() {
+        return isSearchMode() || !mShowCreateContact ? 0 : 1;
+    }
+
+    /**
+     * Whether the first entry should be "Create contact", when not in search mode.
+     */
+    public void setShowCreateContact(boolean showCreateContact) {
+        mShowCreateContact = showCreateContact;
+        invalidate();
+    }
+
+    @Override
+    public int getCount() {
+        return super.getCount() + getHeaderEntryCount();
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (position == 0 && getHeaderEntryCount() > 0) {
+            final ContactListItemView itemView;
+            if (convertView == null) {
+                // Pass the cursor down. Don't worry, it isn't used.
+                itemView = newView(getContext(), 0, getCursor(0), 0, parent);
+            } else {
+                itemView = (ContactListItemView ) convertView;
+            }
+            itemView.setDrawableResource(R.drawable.search_shortcut_background,
+                    R.drawable.ic_search_add_contact);
+            itemView.setDisplayName(getContext().getResources().getString(
+                    R.string.header_entry_contact_list_adapter_header_title));
+            return itemView;
+        }
+        return super.getView(position - getHeaderEntryCount(), convertView, parent);
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return super.getItem(position - getHeaderEntryCount());
+    }
+
+    @Override
+    protected void bindView(View itemView, int partition, Cursor cursor, int position) {
+        super.bindView(itemView, partition, cursor, position + getHeaderEntryCount());
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (position == 0 && getHeaderEntryCount() > 0) {
+            return getViewTypeCount() - 1;
+        }
+        return super.getItemViewType(position - getHeaderEntryCount());
+    }
+
+    @Override
+    public int getViewTypeCount() {
+        // One additional view type, for the header entry.
+        return super.getViewTypeCount() + 1;
+    }
+
+    @Override
+    protected boolean getExtraStartingSection() {
+        return getHeaderEntryCount() > 0;
+    }
+}
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index e453a4b..69fef9e 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -26,7 +26,6 @@
 import android.app.LoaderManager.LoaderCallbacks;
 import android.app.SearchManager;
 import android.content.ActivityNotFoundException;
-import android.content.ComponentName;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Intent;
@@ -1560,6 +1559,13 @@
             final Intent intent = ContactSaveService.createSetStarredIntent(
                     QuickContactActivity.this, mLookupUri, !isStarred);
             startService(intent);
+
+            final CharSequence accessibilityText = !isStarred
+                    ? getResources().getText(R.string.description_action_menu_add_star)
+                    : getResources().getText(R.string.description_action_menu_remove_star);
+            // Accessibility actions need to have an associated view. We can't access the MenuItem's
+            // underlying view, so put this accessibility action on the root view.
+            mScroller.announceForAccessibility(accessibilityText);
         }
     }