Merge "Import translations. DO NOT MERGE" into ub-contactsdialer-h-dev
diff --git a/AndroidManifest_common.xml b/AndroidManifest_common.xml
index c616c1e..d1bd37c 100644
--- a/AndroidManifest_common.xml
+++ b/AndroidManifest_common.xml
@@ -351,7 +351,20 @@
             </intent-filter>
         </activity>
 
-        <activity
+         <!-- Keep support for apps that expect the Compact editor -->
+         <activity-alias android:name="com.android.contacts.activities.CompactContactEditorActivity"
+             android:exported="true"
+             android:targetActivity=".activities.ContactEditorActivity">
+             <intent-filter>
+                 <action android:name="android.intent.action.INSERT" />
+                 <category android:name="android.intent.category.DEFAULT" />
+                 <data android:mimeType="vnd.android.cursor.dir/person" />
+                 <data android:mimeType="vnd.android.cursor.dir/contact" />
+                 <data android:mimeType="vnd.android.cursor.dir/raw_contact" />
+             </intent-filter>
+         </activity-alias>
+
+         <activity
             android:name=".activities.ContactEditorSpringBoardActivity"
             android:noHistory="true"
             android:theme="@style/TransparentThemeAppCompat">
diff --git a/res/layout/fragment_sim_import.xml b/res/layout/fragment_sim_import.xml
index b0eb280..00336dd 100644
--- a/res/layout/fragment_sim_import.xml
+++ b/res/layout/fragment_sim_import.xml
@@ -41,7 +41,7 @@
                 style="@style/Widget.AppCompat.Button.Borderless"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_gravity="right|center_vertical"
+                android:layout_gravity="end|center_vertical"
                 android:text="@string/sim_import_button_text"
                 />
         </android.support.v7.widget.Toolbar>
diff --git a/res/layout/join_contact_picker_section_header.xml b/res/layout/join_contact_picker_section_header.xml
index 7dafb49..f39cafd 100644
--- a/res/layout/join_contact_picker_section_header.xml
+++ b/res/layout/join_contact_picker_section_header.xml
@@ -23,8 +23,9 @@
     <TextView
         android:id="@+id/text"
         style="@style/ContactListSeparatorTextViewStyle"
-        android:paddingLeft="8dip"
-        android:paddingRight="8dip"
-        android:paddingStart="8dip"
-        android:paddingEnd="8dip" />
+        android:textAlignment="viewStart"
+        android:paddingLeft="24dip"
+        android:paddingRight="24dip"
+        android:paddingStart="24dip"
+        android:paddingEnd="24dip"/>
 </LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d3431fb..d603973 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -148,8 +148,8 @@
     <!-- For join screen. Mainly for tablet. -->
     <dimen name="join_header_left_margin">@dimen/contact_browser_list_header_left_margin</dimen>
     <dimen name="join_header_right_margin">@dimen/contact_browser_list_header_right_margin</dimen>
-    <dimen name="join_header_top_margin">16dip</dimen>
-    <dimen name="join_header_bottom_margin">0dip</dimen>
+    <dimen name="join_header_top_margin">12dip</dimen>
+    <dimen name="join_header_bottom_margin">12dip</dimen>
 
     <dimen name="contact_filter_header_min_height">24dip</dimen>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6980f23..a402d68 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -972,9 +972,9 @@
     <string name="permission_explanation_subheader_SMS">Messages</string>
 
     <!-- The header text for hamburger promo [CHAR LIMIT=60]-->
-    <string name="hamburger_feature_highlight_header">Organize your list</string>
+    <string name="hamburger_feature_highlight_header">Suggestions</string>
     <!-- The body text for hamburger promo [CHAR LIMIT=200]-->
