Merge change 26710 into eclair

* changes:
  Delay the type value change until the custom value is correct.
diff --git a/res/values/config.xml b/res/values/config.xml
index 81c3d67..93d19e9 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -35,14 +35,12 @@
     <bool name="config_allow_export_to_sdcard">true</bool>
 
     <!-- If true, enable vibration (haptic feedback) for dialer key presses.
+         The pattern is set on a per-platform basis using config_virtualKeyVibePattern.
          TODO: If enough users are annoyed by this, we might eventually
          need to make it a user preference rather than a per-platform
          resource. -->
     <bool name="config_enable_dialer_key_vibration">true</bool>
 
-    <!-- How long to vibrate (in msec), if dialer key vibration is enabled. -->
-    <integer name="config_dialer_key_vibrate_duration">40</integer>
-
     <!-- The type of vcard for improt. If the vcard importer cannot guess the exact type
     of a vCard type, the improter uses this type. -->
     <string name="config_import_vcard_type" translatable="false">default</string>
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index 79af879..fef9bb5 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -1719,7 +1719,7 @@
             case MODE_JOIN_CONTACT:
                 mQueryHandler.setLoadingJoinSuggestions(true);
                 mQueryHandler.startQuery(QUERY_TOKEN, null, getJoinSuggestionsUri(null), projection,
-                        null, null, null);
+                        Contacts._ID + " != " + mQueryAggregateId, null, null);
                 break;
         }
     }
@@ -1795,7 +1795,8 @@
                         null, null);
                 mAdapter.setSuggestionsCursor(cursor);
                 return resolver.query(getContactFilterUri(filter), projection,
-                        getContactSelection(), null, getSortOrder(projection));
+                        Contacts._ID + " != " + mQueryAggregateId, null,
+                        getSortOrder(projection));
             }
         }
         throw new UnsupportedOperationException("filtering not allowed in mode " + mMode);
diff --git a/src/com/android/contacts/TwelveKeyDialer.java b/src/com/android/contacts/TwelveKeyDialer.java
index bdc6b6f..d07d785 100644
--- a/src/com/android/contacts/TwelveKeyDialer.java
+++ b/src/com/android/contacts/TwelveKeyDialer.java
@@ -82,6 +82,9 @@
     /** The DTMF tone volume relative to other sounds in the stream */
     private static final int TONE_RELATIVE_VOLUME = 50;
 
+    /** Play the vibrate pattern only once. */
+    private static final int VIBRATE_NO_REPEAT = -1;
+
     private EditText mDigits;
     private View mDelete;
     private MenuItem mAddToContactMenuItem;
@@ -108,7 +111,7 @@
     // Vibration (haptic feedback) for dialer key presses.
     private Vibrator mVibrator;
     private boolean mVibrateOn;
-    private long mVibrateDuration;
+    private long[] mVibratePattern;
 
 
     /** Identifier for the "Add Call" intent extra. */
@@ -218,12 +221,10 @@
             super.onRestoreInstanceState(icicle);
         }
 
-        // Initialize vibration parameters.
         // TODO: We might eventually need to make mVibrateOn come from a
         // user preference rather than a per-platform resource, in which
         // case we would need to update it in onResume() rather than here.
-        mVibrateOn = r.getBoolean(R.bool.config_enable_dialer_key_vibration);
-        mVibrateDuration = (long) r.getInteger(R.integer.config_dialer_key_vibrate_duration);
+        initVibrationPattern(r);
     }
 
     @Override
@@ -984,7 +985,7 @@
         if (mVibrator == null) {
             mVibrator = new Vibrator();
         }
