summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cheng <chengandrew@google.com>2021-10-26 11:26:55 -0700
committerAndrew Cheng <chengca@google.com>2021-11-18 18:43:56 +0000
commitb20bb3bcef5bde1ef05117f2dfc6571c284969f2 (patch)
treeddcd3c9846c98a2d3334ff7e1d2501c9cc53cd02
parentfffb220a0a695485714a4a9d08f69aaa4bd2e7be (diff)
downloadvcard-b20bb3bcef5bde1ef05117f2dfc6571c284969f2.tar.gz
Bluetooth sync adr-type "other" between two devices
{@link ContactsContract} has a {@link StructuredPostal.TYPE_OTHER}. However, when a vCard is created in {@link VCardBuilder}, {@code TYPE_OTHER} does not get mapped to anything, i.e., the {@code ADR} entry in the vCard does not have a {@code TYPE=}. Then, when a vCard is parsed in {@link VCardEntry}, it will get a null String when trying to get the address's {@code TYPE=}, which it will then default to {@link StructuredPostal.TYPE_HOME}. As a result, if a user syncs contact information between two Android devices using vCards (e.g., over Bluetooth), an address marked as type "Other" on the source device will appear as type "Home" on the sink device. To correctly sync the type "Other", this CL uses the existing framework in the vcard package that handles {@link ContactsContract}'s custom types, i.e., prepending with "X-". According to RFC 2426, this constitutes a valid "x-name", which constitutes a valid "adr-type". Bug: 197177611 Test: atest AndroidVCardTests Test: (Manual) Create a contact with address of type "other". Sync the contact to a second device. Verify on the second device that the address is still of type "other", and not of type "home". Also, in the Bluetooth HCI snoop logs, look for the raw vCards, and verify in the "ADR" entry, there is a "TYPE=X-OTHER". Note, both devices must be Android. Change-Id: I47217041e52d2d1c57b206bf88cc3b763baae418
-rw-r--r--java/com/android/vcard/VCardBuilder.java4
-rw-r--r--java/com/android/vcard/VCardConstants.java2
-rw-r--r--java/com/android/vcard/VCardEntry.java7
-rw-r--r--tests/res/raw/v30_adr_types.vcf8
-rw-r--r--tests/src/com/android/vcard/tests/VCardExporterTests.java40
-rw-r--r--tests/src/com/android/vcard/tests/VCardImporterTests.java28
-rw-r--r--tests/src/com/android/vcard/tests/VCardJapanizationTests.java5
7 files changed, 93 insertions, 1 deletions
diff --git a/java/com/android/vcard/VCardBuilder.java b/java/com/android/vcard/VCardBuilder.java
index d273347..c938d04 100644
--- a/java/com/android/vcard/VCardBuilder.java
+++ b/java/com/android/vcard/VCardBuilder.java
@@ -1489,6 +1489,10 @@ public class VCardBuilder {
break;
}
case StructuredPostal.TYPE_OTHER: {
+ // {@code TYPE_OTHER} will be treated as a "custom type" in that a "X-" will be
+ // similarly prepended. According to RFC 2426, this constitutes a valid "x-name",
+ // which constitutes a valid "adr-type".
+ parameterList.add("X-" + VCardConstants.PARAM_ADR_EXTRA_TYPE_OTHER);
break;
}
default: {
diff --git a/java/com/android/vcard/VCardConstants.java b/java/com/android/vcard/VCardConstants.java
index 67c07b7..ed0c34e 100644
--- a/java/com/android/vcard/VCardConstants.java
+++ b/java/com/android/vcard/VCardConstants.java
@@ -153,6 +153,8 @@ public class VCardConstants {
public static final String PARAM_ADR_TYPE_PARCEL = "PARCEL";
public static final String PARAM_ADR_TYPE_DOM = "DOM";
public static final String PARAM_ADR_TYPE_INTL = "INTL";
+ // {@link VCardBuilder} translates this type to "X-OTHER".
+ public static final String PARAM_ADR_EXTRA_TYPE_OTHER = "OTHER";
public static final String PARAM_LANGUAGE = "LANGUAGE";
diff --git a/java/com/android/vcard/VCardEntry.java b/java/com/android/vcard/VCardEntry.java
index ee60578..8054bb7 100644
--- a/java/com/android/vcard/VCardEntry.java
+++ b/java/com/android/vcard/VCardEntry.java
@@ -2223,6 +2223,13 @@ public class VCardEntry {
} else {
label = typeStringOrg;
}
+ // {@link ContactsContract} has a {@link StructuredPostal.TYPE_OTHER}, so
+ // if the custom type is "other", map it from {@code TYPE_CUSTOM} to
+ // {@code TYPE_OTHER}.
+ if (VCardConstants.PARAM_ADR_EXTRA_TYPE_OTHER.equals(label.toUpperCase())) {
+ type = StructuredPostal.TYPE_OTHER;
+ label = null;
+ }
}
}
}
diff --git a/tests/res/raw/v30_adr_types.vcf b/tests/res/raw/v30_adr_types.vcf
new file mode 100644
index 0000000..55dd1b4
--- /dev/null
+++ b/tests/res/raw/v30_adr_types.vcf
@@ -0,0 +1,8 @@
+BEGIN:VCARD
+VERSION:3.0
+N:Familyname;Givenname;;;
+FN:Givenname Familyname
+ADR;TYPE=WORK:;;1010 Technology Pkwy\, Silicon City\, Somecountry;;;;
+ADR;TYPE=X-Other:;;123 Main St\, Anytown\, Anywhere;;;;
+ADR;TYPE=X-School:;;112358 Academic Lane\, College Town\, Someplace Great;;;;
+END:VCARD
diff --git a/tests/src/com/android/vcard/tests/VCardExporterTests.java b/tests/src/com/android/vcard/tests/VCardExporterTests.java
index 42f9445..d83ca40 100644
--- a/tests/src/com/android/vcard/tests/VCardExporterTests.java
+++ b/tests/src/com/android/vcard/tests/VCardExporterTests.java
@@ -17,6 +17,7 @@
package com.android.vcard.tests;
import com.android.vcard.VCardConfig;
+import com.android.vcard.VCardConstants;
import com.android.vcard.tests.testutils.ContactEntry;
import com.android.vcard.tests.testutils.PropertyNodesVerifierElem;
import com.android.vcard.tests.testutils.PropertyNodesVerifierElem.TypeSet;
@@ -885,6 +886,45 @@ public class VCardExporterTests extends VCardTestsBase {
testPostalWithBothStructuredAndFormattedCommon(V40);
}
+ private void testPostalAddressTypeHandlingCommon(int vcardType) {
+ mVerifier.initForExportTest(vcardType);
+
+ ContactEntry entry = mVerifier.addInputEntry();
+ entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
+ .put(StructuredPostal.STREET, "1010 Technology Pkwy")
+ .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK);
+ entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
+ .put(StructuredPostal.STREET, "123 Main St")
+ .put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER);
+ entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
+ .put(StructuredPostal.STREET, "112358 Academic Lane")
+ .put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
+ .put(StructuredPostal.LABEL, "School");
+
+ PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName();
+ elem.addExpectedNode("ADR",
+ Arrays.asList("", "", "1010 Technology Pkwy", "", "", "", ""),
+ new TypeSet(VCardConstants.PARAM_TYPE_WORK));
+ elem.addExpectedNode("ADR",
+ Arrays.asList("", "", "123 Main St", "", "", "", ""),
+ new TypeSet("X-" + VCardConstants.PARAM_ADR_EXTRA_TYPE_OTHER));
+ elem.addExpectedNode("ADR",
+ Arrays.asList("", "", "112358 Academic Lane", "", "", "", ""),
+ new TypeSet("X-School"));
+ }
+
+ public void testPostalAddressTypeHandlingV21() {
+ testPostalAddressTypeHandlingCommon(V21);
+ }
+
+ public void testPostalAddressTypeHandlingV30() {
+ testPostalAddressTypeHandlingCommon(V30);
+ }
+
+ public void testPostalAddressTypeHandlingV40() {
+ testPostalAddressTypeHandlingCommon(V40);
+ }
+
private void testOrganizationCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
ContactEntry entry = mVerifier.addInputEntry();
diff --git a/tests/src/com/android/vcard/tests/VCardImporterTests.java b/tests/src/com/android/vcard/tests/VCardImporterTests.java
index 7b4e669..b4713d0 100644
--- a/tests/src/com/android/vcard/tests/VCardImporterTests.java
+++ b/tests/src/com/android/vcard/tests/VCardImporterTests.java
@@ -555,6 +555,34 @@ public class VCardImporterTests extends VCardTestsBase {
testComplicatedCase_Parsing(V21, R.raw.v21_complicated);
}
+ public void testV30adr_types_various() {
+ mVerifier.initForImportTest(V30, R.raw.v30_adr_types);
+ ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
+ elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.FAMILY_NAME, "Familyname")
+ .put(StructuredName.GIVEN_NAME, "Givenname")
+ .put(StructuredName.DISPLAY_NAME, "Givenname Familyname");
+ elem.addExpected(StructuredPostal.CONTENT_ITEM_TYPE)
+ .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK)
+ .put(StructuredPostal.STREET,
+ "1010 Technology Pkwy, Silicon City, Somecountry")
+ .put(StructuredPostal.FORMATTED_ADDRESS,
+ "1010 Technology Pkwy, Silicon City, Somecountry");
+ elem.addExpected(StructuredPostal.CONTENT_ITEM_TYPE)
+ .put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER)
+ .put(StructuredPostal.STREET,
+ "123 Main St, Anytown, Anywhere")
+ .put(StructuredPostal.FORMATTED_ADDRESS,
+ "123 Main St, Anytown, Anywhere");
+ elem.addExpected(StructuredPostal.CONTENT_ITEM_TYPE)
+ .put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
+ .put(StructuredPostal.LABEL, "School")
+ .put(StructuredPostal.STREET,
+ "112358 Academic Lane, College Town, Someplace Great")
+ .put(StructuredPostal.FORMATTED_ADDRESS,
+ "112358 Academic Lane, College Town, Someplace Great");
+ }
+
public void testV30ComplicatedCase_Parsing() {
testComplicatedCase_Parsing(V30, R.raw.v30_complicated);
}
diff --git a/tests/src/com/android/vcard/tests/VCardJapanizationTests.java b/tests/src/com/android/vcard/tests/VCardJapanizationTests.java
index 19f70df..5921e31 100644
--- a/tests/src/com/android/vcard/tests/VCardJapanizationTests.java
+++ b/tests/src/com/android/vcard/tests/VCardJapanizationTests.java
@@ -23,6 +23,7 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import com.android.vcard.VCardConfig;
+import com.android.vcard.VCardConstants;
import com.android.vcard.tests.testutils.ContactEntry;
import com.android.vcard.tests.testutils.ContentValuesBuilder;
import com.android.vcard.tests.testutils.PropertyNodesVerifierElem;
@@ -325,7 +326,9 @@ public class VCardJapanizationTests extends VCardTestsBase {
.addExpectedNode("X-REDUCTION", "")
.addExpectedNode("X-NO", "")
.addExpectedNode("X-DCM-HMN-MODE", "")
- .addExpectedNode("ADR", Arrays.asList("2", "", "", "", "", "", ""));
+ .addExpectedNode("ADR",
+ Arrays.asList("2", "", "", "", "", "", ""),
+ new TypeSet("X-" + VCardConstants.PARAM_ADR_EXTRA_TYPE_OTHER));
}
/**