-    <string name="hamburger_feature_highlight_body">Clean up duplicates &amp; group contacts by label</string>
+    <string name="hamburger_feature_highlight_body">Keep your contacts organized and useful</string>
 
     <!-- The label for the action shown in a snackbar after an operation that modifies some data is performed.
          The user can click on the action to rollback the modification-->
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index c2198bb..5d478fe 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -810,9 +810,13 @@
                     R.id.contacts_list_container, mMembersFragment, TAG_GROUP_VIEW);
         } else if (isAssistantView()) {
             Fragment uiFragment = fragmentManager.findFragmentByTag(TAG_ASSISTANT);
+            Fragment unavailableFragment = fragmentManager.findFragmentByTag(TAG_UNAVAILABLE);
             if (uiFragment == null) {
                 uiFragment = ObjectFactory.getAssistantFragment();
             }
+            if (unavailableFragment != null) {
+                transaction.remove(unavailableFragment);
+            }
             transaction.replace(R.id.contacts_list_container, uiFragment, TAG_ASSISTANT);
             resetToolBarStatusBarColor();
         }
diff --git a/src/com/android/contacts/common/CallUtil.java b/src/com/android/contacts/common/CallUtil.java
index 88fca92..acfad52 100644
--- a/src/com/android/contacts/common/CallUtil.java
+++ b/src/com/android/contacts/common/CallUtil.java
@@ -20,6 +20,7 @@
 import com.android.contacts.common.compat.PhoneAccountSdkCompat;
 import com.android.contacts.common.util.PermissionsUtil;
 import com.android.contacts.common.util.PhoneNumberHelper;
+import com.android.contactsbind.FeedbackHelper;
 import com.android.phone.common.PhoneConstants;
 
 import android.content.Context;
@@ -41,6 +42,8 @@
  */
 public class CallUtil {
 
+    public static final String TAG = "CallUtil";
+
     /**
      * Indicates that the video calling is not available.
      */
@@ -140,26 +143,32 @@
             return VIDEO_CALLING_DISABLED;
         }
 
