Merge change 26949 into eclair

* changes:
  Fixed the font size in the dialer (increased the size).
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f4e3465..d0c77b2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -480,34 +480,38 @@
 
 
     <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is disabled -->
-    <string name="noContactsHelpText">"You don't have any contacts.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+    <string name="noContactsHelpText">"You don't have any contacts to display.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or configure an account with contacts you can sync to the phone\n</li>
         \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
         \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font>\n</li>"
     </string>
 
     <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is enabled -->
-    <string name="noContactsHelpTextWithSync">"You don't have any contacts.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
-        \n<li><font fgcolor="#ffffffff"><b>Display groups</b></font> to change which contact groups are visible\n</li>
+    <string name="noContactsHelpTextWithSync">"You don't have any contacts to display. (If you just added an account, it can take a few minutes to sync contacts.)\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or configure an account with contacts you can sync to the phone\n</li>
+        \n<li><font fgcolor="#ffffffff"><b>Display groups</b></font> to change which groups of contacts are visible\n</li>
         \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
         \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font>\n</li>"
     </string>
 
     <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is disabled, and there is no sim card (cdma)-->
-    <string name="noContactsNoSimHelpText">"You don't have any contacts.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+    <string name="noContactsNoSimHelpText">"You don't have any contacts to display.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or configure an account with contacts you can sync to the phone\n</li>
         \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
         \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font>\n</li>"
     </string>
 
     <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is enabled, and there is no sim card (cdma) -->
-    <string name="noContactsNoSimHelpTextWithSync">"You don't have any contacts.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
-        \n<li><font fgcolor="#ffffffff"><b>Display groups</b></font> to change which contact groups are visible\n</li>
+    <string name="noContactsNoSimHelpTextWithSync">"You don't have any contacts to display. (If you just added an account, it can take a few minutes to sync contacts.)\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or configure an account with contacts you can sync to the phone\n</li>
+        \n<li><font fgcolor="#ffffffff"><b>Display groups</b></font> to change which groups of contacts are visible\n</li>
         \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
         \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font>\n</li>"
     </string>
 
     <!-- Displayed full screen when the user has no favorites and they are displaying the favorites tab -->
     <string name="noFavoritesHelpText">"You don't have any favorites.\n\nTo add a contact to your list of favorites:\n
-        <li>Touch the Contacts tab\n</li>
+        <li>Touch the <b>Contacts</b> tab\n</li>
         \n<li>Touch the contact you want to add to your favorites\n</li>
         \n<li>Touch the star next to the contact\'s name\n</li>"
     </string>
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index d5f6857..5d5a944 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -17,13 +17,11 @@
 package com.android.contacts;
 
 import com.android.contacts.model.ContactsSource;
+import com.android.contacts.model.GoogleSource;
 import com.android.contacts.model.Sources;
-import com.android.contacts.model.ContactsSource.DataKind;
-import com.android.contacts.model.ContactsSource.EditType;
 import com.android.contacts.ui.DisplayGroupsActivity;
 import com.android.contacts.ui.DisplayGroupsActivity.Prefs;
 import com.android.contacts.util.Constants;
-import com.google.android.collect.Lists;
 
 import android.accounts.Account;
 import android.app.Activity;
@@ -64,7 +62,6 @@
 import android.provider.Contacts.People;
 import android.provider.Contacts.PeopleColumns;
 import android.provider.Contacts.Phones;
-import android.provider.ContactsContract.CommonDataKinds;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Intents;
@@ -80,7 +77,6 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.SparseArray;
 import android.view.ContextMenu;
 import android.view.ContextThemeWrapper;
 import android.view.Gravity;
@@ -305,6 +301,15 @@
 
     static final String KEY_PICKER_MODE = "picker_mode";
 
+    /*
+     * TODO: Will be commented in the really near future. Similar commented out codes will be done.
+     *       These are for make vCard exporter code understard two additional options:
+     *       "export contacts in the phone only" and
+     *       "export all contacts without caring Account information".
+     * static final Account sExportPhoneLocalAccount;
+     * static final Account sExportAllAccount;
+     */
+
     private ContactItemListAdapter mAdapter;
 
     int mMode = MODE_DEFAULT;
