Merge change 26971 into eclair

* changes:
  Implement pause/resume for the RS thread.
diff --git a/api/current.xml b/api/current.xml
index 5b1e4d1..b776052 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -113131,6 +113131,37 @@
 >
 </field>
 </interface>
+<class name="ContactsContract.CommonDataKinds.Birthday"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<field name="BIRTHDAY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;data1&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CONTENT_ITEM_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;vnd.android.cursor.item/birthday&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
 <class name="ContactsContract.CommonDataKinds.Email"
  extends="java.lang.Object"
  abstract="false"
@@ -113617,37 +113648,6 @@
 >
 </field>
 </class>
-<class name="ContactsContract.CommonDataKinds.Miscellaneous"
- extends="java.lang.Object"
- abstract="false"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-<field name="BIRTHDAY"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;data1&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="CONTENT_ITEM_TYPE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;vnd.android.cursor.item/misc&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
 <class name="ContactsContract.CommonDataKinds.Nickname"
  extends="java.lang.Object"
  abstract="false"
diff --git a/core/java/android/pim/vcard/ContactStruct.java b/core/java/android/pim/vcard/ContactStruct.java
index d7fc2d1..35224c7 100644
--- a/core/java/android/pim/vcard/ContactStruct.java
+++ b/core/java/android/pim/vcard/ContactStruct.java
@@ -18,7 +18,6 @@
 import android.accounts.Account;
 import android.content.ContentProviderOperation;
 import android.content.ContentResolver;
-import android.content.ContentValues;
 import android.content.OperationApplicationException;
 import android.database.Cursor;
 import android.os.RemoteException;
@@ -26,10 +25,10 @@
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Groups;
 import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Birthday;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
 import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.CommonDataKinds.Miscellaneous;
 import android.provider.ContactsContract.CommonDataKinds.Nickname;
 import android.provider.ContactsContract.CommonDataKinds.Note;
 import android.provider.ContactsContract.CommonDataKinds.Organization;
@@ -1317,9 +1316,9 @@
         
         if (!TextUtils.isEmpty(mBirthday)) {
             builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
-            builder.withValueBackReference(Miscellaneous.RAW_CONTACT_ID, 0);
-            builder.withValue(Data.MIMETYPE, Miscellaneous.CONTENT_ITEM_TYPE);
-            builder.withValue(Miscellaneous.BIRTHDAY, mBirthday);
+            builder.withValueBackReference(Birthday.RAW_CONTACT_ID, 0);
+            builder.withValue(Data.MIMETYPE, Birthday.CONTENT_ITEM_TYPE);
+            builder.withValue(Birthday.BIRTHDAY, mBirthday);
             operationList.add(builder.build());
         }
 
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index cef971d..2404a43 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -24,12 +24,14 @@
 import android.database.Cursor;
 import android.database.sqlite.SQLiteException;
 import android.os.RemoteException;
+import android.provider.CallLog;
+import android.provider.CallLog.Calls;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.CommonDataKinds.Miscellaneous;
+import android.provider.ContactsContract.CommonDataKinds.Birthday;
 import android.provider.ContactsContract.CommonDataKinds.Nickname;
 import android.provider.ContactsContract.CommonDataKinds.Note;
 import android.provider.ContactsContract.CommonDataKinds.Organization;
@@ -40,9 +42,9 @@
 import android.provider.ContactsContract.CommonDataKinds.Website;
 import android.provider.CallLog.Calls;
 import android.provider.CallLog;
-import android.text.format.DateUtils;
 import android.text.format.Time;
 import android.text.TextUtils;
+import android.text.format.Time;
 import android.util.CharsetUtils;
 import android.util.Log;
 