-        List<PhoneAccountHandle> accountHandles = telecommMgr.getCallCapablePhoneAccounts();
-        for (PhoneAccountHandle accountHandle : accountHandles) {
-            PhoneAccount account = telecommMgr.getPhoneAccount(accountHandle);
-            if (account != null) {
-                if (account.hasCapabilities(PhoneAccount.CAPABILITY_VIDEO_CALLING)) {
-                    // Builds prior to N do not have presence support.
-                    if (!CompatUtils.isVideoPresenceCompatible()) {
-                        return VIDEO_CALLING_ENABLED;
-                    }
+        try {
+            List<PhoneAccountHandle> accountHandles = telecommMgr.getCallCapablePhoneAccounts();
+            for (PhoneAccountHandle accountHandle : accountHandles) {
+                PhoneAccount account = telecommMgr.getPhoneAccount(accountHandle);
+                if (account != null) {
+                    if (account.hasCapabilities(PhoneAccount.CAPABILITY_VIDEO_CALLING)) {
+                        // Builds prior to N do not have presence support.
+                        if (!CompatUtils.isVideoPresenceCompatible()) {
+                            return VIDEO_CALLING_ENABLED;
+                        }
 
-                    int videoCapabilities = VIDEO_CALLING_ENABLED;
-                    if (account.hasCapabilities(
-                            PhoneAccountSdkCompat.CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)) {
-                        videoCapabilities |= VIDEO_CALLING_PRESENCE;
+                        int videoCapabilities = VIDEO_CALLING_ENABLED;
+                        if (account.hasCapabilities(PhoneAccountSdkCompat
+                                .CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)) {
+                            videoCapabilities |= VIDEO_CALLING_PRESENCE;
+                        }
+                        return videoCapabilities;
                     }
-                    return videoCapabilities;
                 }
             }
+            return VIDEO_CALLING_DISABLED;
+        } catch (SecurityException e) {
+            FeedbackHelper.sendFeedback(context, TAG,
+                    "Security exception when querying intent activities", e);
+            return VIDEO_CALLING_DISABLED;
         }
-        return VIDEO_CALLING_DISABLED;
     }
 
     /**
diff --git a/src/com/android/contacts/common/database/SimContactDao.java b/src/com/android/contacts/common/database/SimContactDao.java
index 8805c52..3175ce4 100644
--- a/src/com/android/contacts/common/database/SimContactDao.java
+++ b/src/com/android/contacts/common/database/SimContactDao.java
@@ -24,7 +24,6 @@
 import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Build;
 import android.os.RemoteException;
 import android.provider.BaseColumns;
@@ -40,14 +39,12 @@
 import android.util.SparseArray;
 
 import com.android.contacts.R;
-import com.android.contacts.common.Experiments;
 import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.model.SimCard;
 import com.android.contacts.common.model.SimContact;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.util.PermissionsUtil;
 import com.android.contacts.util.SharedPreferenceUtil;
-import com.android.contactsbind.experiments.Flags;
 import com.google.common.base.Joiner;
 
 import java.util.ArrayList;
@@ -97,17 +94,6 @@
         mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
     }
 
-    public void warmupSimQueryIfNeeded() {
-        if (!canReadSimContacts()) return;
-
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                getSimCardsWithContacts();
-                return null;
-            }
-        }.execute();
-    }
 
     public Context getContext() {
         return mContext;
@@ -279,13 +265,19 @@
         return contacts != null ? contacts : loadContactsForSim(sim);
     }
 
+    // See b/32831092
+    // Sometimes the SIM contacts provider seems to get stuck if read from multiple threads
+    // concurrently. So we just have a global lock around it to prevent potential issues.
+    private static final Object SIM_READ_LOCK = new Object();
     private ArrayList<SimContact> loadFrom(Uri uri) {
-        final Cursor cursor = mResolver.query(uri, null, null, null, null);
+        synchronized (SIM_READ_LOCK) {
+            final Cursor cursor = mResolver.query(uri, null, null, null, null);
 
-        try {
-            return loadFromCursor(cursor);
-        } finally {
-            cursor.close();
+            try {
+                return loadFromCursor(cursor);
+            } finally {
+                cursor.close();
+            }
         }
     }
 
@@ -423,10 +415,6 @@
         }
 
         @Override
-        public void warmupSimQueryIfNeeded() {
-        }
-
-        @Override
         public List<SimCard> getSimCards() {
             return SharedPreferenceUtil.restoreSimStates(getContext(), mSimCards);
         }
diff --git a/src/com/android/contacts/common/model/account/BaseAccountType.java b/src/com/android/contacts/common/model/account/BaseAccountType.java
index 8d8b8e4..400b0e9 100644
--- a/src/com/android/contacts/common/model/account/BaseAccountType.java
+++ b/src/com/android/contacts/common/model/account/BaseAccountType.java
@@ -947,24 +947,24 @@
             kinds.add(kn);
 
             kn.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
-                    FLAGS_PERSON_NAME).setLongForm(true));
+                    FLAGS_PERSON_NAME).setOptional(true));
             if (!displayOrderPrimary) {
                 kn.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
                         FLAGS_PERSON_NAME));
                 kn.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
-                        FLAGS_PERSON_NAME).setLongForm(true));
+                        FLAGS_PERSON_NAME).setOptional(true));
                 kn.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
                         FLAGS_PERSON_NAME));
             } else {
                 kn.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
                         FLAGS_PERSON_NAME));
                 kn.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
-                        FLAGS_PERSON_NAME).setLongForm(true));
+                        FLAGS_PERSON_NAME).setOptional(true));
                 kn.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
                         FLAGS_PERSON_NAME));
             }
             kn.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix,
-                    FLAGS_PERSON_NAME).setLongForm(true));
+                    FLAGS_PERSON_NAME).setOptional(true));
 
             // Phonetic name
             final DataKind kp = newDataKind(context, parser, attrs, true,
diff --git a/src/com/android/contacts/list/JoinContactListFragment.java b/src/com/android/contacts/list/JoinContactListFragment.java
index d961f34..d827eb5 100644
--- a/src/com/android/contacts/list/JoinContactListFragment.java
+++ b/src/com/android/contacts/list/JoinContactListFragment.java
@@ -146,7 +146,7 @@
     @Override
     public JoinContactListAdapter createListAdapter() {
         JoinContactListAdapter adapter = new JoinContactListAdapter(getActivity());
-        adapter.setPhotoPosition(ContactListItemView.getDefaultPhotoPosition(true /* opposite */));
+        adapter.setPhotoPosition(ContactListItemView.getDefaultPhotoPosition(false /* opposite */));
         return adapter;
     }
 