@@ -353,10 +358,12 @@
 
     // Uri matcher for contact id
     private static final int CONTACTS_ID = 1001;
-    private static final UriMatcher CONTACTS_ID_MATCHER;
+    private static final UriMatcher sContactsIdMatcher;
     static {
-        CONTACTS_ID_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
-        CONTACTS_ID_MATCHER.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);
+        sContactsIdMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+        sContactsIdMatcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);
+        /*sExportPhoneLocalAccount = new Account("Phone-local Account", "phone-local");
+        sExportAllAccount = new Account("All account", "all");*/
     }
 
     private class DeleteClickListener implements DialogInterface.OnClickListener {
@@ -497,7 +504,7 @@
         } else if (Intents.SEARCH_SUGGESTION_CLICKED.equals(action)) {
             Uri data = intent.getData();
             Uri telUri = null;
-            if (CONTACTS_ID_MATCHER.match(data) == CONTACTS_ID) {
+            if (sContactsIdMatcher.match(data) == CONTACTS_ID) {
                 long contactId = Long.valueOf(data.getLastPathSegment());
                 final Cursor cursor = queryPhoneNumbers(contactId);
                 if (cursor != null) {
@@ -827,7 +834,8 @@
                 return createImportExportDialog();
             }
             case R.string.import_from_sim:
-            case R.string.import_from_sdcard: {
+            case R.string.import_from_sdcard:
+            case R.string.export_to_sdcard: {
                 return createSelectAccountDialog(id);
             }
             case R.string.fail_reason_too_many_vcard: {
@@ -866,8 +874,7 @@
 
         public AccountSelectedListener(List<Account> accountList, int resId) {
             if (accountList == null || accountList.size() == 0) {
-                // TODO: Add all the contacts into phone-local account.
-                Log.e(TAG, "The size of Account list is 0");
+                Log.e(TAG, "The size of Account list is 0.");
             }
             mAccountList = accountList;
             mResId = resId;
@@ -884,6 +891,8 @@
                     doImportFromSdCard(mAccountList.get(which));
                     break;
                 }
+                /*case R.string.export_to_sdcard: {
+                }*/
             }
         }
 
@@ -893,10 +902,18 @@
     }
 
     private Dialog createSelectAccountDialog(int resId) {
-        // A lot of codes are copied from EditContactActivity.
-        // TODO: Can we share the logic?
+        final boolean isExport = (resId == R.string.export_to_sdcard);
+        final boolean displayWritableOnly = !isExport;
+
         final Sources sources = Sources.getInstance(this);
-        final List<Account> accountList = sources.getAccounts(true);
+        final List<Account> accountList = sources.getAccounts(displayWritableOnly);
+
+        /*if (isExport) {
+            accountList.add(sExportPhoneLocalAccount);
+            accountList.add(sExportAllAccount);
+        }*/
+
+        // Assume accountList.size() > 1
 
         // Wrap our context to inflate list items using correct theme
         final Context dialogContext = new ContextThemeWrapper(
@@ -987,13 +1004,18 @@
                 switch (resId) {
                     case R.string.import_from_sim:
                     case R.string.import_from_sdcard: {
-                        showDialog(resId);
+                        handleImportExportRequest(resId);
                         break;
                     }
                     case R.string.export_to_sdcard: {
+                        // TODO: use handleImportExportRequest()
                         doExportToSdCard();
                         break;
                     }
+                    default: {
+                        Log.e(TAG, "Unexpected resource: " +
+                                getResources().getResourceEntryName(resId));
+                    }
                 }
             }
         };
@@ -1005,19 +1027,73 @@
         return builder.create();
     }
 
+    private void handleImportExportRequest(int resId) {
+        /*final boolean isExport = (resId == R.string.export_to_sdcard);
+        if (isExport) {
+            // We're sure there are at least two Account ("phone-local" and "all").
+            // Go to account selection every time.
+            showDialog(R.string.export_to_sdcard);
+            return;
+        }*/
+
+        // As for import, there's three possibilities
+        // - more than one accounts -> ask the user
+        // - just one account -> use the account without asking the user
+        // - no account -> use phone-local storage without asking the user
+
+        final Sources sources = Sources.getInstance(this);
+        final List<Account> accountList = sources.getAccounts(true);
+        final int size = accountList.size();
+        Account account;
+        if (size > 1) {
+            showDialog(resId);
+            return;
+        } else if (size == 1) {
+            account = accountList.get(0);
+        } else {
+            account = null;
+        }
+        switch (resId) {
+            case R.string.import_from_sim: {
+                doImportFromSim(account);
+                break;
+            }
+            case R.string.import_from_sdcard: {
+                doImportFromSdCard(account);
+                break;
+            }
+            /*case R.string.export_to_sdcard: {
+                doExportToSdCard(account);
+                break;
+            }*/
+        }
+    }
+
     private void doImportFromSim(Account account) {
+        if (account != null) {
+            GoogleSource.createMyContactsIfNotExist(account, this);
+        }
+
         Intent importIntent = new Intent(Intent.ACTION_VIEW);
         importIntent.setType("vnd.android.cursor.item/sim-contact");
-        importIntent.putExtra("account_name", account.name);
-        importIntent.putExtra("account_type", account.type);
+        if (account != null) {
+            importIntent.putExtra("account_name", account.name);
+            importIntent.putExtra("account_type", account.type);
+        }
         importIntent.setClassName("com.android.phone", "com.android.phone.SimContacts");
         startActivity(importIntent);
     }
 
     private void doImportFromSdCard(Account account) {
+        if (account != null) {
+            GoogleSource.createMyContactsIfNotExist(account, this);
+        }
+
         Intent importIntent = new Intent(this, ImportVCardActivity.class);
-        importIntent.putExtra("account_name", account.name);
-        importIntent.putExtra("account_type", account.type);
+        if (account != null) {
+            importIntent.putExtra("account_name", account.name);
+            importIntent.putExtra("account_type", account.type);
+        }
         startActivity(importIntent);
     }
 
@@ -2248,7 +2324,9 @@
             cache.dataView = (TextView) view.findViewById(R.id.data);
             cache.presenceView = (ImageView) view.findViewById(R.id.presence);
             cache.photoView = (FasttrackBadgeWidget) view.findViewById(R.id.photo);
-            cache.photoView.setExcludeMimes(new String[] {Contacts.CONTENT_ITEM_TYPE});
+            if (cache.photoView != null) {
+                cache.photoView.setExcludeMimes(new String[] {Contacts.CONTENT_ITEM_TYPE});
+            }
             cache.nonFastTrackPhotoView = (ImageView) view.findViewById(R.id.noFastTrackphoto);
             view.setTag(cache);
 
diff --git a/src/com/android/contacts/model/GoogleSource.java b/src/com/android/contacts/model/GoogleSource.java
index 46d0623..9968ace 100644
--- a/src/com/android/contacts/model/GoogleSource.java
+++ b/src/com/android/contacts/model/GoogleSource.java
@@ -20,6 +20,7 @@
 import com.android.contacts.model.EntityDelta.ValuesDelta;
 import com.google.android.collect.Lists;
 
+import android.accounts.Account;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentResolver;
@@ -153,10 +154,19 @@
     }
 
     // TODO: this should come from resource in the future
