Merge "Import translations. DO NOT MERGE" into ub-contactsdialer-master-dev
diff --git a/res/layout/fragment_sim_import.xml b/res/layout/fragment_sim_import.xml
index 9e2f493..6b8c3fe 100644
--- a/res/layout/fragment_sim_import.xml
+++ b/res/layout/fragment_sim_import.xml
@@ -26,6 +26,7 @@
         android:background="?attr/colorPrimary"
         android:elevation="4dp"
         android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
+        app:navigationContentDescription="@string/sim_import_cancel_content_description"
         app:navigationIcon="@drawable/ic_close_dk"
         app:title="@string/sim_import_title_none_selected">
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7b5ce0d..c80c53c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1814,4 +1814,11 @@
 
     <!-- Error message displayed to user when they started the app, but could not sign in to Google's servers. [CHAR LIMIT=50]-->
     <string name="connection_failed">Failed to sign in</string>
+    <!-- Title of SIM import dialog for accessibility; this isn't displayed but is announced
+     by talkback when the window is shown -->
+    <string name="sim_import_dialog_title">Select contacts to import</string>
+
+    <!-- Content description of the cancel navigation icon shown in SIM import dialog toolbar -->
+    <string name="sim_import_cancel_content_description">Cancel import</string>
+
 </resources>
diff --git a/src/com/android/contacts/SimImportFragment.java b/src/com/android/contacts/SimImportFragment.java
index a9dcf97..7421df4 100644
--- a/src/com/android/contacts/SimImportFragment.java
+++ b/src/com/android/contacts/SimImportFragment.java
@@ -15,6 +15,7 @@
  */
 package com.android.contacts;
 
+import android.app.Dialog;
 import android.app.DialogFragment;
 import android.app.LoaderManager;
 import android.content.AsyncTaskLoader;
@@ -74,7 +75,7 @@
     @Override
     public void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setStyle(STYLE_NO_TITLE, R.style.PeopleThemeAppCompat_FullScreenDialog);
+        setStyle(STYLE_NORMAL, R.style.PeopleThemeAppCompat_FullScreenDialog);
         mPreferences = new ContactsPreferences(getContext());
         mAccountTypeManager = AccountTypeManager.getInstance(getActivity());
         mAdapter = new SimContactAdapter(getActivity());
@@ -89,6 +90,15 @@
     }
 
     @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Dialog dialog = super.onCreateDialog(savedInstanceState);
+        // Set the title for accessibility. It isn't displayed but will get announced when the
+        // window is shown
+        dialog.setTitle(R.string.sim_import_dialog_title);
+        return dialog;
+    }
+
+    @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
         getLoaderManager().initLoader(0, null, this);
@@ -248,6 +258,11 @@
             ContactListItemView contactView = (ContactListItemView) itemView;
             bindNameAndViewId(contactView, cursor);
             bindPhoto(contactView, partition, cursor);
