Handle "VOICE" type as OTHER on Android

vCard's "VOICE" type is the default type used in the format, while
OTHER is the default type on Android. Our exporter treats Android's
OTHER type as vCard's "VOICE", while our importer accepts
the default type "VOICE" as Android's CUSTOM type with "VOICE" label,
which confuses users: when they transfer phone numbers with OTHER type
those numbers become "VOICE" on receiver sides.

Bug: 5600504
Change-Id: Id30d2ca9b67b81798565224b881a734e8ee76516
diff --git a/java/com/android/vcard/VCardUtils.java b/java/com/android/vcard/VCardUtils.java
index 575dfbd..a486d5d 100644
--- a/java/com/android/vcard/VCardUtils.java
+++ b/java/com/android/vcard/VCardUtils.java
@@ -153,6 +153,8 @@
                 Phone.TYPE_TTY_TDD);
         sKnownPhoneTypeMap_StoI.put(VCardConstants.PARAM_PHONE_EXTRA_TYPE_ASSISTANT,
                 Phone.TYPE_ASSISTANT);
+        // OTHER (default in Android) should correspond to VOICE (default in vCard).
+        sKnownPhoneTypeMap_StoI.put(VCardConstants.PARAM_TYPE_VOICE, Phone.TYPE_OTHER);
 
         sPhoneTypesUnknownToContactsSet = new HashSet<String>();
         sPhoneTypesUnknownToContactsSet.add(VCardConstants.PARAM_TYPE_MODEM);
@@ -223,7 +225,13 @@
                     final Integer tmp = sKnownPhoneTypeMap_StoI.get(labelCandidate.toUpperCase());
                     if (tmp != null) {
                         final int typeCandidate = tmp;
-                        // TYPE_PAGER is prefered when the number contains @ surronded by
+                        // 1. If a type isn't specified yet, we'll choose the new type candidate.
+                        // 2. If the current type is default one (OTHER) or custom one, we'll
+                        // prefer more specific types specified in the vCard. Note that OTHER and
+                        // the other different types may appear simultaneously here, since vCard
+                        // allow to have VOICE and HOME/WORK in one line.
+                        // e.g. "TEL;WORK;VOICE:1" -> WORK + OTHER -> Type should be WORK
+                        // 3. TYPE_PAGER is prefered when the number contains @ surronded by
                         // a pager number and a domain name.
                         // e.g.
                         // o 1111@domain.com
@@ -233,7 +241,8 @@
                         if ((typeCandidate == Phone.TYPE_PAGER
                                 && 0 < indexOfAt && indexOfAt < number.length() - 1)
                                 || type < 0
-                                || type == Phone.TYPE_CUSTOM) {
+                                || type == Phone.TYPE_CUSTOM
+                                || type == Phone.TYPE_OTHER) {
                             type = tmp;
                         }
                     } else if (type < 0) {
diff --git a/tests/src/com/android/vcard/tests/VCardImporterTests.java b/tests/src/com/android/vcard/tests/VCardImporterTests.java
index e1843a5..3e5cb88 100644
--- a/tests/src/com/android/vcard/tests/VCardImporterTests.java
+++ b/tests/src/com/android/vcard/tests/VCardImporterTests.java
@@ -462,7 +462,7 @@
                 .addExpectedNodeWithOrder("N", ";A;B\\;C\\;;D;:E;\\\\;",
                         Arrays.asList("", "A;B\\", "C\\;", "D", ":E", "\\\\", ""))
                 .addExpectedNodeWithOrder("FN", "A;B\\C\\;D:E\\\\");
-        
+
     }
 
     /**
@@ -635,9 +635,9 @@
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "VIDEO")
                 .put(Phone.NUMBER, "032-222-2222");
+        // vCard's VOICE type should become OTHER type on Android devices.
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
-                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
-                .put(Phone.LABEL, "VOICE")
+                .put(Phone.TYPE, Phone.TYPE_OTHER)
                 .put(Phone.NUMBER, "033-333-3333");
         elem.addExpected(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK)
@@ -724,8 +724,7 @@
                 .put(Organization.DEPARTMENT, "Handset  Alliance")
                 .put(Organization.TYPE, Organization.TYPE_WORK);
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
-                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
-                .put(Phone.LABEL, "VOICE")
+                .put(Phone.TYPE, Phone.TYPE_OTHER)
                 .put(Phone.NUMBER, "030-000-0000")
                 .put(Phone.IS_PRIMARY, 1);
     }
@@ -760,8 +759,7 @@
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 // Phone number formatting is different.
                 .put(Phone.NUMBER, (japanese ? "03-0000-0000" : "030-000-0000"))
-                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
-                .put(Phone.LABEL, "VOICE")
+                .put(Phone.TYPE, Phone.TYPE_OTHER)
                 .put(Phone.IS_PRIMARY, 1);
     }