+    // Note that frameworks/base/core/java/android/pim/vcard/ContactStruct.java also wants
+    // this String.
     private static final String GOOGLE_MY_CONTACTS_GROUP = "System Group: My Contacts";
 
     public static final void attemptMyContactsMembership(EntityDelta state, Context context) {
-        attemptMyContactsMembership(state, context, true);
+        final ValuesDelta stateValues = state.getValues();
+        final String accountName = stateValues.getAsString(RawContacts.ACCOUNT_NAME);
+        final String accountType = stateValues.getAsString(RawContacts.ACCOUNT_TYPE);
+        attemptMyContactsMembership(state, accountName, accountType, context, true);
+    }
+
+    public static final void createMyContactsIfNotExist(Account account, Context context) {
+        attemptMyContactsMembership(null, account.name, account.type, context, true);
     }
 
     /**
@@ -165,12 +175,10 @@
      *     to prevent excess recursion, we provide a flag to make sure we only do the recursion loop
      *     once
      */
-    private static final void attemptMyContactsMembership(EntityDelta state, Context context,
-            boolean allowRecur) {
+    private static final void attemptMyContactsMembership(EntityDelta state,
+                final String accountName, final String accountType, Context context,
+                boolean allowRecur) {
         final ContentResolver resolver = context.getContentResolver();
-        final ValuesDelta stateValues = state.getValues();
-        final String accountName = stateValues.getAsString(RawContacts.ACCOUNT_NAME);
-        final String accountType = stateValues.getAsString(RawContacts.ACCOUNT_TYPE);
 
         Cursor cursor = resolver.query(Groups.CONTENT_URI,
                 new String[] {Groups.TITLE, Groups.SOURCE_ID, Groups.SHOULD_SYNC},
@@ -192,6 +200,10 @@
             }
         }
 
+        if (myContactsExists && state == null) {
+            return;
+        }
+
         try {
             final ContentValues values = new ContentValues();
             values.put(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
@@ -227,7 +239,8 @@
                 } catch (OperationApplicationException e) {
                     // the group was created after the query but before we tried to create it
                     if (allowRecur) {
-                        attemptMyContactsMembership(state, context, false);
+                        attemptMyContactsMembership(
+                                state, accountName, accountType, context, false);
                     }
                     return;
                 }
@@ -239,7 +252,9 @@
                     // TODO: alert user that their contact will be dropped?
                 }
             }