+
+            // For accessibility. Tapping the item checks this so we don't need it to be separately
+            // clickable
+            contactView.getCheckBox().setFocusable(false);
+            contactView.getCheckBox().setClickable(false);
         }
 
         public void setContacts(ArrayList<SimContact> contacts) {
diff --git a/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java b/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java
index a0db4c5..7396bbd 100644
--- a/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java
@@ -38,6 +38,7 @@
     private Uri mUri;
     private Cursor mCursor;
     private MaterialPalette mMaterialPalette;
+    private boolean mIsUserProfile;
 
     /**
      * The contact data loader listener.
@@ -59,6 +60,7 @@
                         return;
                     }
                     mCursor = cursor;
+                    mIsUserProfile = ((PickRawContactLoader) loader).isUserProfile();
                     if (mCursor.getCount() == 1) {
                         loadEditor();
                     } else {
@@ -128,8 +130,8 @@
         if (oldFragment != null) {
             ft.remove(oldFragment);
         }
-        final PickRawContactDialogFragment newFragment =
-                PickRawContactDialogFragment.getInstance(mUri, mCursor, mMaterialPalette);
+        final PickRawContactDialogFragment newFragment = PickRawContactDialogFragment.getInstance(
+                mUri, mCursor, mMaterialPalette, mIsUserProfile);
         ft.add(newFragment, TAG_RAW_CONTACTS_DIALOG);
         // commitAllowingStateLoss is safe in this activity because the fragment entirely depends
         // on the result of the loader. Even if we lose the fragment because the activity was
diff --git a/src/com/android/contacts/common/preference/ContactsPreferences.java b/src/com/android/contacts/common/preference/ContactsPreferences.java
index 085b385..4fa2dcc 100644
--- a/src/com/android/contacts/common/preference/ContactsPreferences.java
+++ b/src/com/android/contacts/common/preference/ContactsPreferences.java
@@ -435,4 +435,5 @@
             }
         }
     }
+
 }
diff --git a/src/com/android/contacts/editor/PickRawContactDialogFragment.java b/src/com/android/contacts/editor/PickRawContactDialogFragment.java
index b9800de..0f87d99 100644
--- a/src/com/android/contacts/editor/PickRawContactDialogFragment.java
+++ b/src/com/android/contacts/editor/PickRawContactDialogFragment.java
@@ -11,6 +11,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.ContactsContract.RawContacts;
+import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -21,7 +22,11 @@
 import com.android.contacts.R;
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.account.AccountDisplayInfo;
+import com.android.contacts.common.model.account.AccountDisplayInfoFactory;
 import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.model.account.GoogleAccountType;
 import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.contacts.common.util.ImplicitIntentsUtil;
 import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
@@ -34,14 +39,20 @@
     /**
      * Used to list the account info for the given raw contacts list.
      */
-    private static final class RawContactAccountListAdapter extends CursorAdapter {
+    private final class RawContactAccountListAdapter extends CursorAdapter {
         private final LayoutInflater mInflater;
         private final Context mContext;
+        private final AccountDisplayInfoFactory mAccountDisplayInfoFactory;
+        private final AccountTypeManager mAccountTypeManager;
+        private final ContactsPreferences mPreferences;
 
         public RawContactAccountListAdapter(Context context, Cursor cursor) {
             super(context, cursor, 0);
             mContext = context;
             mInflater = LayoutInflater.from(context);
+            mAccountDisplayInfoFactory = AccountDisplayInfoFactory.forWritableAccounts(context);
+            mAccountTypeManager = AccountTypeManager.getInstance(context);
+            mPreferences = new ContactsPreferences(context);
         }
 
         @Override
@@ -50,22 +61,18 @@
             final String accountName = cursor.getString(PickRawContactLoader.ACCOUNT_NAME);
             final String accountType = cursor.getString(PickRawContactLoader.ACCOUNT_TYPE);
             final String dataSet = cursor.getString(PickRawContactLoader.DATA_SET);
-            final AccountType account = AccountTypeManager.getInstance(mContext)
-                    .getAccountType(accountType, dataSet);
+            final AccountType account = mAccountTypeManager.getAccountType(accountType, dataSet);
 
-            final ContactsPreferences prefs = new ContactsPreferences(mContext);
             final int displayNameColumn =
-                    prefs.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY
+                    mPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY
                             ? PickRawContactLoader.DISPLAY_NAME_PRIMARY
                             : PickRawContactLoader.DISPLAY_NAME_ALTERNATIVE;
+
             String displayName = cursor.getString(displayNameColumn);
 
-            final TextView nameView = (TextView) view.findViewById(
-                    R.id.display_name);
-            final TextView accountTextView = (TextView) view.findViewById(
-                    R.id.account_name);
-            final ImageView accountIconView = (ImageView) view.findViewById(
-                    R.id.account_icon);
+            if (TextUtils.isEmpty(displayName)) {
+                displayName = mContext.getString(R.string.missing_name);
+            }
 
             if (!account.areContactsWritable()) {
                 displayName = mContext
@@ -74,19 +81,42 @@
             } else {
                 view.setAlpha(1f);
             }
-
+            final TextView nameView = (TextView) view.findViewById(
+                    R.id.display_name);
             nameView.setText(displayName);
-            accountTextView.setText(accountName);
+
+            final String accountDisplayLabel;
+
+            // Use the same string as editor if it's an editable user profile raw contact.
+            if (mIsUserProfile && account.areContactsWritable()) {
+                final AccountDisplayInfo displayInfo =
+                        mAccountDisplayInfoFactory.getAccountDisplayInfo(
+                                new AccountWithDataSet(accountName, accountType, dataSet));
+                accountDisplayLabel = EditorUiUtils.getAccountHeaderLabelForMyProfile(mContext,
+                        displayInfo);
+            }
+            else if (GoogleAccountType.ACCOUNT_TYPE.equals(accountType)
+                    && account.dataSet == null) {
+                // Focus Google accounts have the account name shown
+                accountDisplayLabel = accountName;
+            } else {
+                accountDisplayLabel = account.getDisplayLabel(mContext).toString();
+            }
+            final TextView accountTextView = (TextView) view.findViewById(
+                    R.id.account_name);
+            final ImageView accountIconView = (ImageView) view.findViewById(
+                    R.id.account_icon);
+            accountTextView.setText(accountDisplayLabel);
             accountIconView.setImageDrawable(account.getDisplayIcon(mContext));
 
             final ContactPhotoManager.DefaultImageRequest
                     request = new ContactPhotoManager.DefaultImageRequest(
                     displayName, String.valueOf(rawContactId), /* isCircular = */ true);
-            final ImageView photoView = (ImageView) view.findViewById(
-                    R.id.photo);
             final Uri photoUri = Uri.withAppendedPath(
                     ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
                     RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
+            final ImageView photoView = (ImageView) view.findViewById(
+                    R.id.photo);
             ContactPhotoManager.getInstance(mContext).loadDirectoryPhoto(photoView,
                     photoUri,
                     /* darkTheme = */ false,
@@ -112,13 +142,15 @@
     private Uri mUri;
     private CursorAdapter mAdapter;
     private MaterialPalette mMaterialPalette;
+    private boolean mIsUserProfile;
 
     public static PickRawContactDialogFragment getInstance(Uri uri, Cursor cursor,
-            MaterialPalette materialPalette) {
+            MaterialPalette materialPalette, boolean isUserProfile) {
         final PickRawContactDialogFragment fragment = new PickRawContactDialogFragment();
         fragment.setUri(uri);
         fragment.setCursor(cursor);
         fragment.setMaterialPalette(materialPalette);
+        fragment.setIsUserProfile(isUserProfile);
         return fragment;
     }
 
@@ -163,6 +195,10 @@
         mMaterialPalette = materialPalette;
     }
 
+    private void setIsUserProfile(boolean isUserProfile) {
+        mIsUserProfile = isUserProfile;
+    }
+
     private void finishActivity() {
         if (getActivity() != null && !getActivity().isFinishing()) {
             getActivity().finish();
diff --git a/src/com/android/contacts/editor/PickRawContactLoader.java b/src/com/android/contacts/editor/PickRawContactLoader.java
index 62be517..ca44e21 100644
--- a/src/com/android/contacts/editor/PickRawContactLoader.java
+++ b/src/com/android/contacts/editor/PickRawContactLoader.java
@@ -4,6 +4,7 @@
 import android.content.CursorLoader;
 import android.database.Cursor;
 import android.net.Uri;
+import android.provider.ContactsContract;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.RawContacts;
 
@@ -13,6 +14,7 @@
  */
 public class PickRawContactLoader extends CursorLoader {
     private Uri mContactUri;
+    private boolean mIsUserProfile;
 
     public static final String[] COLUMNS = new String[] {
             RawContacts.ACCOUNT_NAME,
@@ -41,7 +43,7 @@
     public Cursor loadInBackground() {
         // Get the id of the contact we're looking at.
         final Cursor cursor = getContext().getContentResolver()
-                .query(mContactUri, new String[] { Contacts._ID }, null,
+                .query(mContactUri, new String[] { Contacts._ID, Contacts.IS_USER_PROFILE }, null,
                 null, null);
 
         if (cursor == null) {
@@ -54,14 +56,24 @@
         }
 
         cursor.moveToFirst();
-        final long contactId = cursor.getLong(0);
+        final long contactId = cursor.getLong(/* Contacts._ID */ 0);
+        mIsUserProfile = cursor.getInt(/* Contacts.IS_USER_PROFILE */ 1) == 1;
+
         cursor.close();
         // Update selection arguments and uri.
         setSelectionArgs(new String[]{ Long.toString(contactId) });
-        setUri(RawContacts.CONTENT_URI);
+        if (mIsUserProfile) {
+            setUri(ContactsContract.Profile.CONTENT_RAW_CONTACTS_URI);
+        } else {
+            setUri(RawContacts.CONTENT_URI);
+        }
         return super.loadInBackground();
     }
 
+    public boolean isUserProfile() {
+        return mIsUserProfile;
+    }
+
     /**
      * Ensures that this is a valid contact URI. If invalid, then an exception is
      * thrown. Otherwise, the original URI is returned.
diff --git a/tests/src/com/android/contacts/RunMethodInstrumentation.java b/tests/src/com/android/contacts/RunMethodInstrumentation.java
index 77f36ed..11516b8 100644
--- a/tests/src/com/android/contacts/RunMethodInstrumentation.java
+++ b/tests/src/com/android/contacts/RunMethodInstrumentation.java
@@ -60,6 +60,7 @@
         start();
     }
 
+    @Override
     public void onStart() {
         Log.d(TAG, "onStart");
         super.onStart();
diff --git a/tests/src/com/android/contacts/common/database/SimContactDaoTests.java b/tests/src/com/android/contacts/common/database/SimContactDaoTests.java
index 5b25eb2..513f551 100644
--- a/tests/src/com/android/contacts/common/database/SimContactDaoTests.java
+++ b/tests/src/com/android/contacts/common/database/SimContactDaoTests.java
@@ -26,6 +26,7 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.Suppress;
 import android.support.test.runner.AndroidJUnit4;
 
 import com.android.contacts.common.model.SimContact;
@@ -49,8 +50,6 @@
 import static org.hamcrest.Matchers.allOf;
 import static org.junit.Assert.assertThat;
 
-import android.support.test.filters.Suppress;
-
 @RunWith(Enclosed.class)
 public class SimContactDaoTests {
 
diff --git a/tests/src/com/android/contacts/common/test/mocks/MockContentProvider.java b/tests/src/com/android/contacts/common/test/mocks/MockContentProvider.java
index 336467d..d3950fc 100644
--- a/tests/src/com/android/contacts/common/test/mocks/MockContentProvider.java
+++ b/tests/src/com/android/contacts/common/test/mocks/MockContentProvider.java
@@ -165,7 +165,7 @@
         public Cursor getResult(String[] projection) {
             String[] columnNames;
             if (mAnyProjection) {
-                columnNames = projection;
+                columnNames = projection != null ? projection : mDefaultProjection;
             } else {
                 columnNames = mProjection != null ? mProjection : mDefaultProjection;
             }
@@ -176,9 +176,9 @@
                     cursor.addRow((Object[]) row);
                 } else {
                     ContentValues values = (ContentValues) row;
-                    Object[] columns = new Object[projection.length];
-                    for (int i = 0; i < projection.length; i++) {
-                        columns[i] = values.get(projection[i]);
+                    Object[] columns = new Object[columnNames.length];
+                    for (int i = 0; i < columnNames.length; i++) {
+                        columns[i] = values.get(columnNames[i]);
                     }
                     cursor.addRow(columns);
                 }
@@ -485,6 +485,10 @@
         return expect(new Query(contentUri));
     }
 
+    public Query expectQuery(String contentUri) {
+        return expectQuery(Uri.parse(contentUri));
+    }
+
     public void expectTypeQuery(Uri uri, String type) {
         mExpectedTypeQueries.put(uri, type);
     }
diff --git a/tests/src/com/android/contacts/tests/AccountsTestHelper.java b/tests/src/com/android/contacts/tests/AccountsTestHelper.java
index 11476b3..c25c3b4 100644
--- a/tests/src/com/android/contacts/tests/AccountsTestHelper.java
+++ b/tests/src/com/android/contacts/tests/AccountsTestHelper.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 
 import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.preference.ContactsPreferences;
 
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertTrue;
@@ -38,8 +39,6 @@
 
     public static final String TEST_ACCOUNT_TYPE = "com.android.contacts.tests.testauth.basic";
 
-    public static final String EXTRA_ACCOUNT_NAME = "accountName";
-
     private final Context mContext;
     private final AccountManager mAccountManager;
     private final ContentResolver mResolver;
@@ -117,9 +116,9 @@
      *   -w com.google.android.contacts.tests/com.android.contacts.RunMethodInstrumentation
      */
     public static void addTestAccount(Context context, Bundle args) {
-        final String accountName = args.getString(EXTRA_ACCOUNT_NAME);
+        final String accountName = args.getString("name");
         if (accountName == null) {
-            Log.e(TAG, "args must contain extra " + EXTRA_ACCOUNT_NAME);
+            Log.e(TAG, "args must contain extra \"name\"");
             return;
         }
 
@@ -128,13 +127,31 @@
 
     @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
     public static void removeTestAccount(Context context, Bundle args) {
-        final String accountName = args.getString(EXTRA_ACCOUNT_NAME);
+        final String accountName = args.getString("name");
         if (accountName == null) {
-            Log.e(TAG, "args must contain extra " + EXTRA_ACCOUNT_NAME);
+            Log.e(TAG, "args must contain extra \"name\"");
             return;
         }
 
-        AccountWithDataSet account = new AccountWithDataSet(accountName, TEST_ACCOUNT_TYPE, null);
+        final AccountWithDataSet account = new AccountWithDataSet(accountName, TEST_ACCOUNT_TYPE,
+                null);
         new AccountsTestHelper(context).removeTestAccount(account);
     }
+
+    public static void setDefaultAccount(Context context, Bundle args) {
+        final String name = args.getString("name");
+        final String type = args.getString("type");
+
+        if (name == null || type == null) {
+            Log.e(TAG, "args must contain extras \"name\" and \"type\"");
+            return;
+        }
+
+        new ContactsPreferences(context).setDefaultAccount(
+                new AccountWithDataSet(name, type, null));
+    }
+
+    public static void clearDefaultAccount(Context context) {
+        new ContactsPreferences(context).clearDefaultAccount();
+    }
 }