summaryrefslogtreecommitdiffstats
path: root/core/java/android/pim
diff options
context:
space:
mode:
authorDaisuke Miyakawa <dmiyakawa@google.com>2009-11-12 11:19:06 +0900
committerDaisuke Miyakawa <dmiyakawa@google.com>2009-11-13 08:33:11 +0900
commit592988d307e8d305ca163c4e58da0fb350054194 (patch)
tree15a0e545564b17d1af7ccdfe1906adeb363298fb /core/java/android/pim
parentf18a01c77e78209b74e34d05cfb352fa4a92db5f (diff)
downloadframeworks_base-592988d307e8d305ca163c4e58da0fb350054194.zip
frameworks_base-592988d307e8d305ca163c4e58da0fb350054194.tar.gz
frameworks_base-592988d307e8d305ca163c4e58da0fb350054194.tar.bz2
Add unit tests for Japanization and fix several bugs.
Internal issue number: 2195990
Diffstat (limited to 'core/java/android/pim')
-rw-r--r--core/java/android/pim/vcard/ContactStruct.java84
-rw-r--r--core/java/android/pim/vcard/VCardComposer.java82
-rw-r--r--core/java/android/pim/vcard/VCardConfig.java39
-rw-r--r--core/java/android/pim/vcard/VCardUtils.java70
4 files changed, 167 insertions, 108 deletions
diff --git a/core/java/android/pim/vcard/ContactStruct.java b/core/java/android/pim/vcard/ContactStruct.java
index f01659e8..530d5ad 100644
--- a/core/java/android/pim/vcard/ContactStruct.java
+++ b/core/java/android/pim/vcard/ContactStruct.java
@@ -20,8 +20,10 @@ import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.OperationApplicationException;
import android.database.Cursor;
+import android.net.Uri;
import android.os.RemoteException;
import android.provider.ContactsContract;
+import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Groups;
import android.provider.ContactsContract.RawContacts;
@@ -675,16 +677,53 @@ public class ContactStruct {
*/
@SuppressWarnings("fallthrough")
private void handlePhoneticNameFromSound(List<String> elems) {
- // Family, Given, Middle. (1-3)
- // This is not from specification but mere assumption. Some Japanese phones use this order.
+ if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
+ TextUtils.isEmpty(mPhoneticMiddleName) &&
+ TextUtils.isEmpty(mPhoneticGivenName))) {
+ // This means the other properties like "X-PHONETIC-FIRST-NAME" was already found.
+ // Ignore "SOUND;X-IRMC-N".
+ return;
+ }
+
int size;
if (elems == null || (size = elems.size()) < 1) {
return;
}
+
+ // Assume that the order is "Family, Given, Middle".
+ // This is not from specification but mere assumption. Some Japanese phones use this order.
if (size > 3) {
size = 3;
}
+ if (elems.get(0).length() > 0) {
+ boolean onlyFirstElemIsNonEmpty = true;
+ for (int i = 1; i < size; i++) {
+ if (elems.get(i).length() > 0) {
+ onlyFirstElemIsNonEmpty = false;
+ break;
+ }
+ }
+ if (onlyFirstElemIsNonEmpty) {
+ final String[] namesArray = elems.get(0).split(" ");
+ final int nameArrayLength = namesArray.length;
+ if (nameArrayLength == 3) {
+ // Assume the string is "Family Middle Given".
+ mPhoneticFamilyName = namesArray[0];
+ mPhoneticMiddleName = namesArray[1];
+ mPhoneticGivenName = namesArray[2];
+ } else if (nameArrayLength == 2) {
+ // Assume the string is "Family Given" based on the Japanese mobile
+ // phones' preference.
+ mPhoneticFamilyName = namesArray[0];
+ mPhoneticGivenName = namesArray[1];
+ } else {
+ mPhoneticFullName = elems.get(0);
+ }
+ return;
+ }
+ }
+
switch (size) {
// fallthrough
case 3:
@@ -976,36 +1015,8 @@ public class ContactStruct {
if (!TextUtils.isEmpty(mFullName)) {
mDisplayName = mFullName;
} else if (!(TextUtils.isEmpty(mFamilyName) && TextUtils.isEmpty(mGivenName))) {
- StringBuilder builder = new StringBuilder();
- List<String> nameList;
- switch (VCardConfig.getNameOrderType(mVCardType)) {
- case VCardConfig.NAME_ORDER_JAPANESE:
- if (VCardUtils.containsOnlyPrintableAscii(mFamilyName) &&
- VCardUtils.containsOnlyPrintableAscii(mGivenName)) {
- nameList = Arrays.asList(mPrefix, mGivenName, mMiddleName, mFamilyName, mSuffix);
- } else {
- nameList = Arrays.asList(mPrefix, mFamilyName, mMiddleName, mGivenName, mSuffix);
- }
- break;
- case VCardConfig.NAME_ORDER_EUROPE:
- nameList = Arrays.asList(mPrefix, mMiddleName, mGivenName, mFamilyName, mSuffix);
- break;
- default:
- nameList = Arrays.asList(mPrefix, mGivenName, mMiddleName, mFamilyName, mSuffix);
- break;
- }
- boolean first = true;
- for (String namePart : nameList) {
- if (!TextUtils.isEmpty(namePart)) {
- if (first) {
- first = false;
- } else {
- builder.append(' ');
- }
- builder.append(namePart);
- }
- }
- mDisplayName = builder.toString();
+ mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
+ mFamilyName, mMiddleName, mGivenName, mPrefix, mSuffix);
} else if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
TextUtils.isEmpty(mPhoneticGivenName))) {
mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
@@ -1282,6 +1293,15 @@ public class ContactStruct {
}
}
+ public static ContactStruct buildFromResolver(ContentResolver resolver) {
+ return buildFromResolver(resolver, Contacts.CONTENT_URI);
+ }
+
+ public static ContactStruct buildFromResolver(ContentResolver resolver, Uri uri) {
+
+ return null;
+ }
+
private boolean nameFieldsAreEmpty() {
return (TextUtils.isEmpty(mFamilyName)
&& TextUtils.isEmpty(mMiddleName)
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index 980dd05..b7ad7df 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -682,10 +682,18 @@ public class VCardComposer {
final String givenName = contentValues.getAsString(StructuredName.GIVEN_NAME);
final String prefix = contentValues.getAsString(StructuredName.PREFIX);
final String suffix = contentValues.getAsString(StructuredName.SUFFIX);
+ final String phoneticFamilyName =
+ contentValues.getAsString(StructuredName.PHONETIC_FAMILY_NAME);
+ final String phoneticMiddleName =
+ contentValues.getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
+ final String phoneticGivenName =
+ contentValues.getAsString(StructuredName.PHONETIC_GIVEN_NAME);
final String displayName = contentValues.getAsString(StructuredName.DISPLAY_NAME);
return !(TextUtils.isEmpty(familyName) && TextUtils.isEmpty(middleName) &&
TextUtils.isEmpty(givenName) && TextUtils.isEmpty(prefix) &&
- TextUtils.isEmpty(suffix) && TextUtils.isEmpty(displayName));
+ TextUtils.isEmpty(suffix) && TextUtils.isEmpty(phoneticFamilyName) &&
+ TextUtils.isEmpty(phoneticMiddleName) && TextUtils.isEmpty(phoneticGivenName) &&
+ TextUtils.isEmpty(displayName));
}
private void appendStructuredNamesInternal(final StringBuilder builder,
@@ -865,17 +873,18 @@ public class VCardComposer {
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(VCARD_END_OF_LINE);
- if (mIsV30) {
- builder.append(Constants.PROPERTY_FN);
- // TODO: Not allowed formally...
- if (shouldAppendCharsetParameter(displayName)) {
- builder.append(VCARD_PARAM_SEPARATOR);
- builder.append(mVCardCharsetParameter);
- }
- builder.append(VCARD_DATA_SEPARATOR);
- builder.append(encodedDisplayName);
- builder.append(VCARD_END_OF_LINE);
+ builder.append(Constants.PROPERTY_FN);
+
+ // Note: "CHARSET" param is not allowed in vCard 3.0, but we may add it
+ // when it would be useful for external importers, assuming no external
+ // importer allows this vioration.
+ if (shouldAppendCharsetParameter(displayName)) {
+ builder.append(VCARD_PARAM_SEPARATOR);
+ builder.append(mVCardCharsetParameter);
}
+ builder.append(VCARD_DATA_SEPARATOR);
+ builder.append(encodedDisplayName);
+ builder.append(VCARD_END_OF_LINE);
} else if (mIsV30) {
// vCard 3.0 specification requires these fields.
appendVCardLine(builder, Constants.PROPERTY_N, "");
@@ -913,15 +922,12 @@ public class VCardComposer {
.constructNameFromElements(mVCardType,
phoneticFamilyName, phoneticMiddleName, phoneticGivenName);
builder.append(Constants.PROPERTY_SORT_STRING);
-
- // Do not need to care about QP, since vCard 3.0 does not allow it.
- final String encodedSortString = escapeCharacters(sortString);
- if (shouldAppendCharsetParameter(encodedSortString)) {
+ if (shouldAppendCharsetParameter(sortString)) {
builder.append(VCARD_PARAM_SEPARATOR);
builder.append(mVCardCharsetParameter);
}
builder.append(VCARD_DATA_SEPARATOR);
- builder.append(encodedSortString);
+ builder.append(escapeCharacters(sortString));
builder.append(VCARD_END_OF_LINE);
} else if (mIsJapaneseMobilePhone) {
// Note: There is no appropriate property for expressing
@@ -964,11 +970,31 @@ public class VCardComposer {
builder.append(mVCardCharsetParameter);
}
builder.append(VCARD_DATA_SEPARATOR);
- builder.append(encodedPhoneticFamilyName);
+ // DoCoMo's specification requires vCard composer to use just the first
+ // column.
+ {
+ boolean first = true;
+ if (!TextUtils.isEmpty(encodedPhoneticFamilyName)) {
+ builder.append(encodedPhoneticFamilyName);
+ first = false;
+ }
+ if (!TextUtils.isEmpty(encodedPhoneticMiddleName)) {
+ if (first) {
+ first = false;
+ } else {
+ builder.append(' ');
+ }
+ builder.append(encodedPhoneticMiddleName);
+ }
+ if (!TextUtils.isEmpty(encodedPhoneticGivenName)) {
+ if (!first) {
+ builder.append(' ');
+ }
+ builder.append(encodedPhoneticGivenName);
+ }
+ }
builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(encodedPhoneticGivenName);
builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(encodedPhoneticMiddleName);
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(VCARD_END_OF_LINE);
@@ -988,7 +1014,8 @@ public class VCardComposer {
if (mUsesDefactProperty) {
if (!TextUtils.isEmpty(phoneticGivenName)) {
final boolean reallyUseQuotedPrintable =
- !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticGivenName);
+ (mUsesQuotedPrintable &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticGivenName));
final String encodedPhoneticGivenName;
if (reallyUseQuotedPrintable) {
encodedPhoneticGivenName = encodeQuotedPrintable(phoneticGivenName);
@@ -996,7 +1023,7 @@ public class VCardComposer {
encodedPhoneticGivenName = escapeCharacters(phoneticGivenName);
}
builder.append(Constants.PROPERTY_X_PHONETIC_FIRST_NAME);
- if (shouldAppendCharsetParameter(encodedPhoneticGivenName)) {
+ if (shouldAppendCharsetParameter(phoneticGivenName)) {
builder.append(VCARD_PARAM_SEPARATOR);
builder.append(mVCardCharsetParameter);
}
@@ -1010,7 +1037,8 @@ public class VCardComposer {
}
if (!TextUtils.isEmpty(phoneticMiddleName)) {
final boolean reallyUseQuotedPrintable =
- !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticMiddleName);
+ (mUsesQuotedPrintable &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticMiddleName));
final String encodedPhoneticMiddleName;
if (reallyUseQuotedPrintable) {
encodedPhoneticMiddleName = encodeQuotedPrintable(phoneticMiddleName);
@@ -1018,7 +1046,7 @@ public class VCardComposer {
encodedPhoneticMiddleName = escapeCharacters(phoneticMiddleName);
}
builder.append(Constants.PROPERTY_X_PHONETIC_MIDDLE_NAME);
- if (shouldAppendCharsetParameter(encodedPhoneticMiddleName)) {
+ if (shouldAppendCharsetParameter(phoneticMiddleName)) {
builder.append(VCARD_PARAM_SEPARATOR);
builder.append(mVCardCharsetParameter);
}
@@ -1032,7 +1060,8 @@ public class VCardComposer {
}
if (!TextUtils.isEmpty(phoneticFamilyName)) {
final boolean reallyUseQuotedPrintable =
- !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticFamilyName);
+ (mUsesQuotedPrintable &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticFamilyName));
final String encodedPhoneticFamilyName;
if (reallyUseQuotedPrintable) {
encodedPhoneticFamilyName = encodeQuotedPrintable(phoneticFamilyName);
@@ -1040,7 +1069,7 @@ public class VCardComposer {
encodedPhoneticFamilyName = escapeCharacters(phoneticFamilyName);
}
builder.append(Constants.PROPERTY_X_PHONETIC_LAST_NAME);
- if (shouldAppendCharsetParameter(encodedPhoneticFamilyName)) {
+ if (shouldAppendCharsetParameter(phoneticFamilyName)) {
builder.append(VCARD_PARAM_SEPARATOR);
builder.append(mVCardCharsetParameter);
}
@@ -2255,8 +2284,7 @@ public class VCardComposer {
* to know this text is NOT UTF-8 but Shift_Jis.
*/
private boolean shouldAppendCharsetParameter(final String propertyValue) {
- return (!VCardUtils.containsOnlyPrintableAscii(propertyValue) &&
- (!mIsV30 || !mUsesUtf8));
+ return (!(mIsV30 && mUsesUtf8) && !VCardUtils.containsOnlyPrintableAscii(propertyValue));
}
private boolean shouldAppendCharsetParameters(final List<String> propertyValueList) {
diff --git a/core/java/android/pim/vcard/VCardConfig.java b/core/java/android/pim/vcard/VCardConfig.java
index 545c09b..fff4c82 100644
--- a/core/java/android/pim/vcard/VCardConfig.java
+++ b/core/java/android/pim/vcard/VCardConfig.java
@@ -60,7 +60,8 @@ public class VCardConfig {
// 0x10 is reserved for safety
private static final int FLAG_CHARSET_UTF8 = 0;
- private static final int FLAG_CHARSET_SHIFT_JIS = 0x20;
+ private static final int FLAG_CHARSET_SHIFT_JIS = 0x100;
+ private static final int FLAG_CHARSET_MASK = 0xF00;
/**
* The flag indicating the vCard composer will add some "X-" properties used only in Android
@@ -349,8 +350,8 @@ public class VCardConfig {
sJapaneseMobileTypeSet.add(VCARD_TYPE_DOCOMO);
}
- public static int getVCardTypeFromString(String vcardTypeString) {
- String loweredKey = vcardTypeString.toLowerCase();
+ public static int getVCardTypeFromString(final String vcardTypeString) {
+ final String loweredKey = vcardTypeString.toLowerCase();
if (sVCardTypeMap.containsKey(loweredKey)) {
return sVCardTypeMap.get(loweredKey);
} else {
@@ -360,31 +361,31 @@ public class VCardConfig {
}
}
- public static boolean isV30(int vcardType) {
+ public static boolean isV30(final int vcardType) {
return ((vcardType & FLAG_V30) != 0);
}
- public static boolean usesQuotedPrintable(int vcardType) {
+ public static boolean usesQuotedPrintable(final int vcardType) {
return !isV30(vcardType);
}
- public static boolean usesUtf8(int vcardType) {
- return ((vcardType & FLAG_CHARSET_UTF8) != 0);
+ public static boolean usesUtf8(final int vcardType) {
+ return ((vcardType & FLAG_CHARSET_MASK) == FLAG_CHARSET_UTF8);
}
- public static boolean usesShiftJis(int vcardType) {
- return ((vcardType & FLAG_CHARSET_SHIFT_JIS) != 0);
+ public static boolean usesShiftJis(final int vcardType) {
+ return ((vcardType & FLAG_CHARSET_MASK) == FLAG_CHARSET_SHIFT_JIS);
}
-
- public static int getNameOrderType(int vcardType) {
+
+ public static int getNameOrderType(final int vcardType) {
return vcardType & NAME_ORDER_MASK;
}
- public static boolean usesAndroidSpecificProperty(int vcardType) {
+ public static boolean usesAndroidSpecificProperty(final int vcardType) {
return ((vcardType & FLAG_USE_ANDROID_PROPERTY) != 0);
}
- public static boolean usesDefactProperty(int vcardType) {
+ public static boolean usesDefactProperty(final int vcardType) {
return ((vcardType & FLAG_USE_DEFACT_PROPERTY) != 0);
}
@@ -392,12 +393,12 @@ public class VCardConfig {
return (VCardConfig.LOG_LEVEL & VCardConfig.LOG_LEVEL_PERFORMANCE_MEASUREMENT) != 0;
}
- public static boolean refrainsQPToPrimaryProperties(int vcardType) {
+ public static boolean refrainsQPToPrimaryProperties(final int vcardType) {
return (!usesQuotedPrintable(vcardType) ||
((vcardType & FLAG_REFRAIN_QP_TO_PRIMARY_PROPERTIES) != 0));
}
- public static boolean appendTypeParamName(int vcardType) {
+ public static boolean appendTypeParamName(final int vcardType) {
return (isV30(vcardType) || ((vcardType & FLAG_APPEND_TYPE_PARAM) != 0));
}
@@ -405,19 +406,19 @@ public class VCardConfig {
* @return true if the device is Japanese and some Japanese convension is
* applied to creating "formatted" something like FORMATTED_ADDRESS.
*/
- public static boolean isJapaneseDevice(int vcardType) {
+ public static boolean isJapaneseDevice(final int vcardType) {
return sJapaneseMobileTypeSet.contains(vcardType);
}
- public static boolean needsToConvertPhoneticString(int vcardType) {
+ public static boolean needsToConvertPhoneticString(final int vcardType) {
return ((vcardType & FLAG_CONVERT_PHONETIC_NAME_STRINGS) != 0);
}
- public static boolean onlyOneNoteFieldIsAvailable(int vcardType) {
+ public static boolean onlyOneNoteFieldIsAvailable(final int vcardType) {
return vcardType == VCARD_TYPE_DOCOMO;
}
- public static boolean isDoCoMo(int vcardType) {
+ public static boolean isDoCoMo(final int vcardType) {
return ((vcardType & FLAG_DOCOMO) != 0);
}
diff --git a/core/java/android/pim/vcard/VCardUtils.java b/core/java/android/pim/vcard/VCardUtils.java
index 9e5dbb5..00679bd 100644
--- a/core/java/android/pim/vcard/VCardUtils.java
+++ b/core/java/android/pim/vcard/VCardUtils.java
@@ -23,6 +23,7 @@ import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
+import android.util.Log;
import java.util.ArrayList;
import java.util.Collection;
@@ -181,26 +182,36 @@ public class VCardUtils {
sPhoneTypesSetUnknownToContacts.contains(phoneType));
}
- public static String[] sortNameElements(int vcardType,
- String familyName, String middleName, String givenName) {
- String[] list = new String[3];
- switch (VCardConfig.getNameOrderType(vcardType)) {
- case VCardConfig.NAME_ORDER_JAPANESE:
- // TODO: Should handle Ascii case?
- list[0] = familyName;
- list[1] = middleName;
- list[2] = givenName;
- break;
- case VCardConfig.NAME_ORDER_EUROPE:
- list[0] = middleName;
- list[1] = givenName;
- list[2] = familyName;
- break;
- default:
- list[0] = givenName;
- list[1] = middleName;
- list[2] = familyName;
- break;
+ public static String[] sortNameElements(final int vcardType,
+ final String familyName, final String middleName, final String givenName) {
+ final String[] list = new String[3];
+ final int nameOrderType = VCardConfig.getNameOrderType(vcardType);
+ switch (nameOrderType) {
+ case VCardConfig.NAME_ORDER_JAPANESE: {
+ if (containsOnlyPrintableAscii(familyName) &&
+ containsOnlyPrintableAscii(givenName)) {
+ list[0] = givenName;
+ list[1] = middleName;
+ list[2] = familyName;
+ } else {
+ list[0] = familyName;
+ list[1] = middleName;
+ list[2] = givenName;
+ }
+ break;
+ }
+ case VCardConfig.NAME_ORDER_EUROPE: {
+ list[0] = middleName;
+ list[1] = givenName;
+ list[2] = familyName;
+ break;
+ }
+ default: {
+ list[0] = givenName;
+ list[1] = middleName;
+ list[2] = familyName;
+ break;
+ }
}
return list;
}
@@ -302,24 +313,23 @@ public class VCardUtils {
return dataArray;
}
- public static String constructNameFromElements(int nameOrderType,
- String familyName, String middleName, String givenName) {
- return constructNameFromElements(nameOrderType, familyName, middleName, givenName,
+ public static String constructNameFromElements(final int vcardType,
+ final String familyName, final String middleName, final String givenName) {
+ return constructNameFromElements(vcardType, familyName, middleName, givenName,
null, null);
}
- public static String constructNameFromElements(int nameOrderType,
- String familyName, String middleName, String givenName,
- String prefix, String suffix) {
- StringBuilder builder = new StringBuilder();
- String[] nameList = sortNameElements(nameOrderType,
- familyName, middleName, givenName);
+ public static String constructNameFromElements(final int vcardType,
+ final String familyName, final String middleName, final String givenName,
+ final String prefix, final String suffix) {
+ final StringBuilder builder = new StringBuilder();
+ final String[] nameList = sortNameElements(vcardType, familyName, middleName, givenName);
boolean first = true;
if (!TextUtils.isEmpty(prefix)) {
first = false;
builder.append(prefix);
}
- for (String namePart : nameList) {
+ for (final String namePart : nameList) {
if (!TextUtils.isEmpty(namePart)) {
if (first) {
first = false;