diff --git a/src/com/android/contacts/list/MultiSelectEmailAddressesListAdapter.java b/src/com/android/contacts/list/MultiSelectEmailAddressesListAdapter.java
index b225ba4..af9ee52 100644
--- a/src/com/android/contacts/list/MultiSelectEmailAddressesListAdapter.java
+++ b/src/com/android/contacts/list/MultiSelectEmailAddressesListAdapter.java
@@ -160,7 +160,6 @@
         cursor.moveToPosition(position);
 
         bindViewId(view, cursor, EmailQuery.EMAIL_ID);
-        bindSectionHeaderAndDivider(view, position);
         if (isFirstEntry) {
             bindName(view, cursor);
             bindQuickContact(view, partition, cursor, EmailQuery.PHOTO_ID,
@@ -190,16 +189,6 @@
         view.showData(cursor, EmailQuery.EMAIL_ADDRESS);
     }
 
-    protected void bindSectionHeaderAndDivider(final ContactListItemView view, int position) {
-        final int section = getSectionForPosition(position);
-        if (getPositionForSection(section) == position) {
-            final String title = (String)getSections()[section];
-            view.setSectionHeader(title);
-        } else {
-            view.setSectionHeader(null);
-        }
-    }
-
     protected void bindName(final ContactListItemView view, Cursor cursor) {
         view.showDisplayName(cursor, EmailQuery.DISPLAY_NAME, getContactNameDisplayOrder());
     }
diff --git a/src/com/android/contacts/list/MultiSelectEmailAddressesListFragment.java b/src/com/android/contacts/list/MultiSelectEmailAddressesListFragment.java
index d14488a..956e473 100644
--- a/src/com/android/contacts/list/MultiSelectEmailAddressesListFragment.java
+++ b/src/com/android/contacts/list/MultiSelectEmailAddressesListFragment.java
@@ -38,7 +38,7 @@
 
     public MultiSelectEmailAddressesListFragment() {
         setPhotoLoaderEnabled(true);
-        setSectionHeaderDisplayEnabled(true);
+        setSectionHeaderDisplayEnabled(false);
         setSearchMode(false);
         setHasOptionsMenu(true);
         setListType(ListEvent.ListType.PICK_EMAIL);
diff --git a/src/com/android/contacts/list/MultiSelectPhoneNumbersListAdapter.java b/src/com/android/contacts/list/MultiSelectPhoneNumbersListAdapter.java
index b3574ab..985809b 100644
--- a/src/com/android/contacts/list/MultiSelectPhoneNumbersListAdapter.java
+++ b/src/com/android/contacts/list/MultiSelectPhoneNumbersListAdapter.java
@@ -160,7 +160,6 @@
         cursor.moveToPosition(position);
 
         bindViewId(view, cursor, PhoneQuery.PHONE_ID);
-        bindSectionHeaderAndDivider(view, position);
         if (isFirstEntry) {
             bindName(view, cursor);
             bindQuickContact(view, partition, cursor, PhoneQuery.PHOTO_ID,
@@ -190,15 +189,6 @@
         view.showData(cursor, PhoneQuery.PHONE_NUMBER);
     }
 
-    protected void bindSectionHeaderAndDivider(final ContactListItemView view, int position) {
-        if (isSectionHeaderDisplayEnabled()) {
-            Placement placement = getItemPlacementInSection(position);
-            view.setSectionHeader(placement.firstInSection ? placement.sectionHeader : null);
-        } else {
-            view.setSectionHeader(null);
-        }
-    }
-
     protected void bindName(final ContactListItemView view, Cursor cursor) {
         view.showDisplayName(cursor, PhoneQuery.DISPLAY_NAME, getContactNameDisplayOrder());
     }
diff --git a/src/com/android/contacts/list/MultiSelectPhoneNumbersListFragment.java b/src/com/android/contacts/list/MultiSelectPhoneNumbersListFragment.java
index 5a1a761..751449b 100644
--- a/src/com/android/contacts/list/MultiSelectPhoneNumbersListFragment.java
+++ b/src/com/android/contacts/list/MultiSelectPhoneNumbersListFragment.java
@@ -38,7 +38,7 @@
 
     public MultiSelectPhoneNumbersListFragment() {
         setPhotoLoaderEnabled(true);
-        setSectionHeaderDisplayEnabled(true);
+        setSectionHeaderDisplayEnabled(false);
         setSearchMode(false);
         setHasOptionsMenu(true);
         setListType(ListEvent.ListType.PICK_PHONE);