-        mVibrator.vibrate(mVibrateDuration);
+        mVibrator.vibrate(mVibratePattern, VIBRATE_NO_REPEAT);
     }
 
     /**
@@ -1067,6 +1068,35 @@
     }
 
     /**
+     * Initialize the vibration parameters.
+     * @param r The Resources with the vibration parameters.
+     */
+    private void initVibrationPattern(Resources r) {
+        int[] pattern = null;
+        try {
+            mVibrateOn = r.getBoolean(R.bool.config_enable_dialer_key_vibration);
+            pattern = r.getIntArray(com.android.internal.R.array.config_virtualKeyVibePattern);
+            if (null == pattern) {
+                Log.e(TAG, "Vibrate pattern is null.");
+                mVibrateOn = false;
+            }
+        } catch (Resources.NotFoundException nfe) {
+            Log.e(TAG, "Vibrate control bool or pattern missing.", nfe);
+            mVibrateOn = false;
+        }
+
+        if (!mVibrateOn) {
+            return;
+        }
+
+        // int[] to long[] conversion.
+        mVibratePattern = new long[pattern.length];
+        for (int i = 0; i < pattern.length; i++) {
+            mVibratePattern[i] = pattern[i];
+        }
+    }
+
+    /**
      * This function return true if Wait menu item can be shown
      * otherwise returns false. Assumes the passed string is non-empty
      * and the 0th index check is not required.
diff --git a/src/com/android/contacts/ViewContactActivity.java b/src/com/android/contacts/ViewContactActivity.java
index 70c1867..9b22b4b 100644
--- a/src/com/android/contacts/ViewContactActivity.java
+++ b/src/com/android/contacts/ViewContactActivity.java
@@ -862,6 +862,11 @@
                 final String accountType = entValues.getAsString(RawContacts.ACCOUNT_TYPE);
                 final long rawContactId = entValues.getAsLong(RawContacts._ID);
 
+                if (!mRawContactIds.contains(rawContactId)) {
+                    mRawContactIds.add(rawContactId);
+                }
+
+
 //                // This performs the tab filtering
 //                if (mSelectedRawContactId != null
 //                        && mSelectedRawContactId != rawContactId
@@ -903,10 +908,6 @@
                         continue;
                     }
 
-                    if (!mRawContactIds.contains(entry.contactId)) {
-                        mRawContactIds.add(entry.contactId);
-                    }
-
                     if (CommonDataKinds.Phone.CONTENT_ITEM_TYPE.equals(mimetype)
                             || CommonDataKinds.Email.CONTENT_ITEM_TYPE.equals(mimetype)
                             || CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE.equals(mimetype)
diff --git a/src/com/android/contacts/model/EntityModifier.java b/src/com/android/contacts/model/EntityModifier.java
index 0d8ede9..1d78cfc 100644
--- a/src/com/android/contacts/model/EntityModifier.java
+++ b/src/com/android/contacts/model/EntityModifier.java
@@ -33,9 +33,11 @@
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.provider.ContactsContract.Intents.Insert;
+import android.provider.ContactsContract;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseIntArray;
@@ -378,8 +380,12 @@
                     continue;
                 }
 
-                // Test and remove this row if empty
-                if (EntityModifier.isEmpty(entry, kind)) {
+                // Test and remove this row if empty and it isn't a photo from google
+                final boolean isGoogleSource = TextUtils.equals(GoogleSource.ACCOUNT_TYPE,
+                        entry.getAsString(RawContacts.ACCOUNT_TYPE));
+                final boolean isPhoto = TextUtils.equals(Photo.CONTENT_ITEM_TYPE, kind.mimeType);
+                final boolean isGooglePhoto = isPhoto && isGoogleSource;
+                if (EntityModifier.isEmpty(entry, kind) && !isGooglePhoto) {
                     // TODO: remove this verbose logging
                     Log.w(TAG, "Trimming: " + entry.toString());
                     entry.markDeleted();
diff --git a/src/com/android/contacts/model/ExchangeSource.java b/src/com/android/contacts/model/ExchangeSource.java
index 5c2d024..0a7fb23 100644
--- a/src/com/android/contacts/model/ExchangeSource.java
+++ b/src/com/android/contacts/model/ExchangeSource.java
@@ -123,6 +123,8 @@
             kind.typeList.add(buildPhoneType(Phone.TYPE_MMS).setSecondary(true).setSpecificMax(1));
             kind.typeList
                     .add(buildPhoneType(Phone.TYPE_RADIO).setSecondary(true).setSpecificMax(1));
+            kind.typeList.add(buildPhoneType(Phone.TYPE_ASSISTANT).setSecondary(true)
+                    .setSpecificMax(1).setCustomColumn(Phone.LABEL));
             kind.typeList.add(buildPhoneType(Phone.TYPE_CUSTOM).setSecondary(true)
                     .setSpecificMax(1).setCustomColumn(Phone.LABEL));