@@ -82,6 +84,8 @@
 public class VCardComposer {
     private static final String LOG_TAG = "vcard.VCardComposer";
 
+    private final static String DEFAULT_EMAIL_TYPE = Constants.ATTR_TYPE_INTERNET;
+
     public static interface OneEntryHandler {
         public boolean onInit(Context context);
 
@@ -403,7 +407,7 @@
 
     /**
      * @return Returns true when initialization is successful and all the other
-     *         methods are available. Returns false otherwise.
+     *          methods are available. Returns false otherwise.
      */
     public boolean init(final String selection, final String[] selectionArgs) {
         if (mCareHandlerErrors) {
@@ -554,7 +558,7 @@
         final long dateAsLong = mCursor.getLong(DATE_COLUMN_INDEX);
         builder.append(VCARD_PROPERTY_X_TIMESTAMP);
         builder.append(VCARD_ATTR_SEPARATOR);
-        appendType(builder, callLogTypeStr);
+        appendTypeAttribute(builder, callLogTypeStr);
         builder.append(VCARD_DATA_SEPARATOR);
         builder.append(toRfc2455Format(dateAsLong));
         builder.append(VCARD_COL_SEPARATOR);
@@ -705,9 +709,9 @@
         return mErrorReason;
     }
 
-    private void appendStructuredNames(StringBuilder builder,
+    private void appendStructuredNames(final StringBuilder builder,
             final Map<String, List<ContentValues>> contentValuesListMap) {
-        List<ContentValues> contentValuesList = contentValuesListMap
+        final List<ContentValues> contentValuesList = contentValuesListMap
                 .get(StructuredName.CONTENT_ITEM_TYPE);
         if (contentValuesList != null) {
             appendStructuredNamesInternal(builder, contentValuesList);
@@ -922,7 +926,7 @@
 
     private void appendNickNames(final StringBuilder builder,
             final Map<String, List<ContentValues>> contentValuesListMap) {
-        List<ContentValues> contentValuesList = contentValuesListMap
+        final List<ContentValues> contentValuesList = contentValuesListMap
                 .get(Nickname.CONTENT_ITEM_TYPE);
         if (contentValuesList != null) {
             final String propertyNickname;
@@ -958,7 +962,7 @@
 
     private void appendPhones(final StringBuilder builder,
             final Map<String, List<ContentValues>> contentValuesListMap) {
-        List<ContentValues> contentValuesList = contentValuesListMap
+        final List<ContentValues> contentValuesList = contentValuesListMap
                 .get(Phone.CONTENT_ITEM_TYPE);
         if (contentValuesList != null) {
             for (ContentValues contentValues : contentValuesList) {
@@ -976,7 +980,7 @@
 
     private void appendEmails(final StringBuilder builder,
             final Map<String, List<ContentValues>> contentValuesListMap) {
-        List<ContentValues> contentValuesList = contentValuesListMap
+        final List<ContentValues> contentValuesList = contentValuesListMap
                 .get(Email.CONTENT_ITEM_TYPE);
         if (contentValuesList != null) {
             for (ContentValues contentValues : contentValuesList) {
@@ -992,7 +996,7 @@
 
     private void appendPostals(final StringBuilder builder,
             final Map<String, List<ContentValues>> contentValuesListMap) {
-        List<ContentValues> contentValuesList = contentValuesListMap
+        final List<ContentValues> contentValuesList = contentValuesListMap
                 .get(StructuredPostal.CONTENT_ITEM_TYPE);
 
         if (contentValuesList != null) {
@@ -1062,7 +1066,7 @@
 
     private void appendIms(final StringBuilder builder,
             final Map<String, List<ContentValues>> contentValuesListMap) {
-        List<ContentValues> contentValuesList = contentValuesListMap
+        final List<ContentValues> contentValuesList = contentValuesListMap
                 .get(Im.CONTENT_ITEM_TYPE);
         if (contentValuesList != null) {
             for (ContentValues contentValues : contentValuesList) {
@@ -1081,7 +1085,7 @@
 
     private void appendWebsites(final StringBuilder builder,
             final Map<String, List<ContentValues>> contentValuesListMap) {
-        List<ContentValues> contentValuesList = contentValuesListMap
+        final List<ContentValues> contentValuesList = contentValuesListMap
                 .get(Website.CONTENT_ITEM_TYPE);
         if (contentValuesList != null) {
             for (ContentValues contentValues : contentValuesList) {
@@ -1093,20 +1097,20 @@
 
     private void appendBirthday(final StringBuilder builder,
             final Map<String, List<ContentValues>> contentValuesListMap) {
-        List<ContentValues> contentValuesList = contentValuesListMap
-                .get(Miscellaneous.CONTENT_ITEM_TYPE);
+        final List<ContentValues> contentValuesList = contentValuesListMap
+                .get(Birthday.CONTENT_ITEM_TYPE);
         if (contentValuesList != null && contentValuesList.size() > 0) {
             // Theoretically, there must be only one birthday for each vCard data and
             // we are afraid of some parse error occuring in some devices, so
             // we emit only one birthday entry for now.
-            final String birthday = contentValuesList.get(0).getAsString(Miscellaneous.BIRTHDAY);
+            final String birthday = contentValuesList.get(0).getAsString(Birthday.BIRTHDAY);
             appendVCardLine(builder, VCARD_PROPERTY_BIRTHDAY, birthday);
         }
     }
 
     private void appendOrganizations(final StringBuilder builder,
             final Map<String, List<ContentValues>> contentValuesListMap) {
-        List<ContentValues> contentValuesList = contentValuesListMap
+        final List<ContentValues> contentValuesList = contentValuesListMap
                 .get(Organization.CONTENT_ITEM_TYPE);
         if (contentValuesList != null) {
             for (ContentValues contentValues : contentValuesList) {
@@ -1124,7 +1128,7 @@
 
     private void appendPhotos(final StringBuilder builder,
             final Map<String, List<ContentValues>> contentValuesListMap) {
-        List<ContentValues> contentValuesList = contentValuesListMap
+        final List<ContentValues> contentValuesList = contentValuesListMap
                 .get(Photo.CONTENT_ITEM_TYPE);
         if (contentValuesList != null) {
             for (ContentValues contentValues : contentValuesList) {
@@ -1153,7 +1157,7 @@
                     Log.d(LOG_TAG, "Unknown photo type. Ignore.");
                     continue;
                 }
-                String photoString = VCardUtils.encodeBase64(data);
+                final String photoString = VCardUtils.encodeBase64(data);
                 if (photoString.length() > 0) {
                     appendVCardPhotoLine(builder, photoString, photoType);
                 }
@@ -1201,64 +1205,76 @@
      * Note that Quoted-Printable string must not be input here.
      */
     @SuppressWarnings("fallthrough")
-    private String escapeCharacters(String unescaped) {
+    private String escapeCharacters(final String unescaped) {
         if (TextUtils.isEmpty(unescaped)) {
             return "";
         }
 
-        StringBuilder builder = new StringBuilder();
+        final StringBuilder tmpBuilder = new StringBuilder();
         final int length = unescaped.length();
         for (int i = 0; i < length; i++) {
             char ch = unescaped.charAt(i);
             switch (ch) {
-            case ';':
-                builder.append('\\');
-                builder.append(';');
-                break;
-            case '\r':
-                if (i + 1 < length) {
-                    char nextChar = unescaped.charAt(i);
-                    if (nextChar == '\n') {
-                        continue;
+                case ';': {
+                    tmpBuilder.append('\\');
+                    tmpBuilder.append(';');
+                    break;
+                }
+                case '\r': {
+                    if (i + 1 < length) {
+                        char nextChar = unescaped.charAt(i);
+                        if (nextChar == '\n') {
+                            continue;
+                        } else {
+                            // fall through
+                        }
                     } else {
                         // fall through
                     }
-                } else {
-                    // fall through
                 }
-            case '\n':
-                // In vCard 2.1, there's no specification about this, while
-                // vCard 3.0 explicitly
-                // requires this should be encoded to "\n".
-                builder.append("\\n");
-                break;
-            case '\\':
-                if (mIsV30) {
-                    builder.append("\\\\");
+                case '\n': {
+                    // In vCard 2.1, there's no specification about this, while
+                    // vCard 3.0 explicitly requires this should be encoded to "\n".
+                    tmpBuilder.append("\\n");
                     break;
                 }
-            case '<':
-            case '>':
-                if (mIsDoCoMo) {
-                    builder.append('\\');
-                    builder.append(ch);
+                case '\\': {
+                    if (mIsV30) {
+                        tmpBuilder.append("\\\\");
+                        break;
+                    } else {
+                        // fall through
+                    }
                 }
-                break;
-            case ',':
-                if (mIsV30) {
-                    builder.append("\\,");
+                case '<':
+                case '>': {
+                    if (mIsDoCoMo) {
+                        tmpBuilder.append('\\');
+                        tmpBuilder.append(ch);
+                    } else {
+                        tmpBuilder.append(ch);
+                    }
                     break;
                 }
-            default:
-                builder.append(ch);
-                break;
+                case ',': {
+                    if (mIsV30) {
+                        tmpBuilder.append("\\,");
+                    } else {
+                        tmpBuilder.append(ch);
+                    }
+                    break;
+                }
+                default: {
+                    tmpBuilder.append(ch);
+                    break;
+                }
             }
         }
-        return builder.toString();
+        return tmpBuilder.toString();
     }
 
-    private void appendVCardPhotoLine(StringBuilder builder,
-            String encodedData, String type) {
+    private void appendVCardPhotoLine(final StringBuilder builder,
+            final String encodedData, final String photoType) {
         StringBuilder tmpBuilder = new StringBuilder();
         tmpBuilder.append(VCARD_PROPERTY_PHOTO);
         tmpBuilder.append(VCARD_ATTR_SEPARATOR);
@@ -1268,14 +1284,15 @@
             tmpBuilder.append(VCARD_ATTR_ENCODING_BASE64_V21);
         }
         tmpBuilder.append(VCARD_ATTR_SEPARATOR);
-        appendType(tmpBuilder, type);
+        appendTypeAttribute(tmpBuilder, photoType);
         tmpBuilder.append(VCARD_DATA_SEPARATOR);
         tmpBuilder.append(encodedData);
 
-        String tmpStr = tmpBuilder.toString();
+        final String tmpStr = tmpBuilder.toString();
         tmpBuilder = new StringBuilder();
         int lineCount = 0;
-        for (int i = 0; i < tmpStr.length(); i++) {
+        int length = tmpStr.length();
+        for (int i = 0; i < length; i++) {
             tmpBuilder.append(tmpStr.charAt(i));
             lineCount++;
             if (lineCount > 72) {
@@ -1289,7 +1306,8 @@
         builder.append(VCARD_COL_SEPARATOR);
     }
 
-    private void appendVCardPostalLine(StringBuilder builder, Integer type, String label,
+    private void appendVCardPostalLine(final StringBuilder builder,
+            final Integer typeAsObject, final String label,
             final ContentValues contentValues) {
         builder.append(VCARD_PROPERTY_ADR);
         builder.append(VCARD_ATTR_SEPARATOR);
@@ -1310,48 +1328,59 @@
             }
         }
 
-        if (type == null) {
-            type = StructuredPostal.TYPE_OTHER;
+        final int typeAsPrimitive;
+        if (typeAsObject == null) {
+            typeAsPrimitive = StructuredPostal.TYPE_OTHER;
+        } else {
+            typeAsPrimitive = typeAsObject;
         }
 
-        boolean typeIsAppended = false;
-        switch (type) {
-        case StructuredPostal.TYPE_HOME:
-            builder.append(Constants.ATTR_TYPE_HOME);
-            typeIsAppended = true;
-            break;
-        case StructuredPostal.TYPE_WORK:
-            builder.append(Constants.ATTR_TYPE_WORK);
-            typeIsAppended = true;
-            break;
-        case StructuredPostal.TYPE_CUSTOM:
-            if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
-                        && VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
-                // We're not sure whether the label is valid in the spec ("IANA-token" in the vCard 3.1
-                // is unclear...)
-                // Just for safety, we add "X-" at the beggining of each label.
-                // Also checks the label obeys with vCard 3.0 spec.
-                builder.append("X-");
-                builder.append(label);
-                builder.append(VCARD_DATA_SEPARATOR);
+        String typeAsString = null;
+        switch (typeAsPrimitive) {
+            case StructuredPostal.TYPE_HOME: {
+                typeAsString = Constants.ATTR_TYPE_HOME;
+                break;
             }
-            break;
-        case StructuredPostal.TYPE_OTHER:
-            break;
-        default:
-            Log.e(LOG_TAG, "Unknown StructuredPostal type: " + type);
-            break;
+            case StructuredPostal.TYPE_WORK: {
+                typeAsString = Constants.ATTR_TYPE_WORK;
+                break;
+            }
+            case StructuredPostal.TYPE_CUSTOM: {
+                if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
+                        && VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
+                    // We're not sure whether the label is valid in the spec
+                    // ("IANA-token" in the vCard 3.0 is unclear...)
+                    // Just  for safety, we add "X-" at the beggining of each label.
+                    // Also checks the label obeys with vCard 3.0 spec.
+                    builder.append("X-");
+                    builder.append(label);
+                    builder.append(VCARD_DATA_SEPARATOR);
+                }
+                break;
+            }
+            case StructuredPostal.TYPE_OTHER: {
+                break;
+            }
+            default: {
+                Log.e(LOG_TAG, "Unknown StructuredPostal type: " + typeAsPrimitive);
+                break;
+            }
+        }
+
+        if (typeAsString != null) {
+            appendTypeAttribute(builder, typeAsString);
         }
 
         if (dataExists) {
-            if (typeIsAppended) {
+            // Strictly, vCard 3.0 does not allow exporters to emit charset information,
+            // but we will add it since the information should be useful for importers,
+            //
+            // Assume no parser does not emit error with this attribute in vCard 3.0.
+            if (typeAsString != null) {
                 builder.append(VCARD_ATTR_SEPARATOR);
             }
-            // Strictly, vCard 3.0 does not allow this, but we add this since
-            // this information
-            // should be useful, Assume no parser does not emit error with this
-            // attribute.
             builder.append(mVCardAttributeCharset);
+
             if (useQuotedPrintable) {
                 builder.append(VCARD_ATTR_SEPARATOR);
                 builder.append(VCARD_ATTR_ENCODING_QP);
@@ -1381,61 +1410,78 @@
         builder.append(VCARD_COL_SEPARATOR);
     }
 
-    private void appendVCardEmailLine(StringBuilder builder, Integer type, String label, String data) {
+    private void appendVCardEmailLine(final StringBuilder builder,
+            final Integer typeAsObject, final String label, final String data) {
         builder.append(VCARD_PROPERTY_EMAIL);
-        builder.append(VCARD_ATTR_SEPARATOR);
 
-        if (type == null) {
-            type = Email.TYPE_OTHER;
+        final int typeAsPrimitive;
+        if (typeAsObject == null) {
+            typeAsPrimitive = Email.TYPE_OTHER;
+        } else {
+            typeAsPrimitive = typeAsObject;
         }
 
-        switch (type) {
-        case Email.TYPE_CUSTOM:
-            if (android.provider.Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME
+        final String typeAsString;
+        switch (typeAsPrimitive) {
+            case Email.TYPE_CUSTOM: {
+                // For backward compatibility.
+                // Detail: Until Donut, there isn't TYPE_MOBILE for email while there is now.
+                //         To support mobile type at that time, this custom label had been used.
+                if (android.provider.Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME
                         .equals(label)) {
-                builder.append(Constants.ATTR_TYPE_CELL);
-            } else if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
+                    typeAsString = Constants.ATTR_TYPE_CELL;
+                } else if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
                         && VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
-                builder.append("X-");
-                builder.append(label);
-            } else {
-                // Default to INTERNET.
-                builder.append(Constants.ATTR_TYPE_INTERNET);
+                    typeAsString = "X-" + label;
+                } else {
+                    typeAsString = DEFAULT_EMAIL_TYPE;
+                }
+                break;
             }
-            break;
-        case Email.TYPE_HOME:
-            builder.append(Constants.ATTR_TYPE_HOME);
-            break;
-        case Email.TYPE_WORK:
-            builder.append(Constants.ATTR_TYPE_WORK);
-            break;
-        case Email.TYPE_OTHER:
-            builder.append(Constants.ATTR_TYPE_INTERNET);
-            break;
-        case Email.TYPE_MOBILE:
-            builder.append(Constants.ATTR_TYPE_CELL);
-            break;
-        default:
-            Log.e(LOG_TAG, "Unknown Email type: " + type);
-            builder.append(Constants.ATTR_TYPE_INTERNET);
-            break;
+            case Email.TYPE_HOME: {
+                typeAsString = Constants.ATTR_TYPE_HOME;
+                break;
+            }
+            case Email.TYPE_WORK: {
+                typeAsString = Constants.ATTR_TYPE_WORK;
+                break;
+            }
+            case Email.TYPE_OTHER: {
+                typeAsString = DEFAULT_EMAIL_TYPE;
+                break;
+            }
+            case Email.TYPE_MOBILE: {
+                typeAsString = Constants.ATTR_TYPE_CELL;
+                break;
+            }
+            default: {
+                Log.e(LOG_TAG, "Unknown Email type: " + typeAsPrimitive);
+                typeAsString = DEFAULT_EMAIL_TYPE;
+                break;
+            }
         }
 
+        builder.append(VCARD_ATTR_SEPARATOR);
+        appendTypeAttribute(builder, typeAsString);
         builder.append(VCARD_DATA_SEPARATOR);
         builder.append(data);
         builder.append(VCARD_COL_SEPARATOR);
     }
 
-    private void appendVCardTelephoneLine(StringBuilder builder, Integer type, String label,
+    private void appendVCardTelephoneLine(final StringBuilder builder,
+            final Integer typeAsObject, final String label,
             String encodedData) {
         builder.append(VCARD_PROPERTY_TEL);
         builder.append(VCARD_ATTR_SEPARATOR);
 
-        if (type == null) {
-            type = Phone.TYPE_OTHER;
+        final int typeAsPrimitive;
+        if (typeAsObject == null) {
+            typeAsPrimitive = Phone.TYPE_OTHER;
+        } else {
+            typeAsPrimitive = typeAsObject;
         }
 
-        switch (type) {
+        switch (typeAsPrimitive) {
         case Phone.TYPE_HOME:
             appendTypeAttributes(builder, Arrays.asList(
                     Constants.ATTR_TYPE_HOME, Constants.ATTR_TYPE_VOICE));
@@ -1459,25 +1505,26 @@
             if (mIsDoCoMo) {
                 // Not sure about the reason, but previous implementation had
                 // used "VOICE" instead of "PAGER"
+                // Also, refrain from using appendType() so that "TYPE=" is never be appended.
                 builder.append(Constants.ATTR_TYPE_VOICE);
             } else {
-                builder.append(Constants.ATTR_TYPE_PAGER);
+                appendTypeAttribute(builder, Constants.ATTR_TYPE_PAGER);
             }
             break;
         case Phone.TYPE_OTHER:
-            builder.append(Constants.ATTR_TYPE_VOICE);
+            appendTypeAttribute(builder, Constants.ATTR_TYPE_VOICE);
             break;
         case Phone.TYPE_CUSTOM:
             if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
                         && VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
-                builder.append("X-" + label);
+                appendTypeAttribute(builder, "X-" + label);
             } else {
                 // Just ignore the custom type.
-                builder.append(Constants.ATTR_TYPE_VOICE);
+                appendTypeAttribute(builder, Constants.ATTR_TYPE_VOICE);
             }
             break;
         default:
-            appendUncommonPhoneType(builder, type);
+            appendUncommonPhoneType(builder, typeAsPrimitive);
             break;
         }
 
@@ -1489,7 +1536,7 @@
     /**
      * Appends phone type string which may not be available in some devices.
      */
-    private void appendUncommonPhoneType(StringBuilder builder, Integer type) {
+    private void appendUncommonPhoneType(final StringBuilder builder, final Integer type) {
         if (mIsDoCoMo) {
             // The previous implementation for DoCoMo had been conservative
             // about miscellaneous types.
@@ -1497,7 +1544,7 @@
         } else {
             String phoneAttribute = VCardUtils.getPhoneAttributeString(type);
             if (phoneAttribute != null) {
-                builder.append(phoneAttribute);
+                appendTypeAttribute(builder, phoneAttribute);
             } else {
                 Log.e(LOG_TAG, "Unknown or unsupported (by vCard) Phone type: " + type);
             }
@@ -1510,7 +1557,7 @@
     }
 
     private void appendVCardLine(final StringBuilder builder,
-            final String field, final String rawData, boolean needCharset,
+            final String field, final String rawData, final boolean needCharset,
             boolean needQuotedPrintable) {
         builder.append(field);
         if (needCharset) {
@@ -1545,11 +1592,11 @@
             } else {
                 builder.append(VCARD_ATTR_SEPARATOR);
             }
-            appendType(builder, type);
+            appendTypeAttribute(builder, type);
         }
     }
 
-    private void appendType(final StringBuilder builder, final String type) {
+    private void appendTypeAttribute(final StringBuilder builder, final String type) {
         // Note: In vCard 3.0, Type strings also can be like this: "TYPE=HOME,PREF"
         if (mIsV30) {
             builder.append(Constants.ATTR_TYPE).append(VCARD_ATTR_EQUAL);
@@ -1581,7 +1628,7 @@
             str = tmpBuilder.toString();
         }
 
-        StringBuilder builder = new StringBuilder();
+        final StringBuilder tmpBuilder = new StringBuilder();
         int index = 0;
         int lineCount = 0;
         byte[] strArray = null;
@@ -1594,7 +1641,7 @@
             strArray = str.getBytes();
         }
         while (index < strArray.length) {
-            builder.append(String.format("=%02X", strArray[index]));
+            tmpBuilder.append(String.format("=%02X", strArray[index]));
             index += 1;
             lineCount += 3;
 
@@ -1606,11 +1653,11 @@
                 // it will become
                 // 6 bytes.
                 // 76 - 6 - 3 = 67
-                builder.append("=\r\n");
+                tmpBuilder.append("=\r\n");
                 lineCount = 0;
             }
         }
 
-        return builder.toString();
+        return tmpBuilder.toString();
     }
 }
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 8140d82..e32d3ad 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1639,19 +1639,20 @@
         }
 
         /**
-         * Common data definition for miscellaneous information.
+         * Common data definition for birthdays.
          */
-        public static final class Miscellaneous implements DataColumnsWithJoins {
+        public static final class Birthday implements DataColumnsWithJoins {
             /**
              * This utility class cannot be instantiated
              */
-            private Miscellaneous() {}
+            private Birthday() {}
 
             /** MIME type used when storing this in data table. */
-            public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/misc";
+            public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/birthday";
 
             /**
-             * The birthday as the user entered it.
+             * The birthday. This must be of the form YYYY-MM-DD or YYYY-MM-DDThh:mm:ss
+             * These are xs:date and xs:dateTime
              * <P>Type: TEXT</P>
              */
             public static final String BIRTHDAY = DATA1;
diff --git a/core/java/com/google/android/mms/pdu/PduComposer.java b/core/java/com/google/android/mms/pdu/PduComposer.java
index 8b31936..2aa5e48 100644
--- a/core/java/com/google/android/mms/pdu/PduComposer.java
+++ b/core/java/com/google/android/mms/pdu/PduComposer.java
@@ -19,6 +19,8 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.util.Log;
+import android.text.TextUtils;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileNotFoundException;
@@ -528,6 +530,7 @@
 
                 EncodedStringValue from = mPduHeader.getEncodedStringValue(field);
                 if ((from == null)
+                        || TextUtils.isEmpty(from.getString())
                         || new String(from.getTextString()).equals(
                                 PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) {
                     // Length of from = 1
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 6b92994..e944654 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -112,7 +112,7 @@
     }
     JNIEnv *env = AndroidRuntime::getJNIEnv();
     env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
-            mCameraJObjectWeak, msgType, ext1, ext2);
+            mCameraJObjectWeak, msgType, ext1, ext2, NULL);
 }
 
 void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int msgType)
diff --git a/core/res/res/drawable-hdpi/btn_lock_normal.9.png b/core/res/res/drawable-hdpi/btn_lock_normal.9.png
new file mode 100644
index 0000000..f1dac62
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_lock_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_lock_normal.9.png b/core/res/res/drawable-mdpi/btn_lock_normal.9.png
new file mode 100644
index 0000000..6bdc2c6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_lock_normal.9.png
Binary files differ
diff --git a/core/res/res/layout/keyguard_screen_unlock_landscape.xml b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
index 6dd2949..0ef73fa 100644
--- a/core/res/res/layout/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
@@ -85,21 +85,45 @@
             android:background="@android:drawable/divider_horizontal_dark"
                 />
 
-        <!-- lock icon and header message -->
-        <TextView
-            android:id="@+id/headerText"
+        <!-- used for instructions such as "draw pattern to unlock", the next alarm, and charging
+             status.  -->
+        <LinearLayout
+            android:orientation="horizontal"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginTop="12dip"
-            android:layout_centerHorizontal="true"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="?android:attr/textColorSecondary"
-            android:textSize="17sp"
-            android:drawableLeft="@drawable/ic_lock_idle_lock"
-            android:drawablePadding="4dip"
+            android:layout_marginTop="8dip"
             android:gravity="center"
-            />
-
+            >
+            <TextView
+                android:id="@+id/status1"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textColor="?android:attr/textColorSecondary"
+                android:textSize="17sp"
+                android:drawablePadding="4dip"
+                />
+            <TextView
+                android:id="@+id/statusSep"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="5dip"
+                android:layout_marginRight="5dip"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textColor="?android:attr/textColorSecondary"
+                android:textSize="17sp"
+                />
+            <TextView
+                android:id="@+id/status2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentTop="true"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textColor="?android:attr/textColorSecondary"
+                android:textSize="17sp"
+                android:drawablePadding="4dip"
+                />
+        </LinearLayout>
 
         <!-- fill space between header and button below -->
         <View
@@ -118,12 +142,16 @@
             <RelativeLayout android:id="@+id/footerNormal"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
+                android:gravity="center"
                 >
                 <Button android:id="@+id/emergencyCallAlone"
-                    android:layout_width="fill_parent"
+                    android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text="@string/lockscreen_emergency_call"
                     android:textSize="14sp"
+                    android:background="@drawable/btn_lock_normal"
+                    android:textAppearance="?android:attr/textAppearanceSmall"
+                    android:textColor="?android:attr/textColorPrimary"
                     android:drawableLeft="@drawable/ic_emergency"
                     android:drawablePadding="8dip"
                     />
@@ -140,6 +168,9 @@
                     android:layout_width="fill_parent"
                     android:layout_height="wrap_content"
                     android:textSize="14sp"
+                    android:background="@drawable/btn_lock_normal"
+                    android:textAppearance="?android:attr/textAppearanceSmall"
+                    android:textColor="?android:attr/textColorPrimary"
                     android:visibility="invisible"
                     />
                 <Button android:id="@+id/emergencyCallTogether"
@@ -147,6 +178,9 @@
                     android:layout_height="wrap_content"
                     android:text="@string/lockscreen_emergency_call"
                     android:textSize="14sp"
+                    android:background="@drawable/btn_lock_normal"
+                    android:textAppearance="?android:attr/textAppearanceSmall"
+                    android:textColor="?android:attr/textColorPrimary"
                     android:drawableLeft="@drawable/ic_emergency"
                     android:drawablePadding="8dip"
                     />
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index a5d44fc..f3c7559 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -84,19 +84,45 @@
         android:background="@android:drawable/divider_horizontal_dark"
             />
 
-    <!-- lock icon and header message -->
-    <TextView
-        android:id="@+id/headerText"
+    <!-- used for instructions such as "draw pattern to unlock", the next alarm, and charging
+         status.  -->
+    <LinearLayout
+        android:orientation="horizontal"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="3dip"
-        android:layout_centerHorizontal="true"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textColor="?android:attr/textColorSecondary"
-        android:textSize="17sp"
-        android:drawableLeft="@drawable/ic_lock_idle_lock"
-        android:drawablePadding="4dip"
-        />
+        android:gravity="center"
+        >
+        <TextView
+            android:id="@+id/status1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="17sp"
+            android:drawablePadding="4dip"
+            />
+        <TextView
+            android:id="@+id/statusSep"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="5dip"
+            android:layout_marginRight="5dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="17sp"
+            />
+        <TextView
+            android:id="@+id/status2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="17sp"
+            android:drawablePadding="4dip"
+            />
+    </LinearLayout>
 
     <com.android.internal.widget.LockPatternView
         android:id="@+id/lockPattern"
@@ -122,7 +148,9 @@
                 android:layout_height="wrap_content"
                 android:layout_centerInParent="true"
                 android:text="@string/lockscreen_emergency_call"
+                android:background="@drawable/btn_lock_normal"
                 android:textAppearance="?android:attr/textAppearanceSmall"
+                android:textColor="?android:attr/textColorPrimary"
                 android:drawableLeft="@drawable/ic_emergency"
                 android:drawablePadding="8dip"
                 />
@@ -145,7 +173,9 @@
                 android:layout_marginLeft="4dip"
                 android:layout_marginRight="2dip"
                 android:text="@string/lockscreen_emergency_call"
+                android:background="@drawable/btn_lock_normal"
                 android:textAppearance="?android:attr/textAppearanceSmall"
+                android:textColor="?android:attr/textColorPrimary"
                 android:drawableLeft="@drawable/ic_emergency"
                 android:drawablePadding="8dip"
                 />
@@ -157,7 +187,9 @@
                 android:layout_marginBottom="4dip"
                 android:layout_marginLeft="2dip"
                 android:layout_marginRight="4dip"
+                android:background="@drawable/btn_lock_normal"
                 android:textAppearance="?android:attr/textAppearanceSmall"
+                android:textColor="?android:attr/textColorPrimary"
                 android:visibility="invisible"
                 />
         </LinearLayout>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e2f6981..eb15183 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1345,6 +1345,8 @@
     <!-- When the lock screen is showing, the phone is plugged in and the battery is fully
          charged, say that it is charged. -->
     <string name="lockscreen_charged">Charged.</string>
+    <!-- A short representation of charging information, e.g "34%" -->
+    <string name="lockscreen_battery_short"><xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
 
     <!-- When the lock screen is showing and the battery is low, warn user to plug
          in the phone soon. -->
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java
index ab8b311..0b96bae 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java
@@ -55,6 +55,7 @@
     }
 
     // Generate a random number, sends it to the ping test player.
+    @Suppress
     @MediumTest
     public void testPing() throws Exception {
         mPlayer.setDataSource("test:invoke_mock_media_player.so?url=ping");