-            state.addEntry(ValuesDelta.fromAfter(values));
+            if (state != null) {
+                state.addEntry(ValuesDelta.fromAfter(values));
+            }
         } finally {
             cursor.close();
         }
diff --git a/src/com/android/contacts/ui/DisplayGroupsActivity.java b/src/com/android/contacts/ui/DisplayGroupsActivity.java
index ab6f651..69f0007 100644
--- a/src/com/android/contacts/ui/DisplayGroupsActivity.java
+++ b/src/com/android/contacts/ui/DisplayGroupsActivity.java
@@ -17,6 +17,7 @@
 package com.android.contacts.ui;
 
 import com.android.contacts.R;
+import com.android.contacts.model.GoogleSource;
 import com.android.contacts.model.ContactsSource;
 import com.android.contacts.model.Sources;
 import com.android.contacts.util.EmptyService;
@@ -305,14 +306,18 @@
         final int childPosition = ExpandableListView.getPackedPositionChild(info.packedPosition);
 
         final Cursor groupCursor = mAdapter.getGroup(groupPosition);
+        final String accountName = groupCursor.getString(SettingsQuery.ACCOUNT_NAME);
+        final String accountType = groupCursor.getString(SettingsQuery.ACCOUNT_TYPE);
+
         // TODO: read sync mode through <sync-adapter> definition
-        final int syncMode = SYNC_MODE_EVERYTHING;
+        int syncMode = SYNC_MODE_UNSUPPORTED;
+	if (accountType.equals(GoogleSource.ACCOUNT_TYPE)) {
+	    syncMode = SYNC_MODE_EVERYTHING;
+	}
 
         // Ignore when selective syncing unsupported
         if (syncMode == SYNC_MODE_UNSUPPORTED) return;
 
-        final String accountName = groupCursor.getString(SettingsQuery.ACCOUNT_NAME);
-        final String accountType = groupCursor.getString(SettingsQuery.ACCOUNT_TYPE);
         final Account account = new Account(accountName, accountType);
 
         final boolean shouldSyncUngrouped = groupCursor.getInt(SettingsQuery.SHOULD_SYNC) != 0;