Fix missing encoding attribute on FN field.
When FN field is built from display name, the encoding attribute is missing.
Created common method to build N and FN fields so they will not be out of
sync in the future.
Bug: 7292017
Change-Id: I7faceb316b639d626a54bdd455df1e748b22face
diff --git a/java/com/android/vcard/VCardBuilder.java b/java/com/android/vcard/VCardBuilder.java
index bd1e09d..ce97f46 100644
--- a/java/com/android/vcard/VCardBuilder.java
+++ b/java/com/android/vcard/VCardBuilder.java
@@ -15,8 +15,6 @@
*/
package com.android.vcard;
-import com.android.vcard.VCardUtils.PhoneNumberUtilsPort;
-
import android.content.ContentValues;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
@@ -36,6 +34,8 @@
import android.util.Base64;
import android.util.Log;
+import com.android.vcard.VCardUtils.PhoneNumberUtilsPort;
+
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -85,7 +85,7 @@
private static final String VCARD_DATA_PUBLIC = "PUBLIC";
private static final String VCARD_PARAM_SEPARATOR = ";";
- private static final String VCARD_END_OF_LINE = "\r\n";
+ public static final String VCARD_END_OF_LINE = "\r\n";
private static final String VCARD_DATA_SEPARATOR = ":";
private static final String VCARD_ITEM_SEPARATOR = ";";
private static final String VCARD_WS = " ";
@@ -535,45 +535,13 @@
mBuilder.append(encodedFormattedname);
mBuilder.append(VCARD_END_OF_LINE);
} else if (!TextUtils.isEmpty(displayName)) {
- final boolean reallyUseQuotedPrintableToDisplayName =
- (!mRefrainsQPToNameProperties &&
- !VCardUtils.containsOnlyNonCrLfPrintableAscii(displayName));
- final String encodedDisplayName =
- reallyUseQuotedPrintableToDisplayName ?
- encodeQuotedPrintable(displayName) :
- escapeCharacters(displayName);
// N
- mBuilder.append(VCardConstants.PROPERTY_N);
- if (shouldAppendCharsetParam(displayName)) {
- mBuilder.append(VCARD_PARAM_SEPARATOR);
- mBuilder.append(mVCardCharsetParameter);
- }
- if (reallyUseQuotedPrintableToDisplayName) {
- mBuilder.append(VCARD_PARAM_SEPARATOR);
- mBuilder.append(VCARD_PARAM_ENCODING_QP);
- }
- mBuilder.append(VCARD_DATA_SEPARATOR);
- mBuilder.append(encodedDisplayName);
- mBuilder.append(VCARD_ITEM_SEPARATOR);
- mBuilder.append(VCARD_ITEM_SEPARATOR);
- mBuilder.append(VCARD_ITEM_SEPARATOR);
- mBuilder.append(VCARD_ITEM_SEPARATOR);
- mBuilder.append(VCARD_END_OF_LINE);
+ buildSinglePartNameField(VCardConstants.PROPERTY_N, displayName);
// FN
- mBuilder.append(VCardConstants.PROPERTY_FN);
+ buildSinglePartNameField(VCardConstants.PROPERTY_FN, displayName);
- // Note: "CHARSET" param is not allowed in vCard 3.0, but we may add it
- // when it would be useful or necessary for external importers,
- // assuming the external importer allows this vioration of the spec.
- if (shouldAppendCharsetParam(displayName)) {
- mBuilder.append(VCARD_PARAM_SEPARATOR);
- mBuilder.append(mVCardCharsetParameter);
- }
- mBuilder.append(VCARD_DATA_SEPARATOR);
- mBuilder.append(encodedDisplayName);
- mBuilder.append(VCARD_END_OF_LINE);
} else if (VCardConfig.isVersion30(mVCardType)) {
appendLine(VCardConstants.PROPERTY_N, "");
appendLine(VCardConstants.PROPERTY_FN, "");
@@ -585,6 +553,36 @@
return this;
}
+ private void buildSinglePartNameField(String property, String part) {
+ final boolean reallyUseQuotedPrintable =
+ (!mRefrainsQPToNameProperties &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(part));
+ final String encodedPart = reallyUseQuotedPrintable ?
+ encodeQuotedPrintable(part) :
+ escapeCharacters(part);
+
+ mBuilder.append(property);
+
+ // Note: "CHARSET" param is not allowed in vCard 3.0, but we may add it
+ // when it would be useful or necessary for external importers,
+ // assuming the external importer allows this vioration of the spec.
+ if (shouldAppendCharsetParam(part)) {
+ mBuilder.append(VCARD_PARAM_SEPARATOR);
+ mBuilder.append(mVCardCharsetParameter);
+ }
+ if (reallyUseQuotedPrintable) {
+ mBuilder.append(VCARD_PARAM_SEPARATOR);
+ mBuilder.append(VCARD_PARAM_ENCODING_QP);
+ }
+ mBuilder.append(VCARD_DATA_SEPARATOR);
+ mBuilder.append(encodedPart);
+ mBuilder.append(VCARD_ITEM_SEPARATOR);
+ mBuilder.append(VCARD_ITEM_SEPARATOR);
+ mBuilder.append(VCARD_ITEM_SEPARATOR);
+ mBuilder.append(VCARD_ITEM_SEPARATOR);
+ mBuilder.append(VCARD_END_OF_LINE);
+ }
+
/**
* Emits SOUND;IRMC, SORT-STRING, and de-fact values for phonetic names like X-PHONETIC-FAMILY.
*/
diff --git a/tests/src/com/android/vcard/tests/VCardBuilderTest.java b/tests/src/com/android/vcard/tests/VCardBuilderTest.java
new file mode 100644
index 0000000..e86ca33
--- /dev/null
+++ b/tests/src/com/android/vcard/tests/VCardBuilderTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 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.vcard.tests;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+
+import com.android.vcard.VCardBuilder;
+import com.android.vcard.VCardConfig;
+import com.google.android.collect.Lists;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+
+/**
+ * Unit test for VCardBuilder.
+ */
+public class VCardBuilderTest extends TestCase {
+
+ public void testVCardNameFieldFromDisplayName() {
+ final ArrayList<ContentValues> contentList = Lists.newArrayList();
+
+ final ContentValues values = new ContentValues();
+ values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "ने");
+ contentList.add(values);
+
+ final VCardBuilder builder = new VCardBuilder(VCardConfig.VCARD_TYPE_DEFAULT);
+ builder.appendNameProperties(contentList);
+ final String actual = builder.toString();
+
+ final String expectedCommon = ";CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:" +
+ "=E0=A4=A8=E0=A5=87;;;;";
+
+ final String expectedName = "N" + expectedCommon;
+ final String expectedFullName = "FN" + expectedCommon;
+
+ assertTrue("Actual value:\n" + actual + " expected to contain\n" + expectedName +
+ "\nbut does not.", actual.contains(expectedName));
+ assertTrue("Actual value:\n" + actual + " expected to contain\n" + expectedFullName +
+ "\nbut does not.", actual.contains(expectedFullName));
+ }
+}
+
diff --git a/tests/src/com/android/vcard/tests/VCardTestRunner.java b/tests/src/com/android/vcard/tests/VCardTestRunner.java
index e8ccae9..a220a58 100644
--- a/tests/src/com/android/vcard/tests/VCardTestRunner.java
+++ b/tests/src/com/android/vcard/tests/VCardTestRunner.java
@@ -27,6 +27,7 @@
@Override
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(VCardBuilderTest.class);
suite.addTestSuite(VCardEntryTests.class);
suite.addTestSuite(VCardParserTests.class);
suite.addTestSuite(VCardUtilsTests.class);
@@ -42,4 +43,4 @@
public ClassLoader getLoader() {
return VCardTestRunner.class.getClassLoader();
}
-}
\ No newline at end of file
+}