am d2f813c3: Merge change I60cfe9ce into eclair-mr2

Merge commit 'd2f813c3f85060d42744be2632fed20f520001ee' into eclair-mr2-plus-aosp

* commit 'd2f813c3f85060d42744be2632fed20f520001ee':
  Add unit tests.
diff --git a/core/java/android/pim/vcard/VCardBuilder.java b/core/java/android/pim/vcard/VCardBuilder.java
index 4c62515..377e201 100644
--- a/core/java/android/pim/vcard/VCardBuilder.java
+++ b/core/java/android/pim/vcard/VCardBuilder.java
@@ -1072,7 +1072,7 @@
     public VCardBuilder appendNotes(final List<ContentValues> contentValuesList) {
         if (contentValuesList != null) {
             if (mOnlyOneNoteFieldIsAvailable) {
-                StringBuilder noteBuilder = new StringBuilder();
+                final StringBuilder noteBuilder = new StringBuilder();
                 boolean first = true;
                 for (final ContentValues contentValues : contentValuesList) {
                     String note = contentValues.getAsString(Note.NOTE);
@@ -1593,8 +1593,7 @@
     }
 
     public void appendLine(final String propertyName, final List<String> parameterList,
-            final String rawValue, final boolean needCharset,
-            boolean needQuotedPrintable) {
+            final String rawValue, final boolean needCharset, boolean needQuotedPrintable) {
         mBuilder.append(propertyName);
         if (parameterList != null && parameterList.size() > 0) {
             mBuilder.append(VCARD_PARAM_SEPARATOR);
@@ -1725,31 +1724,12 @@
         return false;
     }
 
-    private String encodeQuotedPrintable(String str) {
+    private String encodeQuotedPrintable(final String str) {
         if (TextUtils.isEmpty(str)) {
             return "";
         }
-        {
-            // Replace "\n" and "\r" with "\r\n".
-            final StringBuilder tmpBuilder = new StringBuilder();
-            int length = str.length();
-            for (int i = 0; i < length; i++) {
-                char ch = str.charAt(i);
-                if (ch == '\r') {
-                    if (i + 1 < length && str.charAt(i + 1) == '\n') {
-                        i++;
-                    }
-                    tmpBuilder.append("\r\n");
-                } else if (ch == '\n') {
-                    tmpBuilder.append("\r\n");
-                } else {
-                    tmpBuilder.append(ch);
-                }
-            }
-            str = tmpBuilder.toString();
-        }
 
-        final StringBuilder tmpBuilder = new StringBuilder();
+        final StringBuilder builder = new StringBuilder();
         int index = 0;
         int lineCount = 0;
         byte[] strArray = null;
@@ -1762,7 +1742,7 @@
             strArray = str.getBytes();
         }
         while (index < strArray.length) {
-            tmpBuilder.append(String.format("=%02X", strArray[index]));
+            builder.append(String.format("=%02X", strArray[index]));
             index += 1;
             lineCount += 3;
 
@@ -1774,12 +1754,12 @@
                 // it will become
                 // 6 bytes.
                 // 76 - 6 - 3 = 67
-                tmpBuilder.append("=\r\n");
+                builder.append("=\r\n");
                 lineCount = 0;
             }
         }
 
-        return tmpBuilder.toString();
+        return builder.toString();
     }
 
 
diff --git a/core/java/android/pim/vcard/VCardUtils.java b/core/java/android/pim/vcard/VCardUtils.java
index 45c0172..36f9006 100644
--- a/core/java/android/pim/vcard/VCardUtils.java
+++ b/core/java/android/pim/vcard/VCardUtils.java
@@ -74,6 +74,7 @@
 
         sPhoneTypesUnknownToContactsSet = new HashSet<String>();
         sPhoneTypesUnknownToContactsSet.add(VCardConstants.PARAM_TYPE_MODEM);
+        sPhoneTypesUnknownToContactsSet.add(VCardConstants.PARAM_TYPE_MSG);
         sPhoneTypesUnknownToContactsSet.add(VCardConstants.PARAM_TYPE_BBS);
         sPhoneTypesUnknownToContactsSet.add(VCardConstants.PARAM_TYPE_VIDEO);
 
@@ -399,10 +400,10 @@
 
         final int length = str.length();
         final int asciiFirst = 0x20;
-        final int asciiLast = 0x126;
+        final int asciiLast = 0x7E;  // included
         for (int i = 0; i < length; i = str.offsetByCodePoints(i, 1)) {
-            int c = str.codePointAt(i);
-            if (c < asciiFirst || asciiLast < c) {
+            final int c = str.codePointAt(i);
+            if (!((asciiFirst <= c && c <= asciiLast) || c == '\r' || c == '\n')) {
                 return false;
             }
         }
@@ -421,10 +422,10 @@
 
         final int length = str.length();
         final int asciiFirst = 0x20;
-        final int asciiLast = 0x126;
+        final int asciiLast = 0x7E;  // included
         for (int i = 0; i < length; i = str.offsetByCodePoints(i, 1)) {
-            int c = str.codePointAt(i);
-            if (c < asciiFirst || asciiLast < c || c == '\n' || c == '\r') {
+            final int c = str.codePointAt(i);
+            if (!(asciiFirst <= c && c <= asciiLast)) {
                 return false;
             }
         }
@@ -445,19 +446,19 @@
             return true;
         }
 
-        final int lowerAlphabetFirst = 0x41;  // included ('A')
-        final int lowerAlphabetLast = 0x5b;  // not included ('[')
-        final int upperAlphabetFirst = 0x61;  // included ('a')
-        final int upperAlphabetLast = 0x7b;  // included ('{')
-        final int digitFirst = 0x30;  // included ('0')
-        final int digitLast = 0x39;  // included ('9')
+        final int upperAlphabetFirst = 0x41;  // A
+        final int upperAlphabetAfterLast = 0x5b;  // [
+        final int lowerAlphabetFirst = 0x61;  // a
+        final int lowerAlphabetAfterLast = 0x7b;  // {
+        final int digitFirst = 0x30;  // 0
+        final int digitAfterLast = 0x3A;  // :
         final int hyphen = '-';
         final int length = str.length();
         for (int i = 0; i < length; i = str.offsetByCodePoints(i, 1)) {
             int codepoint = str.codePointAt(i);
-            if (!((lowerAlphabetFirst <= codepoint && codepoint < lowerAlphabetLast) ||
-                    (upperAlphabetFirst <= codepoint && codepoint < upperAlphabetLast) ||
-                    (digitFirst <= codepoint && codepoint < digitLast) ||
+            if (!((lowerAlphabetFirst <= codepoint && codepoint < lowerAlphabetAfterLast) ||
+                    (upperAlphabetFirst <= codepoint && codepoint < upperAlphabetAfterLast) ||
+                    (digitFirst <= codepoint && codepoint < digitAfterLast) ||
                     (codepoint == hyphen))) {
                 return false;
             }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNode.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNode.java
index 89134a1..14a789a 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNode.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNode.java
@@ -122,21 +122,17 @@
         
         if (propName == null || !propName.equals(node.propName)) {
             return false;
-        } else if (!paramMap.equals(node.paramMap)) {
+        } else if (!paramMap_TYPE.equals(node.paramMap_TYPE)) {
             return false;
-        } else if (!(paramMap_TYPE.size() == node.paramMap_TYPE.size()) &&
-                !paramMap_TYPE.equals(node.paramMap_TYPE)) {
-            Log.d("@@@", "paramMap_Type: " + paramMap_TYPE.size() + ", "
-                    + node.paramMap_TYPE.size());
+        } else if (!paramMap_TYPE.equals(node.paramMap_TYPE)) {
             return false;
         } else if (!propGroupSet.equals(node.propGroupSet)) {
             return false;
         }
-        
+
         if (propValue_bytes != null && Arrays.equals(propValue_bytes, node.propValue_bytes)) {
             return true;
         } else {
-            // Log.d("@@@", propValue + ", " + node.propValue);
             if (!propValue.equals(node.propValue)) {
                 return false;
             }
@@ -173,6 +169,7 @@
         builder.append("]");
         if (!propGroupSet.isEmpty()) {
             builder.append(", propGroupSet: [");
+            first = true;
             for (String elem : propGroupSet) {
                 if (first) {
                     first = false;
@@ -193,8 +190,9 @@
             builder.append(", propValue_bytes size: ");
             builder.append(propValue_bytes.length);
         }
-        builder.append(", propValue: ");
+        builder.append(", propValue: \"");
         builder.append(propValue);
+        builder.append("\"");
         return builder.toString();
     }
 }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardJapanizationTests.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardJapanizationTests.java
index faafb99..0522867 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardJapanizationTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardJapanizationTests.java
@@ -18,10 +18,14 @@
 
 import android.content.ContentValues;
 import android.pim.vcard.VCardConfig;
+import android.provider.ContactsContract.CommonDataKinds.Note;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 
 import com.android.unit_tests.vcard.PropertyNodesVerifierElem.TypeSet;
+import com.android.unit_tests.vcard.VCardTestsBase.ContactEntry;
+import com.android.unit_tests.vcard.VCardTestsBase.VCardVerifier;
 
 import java.util.Arrays;
 
@@ -317,4 +321,53 @@
                         Arrays.asList("3", "", "", "", "", "", ""), new TypeSet("HOME"));
         verifier.verify();
     }
-}
\ No newline at end of file
+
+    private void testJapanesePhoneNumberCommon(int vcardType) {
+        VCardVerifier verifier = new VCardVerifier(vcardType);
+        ContactEntry entry = verifier.addInputEntry();
+        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+                .put(Phone.NUMBER, "0312341234")
+                .put(Phone.TYPE, Phone.TYPE_HOME);
+        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+                .put(Phone.NUMBER, "09012341234")
+                .put(Phone.TYPE, Phone.TYPE_MOBILE);
+        verifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addNodeWithoutOrder("TEL", "03-1234-1234", new TypeSet("HOME"))
+                .addNodeWithoutOrder("TEL", "090-1234-1234", new TypeSet("WORK"));
+    }
+
+    public void testJapanesePhoneNumberV21_1() {
+        testJapanesePhoneNumberCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE_UTF8);
+    }
+
+    public void testJapanesePhoneNumberDoCoMo() {
+        testJapanesePhoneNumberCommon(VCardConfig.VCARD_TYPE_DOCOMO);
+    }
+
+    public void testJapanesePhoneNumberV30() {
+        testJapanesePhoneNumberCommon(VCardConfig.VCARD_TYPE_V30_JAPANESE_UTF8);
+    }
+
+    public void testNoteDoCoMo() {
+        VCardVerifier verifier = new VCardVerifier(VCardConfig.VCARD_TYPE_DOCOMO);
+        ContactEntry entry = verifier.addInputEntry();
+        entry.buildData(Note.CONTENT_ITEM_TYPE)
+                .put(Note.NOTE, "note1");
+        entry.buildData(Note.CONTENT_ITEM_TYPE)
+                .put(Note.NOTE, "note2");
+        entry.buildData(Note.CONTENT_ITEM_TYPE)
+                .put(Note.NOTE, "note3");
+
+        // More than one note fields must be aggregated into one note.
+        verifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
+                .addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
+                .addNodeWithoutOrder("X-CLASS", "PUBLIC")
+                .addNodeWithoutOrder("X-REDUCTION", "")
+                .addNodeWithoutOrder("X-NO", "")
+                .addNodeWithoutOrder("X-DCM-HMN-MODE", "")
+                .addNodeWithoutOrder("ADR", "", new TypeSet("HOME"))
+                .addNodeWithoutOrder("NOTE", "note1\nnote2\nnote3", mContentValuesForQP);
+        verifier.verify();
+    }
+}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestsBase.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestsBase.java
index 00debb5..7b5f216 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestsBase.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestsBase.java
@@ -957,8 +957,9 @@
             final String value = entry.getValue();
             builder.append(' ');
             builder.append(key);
-            builder.append('=');
+            builder.append("=\"");
             builder.append(value);
+            builder.append('"');
         }
         return builder.toString();
     }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardUtilsTests.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardUtilsTests.java
new file mode 100644
index 0000000..6202bdb
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardUtilsTests.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.unit_tests.vcard;
+
+import android.pim.vcard.VCardUtils;
+
+import junit.framework.TestCase;
+
+public class VCardUtilsTests extends TestCase {
+    public void testContainsOnlyPrintableAscii() {
+        assertTrue(VCardUtils.containsOnlyPrintableAscii(null));
+        assertTrue(VCardUtils.containsOnlyPrintableAscii(""));
+        assertTrue(VCardUtils.containsOnlyPrintableAscii("abcdefghijklmnopqrstuvwxyz"));
+        assertTrue(VCardUtils.containsOnlyPrintableAscii("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0x20; i < 0x7F; i++) {
+            builder.append((char)i);
+        }
+        assertTrue(VCardUtils.containsOnlyPrintableAscii(builder.toString()));
+        assertTrue(VCardUtils.containsOnlyPrintableAscii("\r\n"));
+        assertFalse(VCardUtils.containsOnlyPrintableAscii("\u0019"));
+        assertFalse(VCardUtils.containsOnlyPrintableAscii("\u007F"));
+    }
+
+    public void testContainsOnlyNonCrLfPrintableAscii() {
+        assertTrue(VCardUtils.containsOnlyNonCrLfPrintableAscii(null));
+        assertTrue(VCardUtils.containsOnlyNonCrLfPrintableAscii(""));
+        assertTrue(VCardUtils.containsOnlyNonCrLfPrintableAscii("abcdefghijklmnopqrstuvwxyz"));
+        assertTrue(VCardUtils.containsOnlyNonCrLfPrintableAscii("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0x20; i < 0x7F; i++) {
+            builder.append((char)i);
+        }
+        assertTrue(VCardUtils.containsOnlyNonCrLfPrintableAscii(builder.toString()));
+        assertFalse(VCardUtils.containsOnlyNonCrLfPrintableAscii("\u0019"));
+        assertFalse(VCardUtils.containsOnlyNonCrLfPrintableAscii("\u007F"));
+        assertFalse(VCardUtils.containsOnlyNonCrLfPrintableAscii("\r"));
+        assertFalse(VCardUtils.containsOnlyNonCrLfPrintableAscii("\n"));
+    }
+
+    public void testContainsOnlyAlphaDigitHyphen() {
+        assertTrue(VCardUtils.containsOnlyAlphaDigitHyphen(null));
+        assertTrue(VCardUtils.containsOnlyAlphaDigitHyphen(""));
+        assertTrue(VCardUtils.containsOnlyNonCrLfPrintableAscii("abcdefghijklmnopqrstuvwxyz"));
+        assertTrue(VCardUtils.containsOnlyNonCrLfPrintableAscii("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+        assertTrue(VCardUtils.containsOnlyNonCrLfPrintableAscii("0123456789-"));
+        for (int i = 0; i < 0x30; i++) {
+            if (i == 0x2D) {  // -
+                continue;
+            }
+            assertFalse(VCardUtils.containsOnlyAlphaDigitHyphen(String.valueOf((char)i)));
+        }
+        for (int i = 0x3A; i < 0x41; i++) {
+            assertFalse(VCardUtils.containsOnlyAlphaDigitHyphen(String.valueOf((char)i)));
+        }
+        for (int i = 0x5B; i < 0x61; i++) {
+            assertFalse(VCardUtils.containsOnlyAlphaDigitHyphen(String.valueOf((char)i)));
+        }
+        for (int i = 0x7B; i < 0x100; i++) {
+            assertFalse(VCardUtils.containsOnlyAlphaDigitHyphen(String.valueOf((char)i)));
+        }
+    }
+}