Merge change I170c8251 into eclair-mr2
* changes: Add tests and fix vCard code.
This commit is contained in:
@@ -56,7 +56,7 @@ package android.pim.vcard;
|
||||
public static final String PROPERTY_X_PHONETIC_MIDDLE_NAME = "X-PHONETIC-MIDDLE-NAME";
|
||||
public static final String PROPERTY_X_PHONETIC_LAST_NAME = "X-PHONETIC-LAST-NAME";
|
||||
|
||||
// Properties both the current (as of 2009-08-17) ContactsStruct and de-fact vCard extensions
|
||||
// Properties both ContactsStruct in Eclair and de-fact vCard extensions
|
||||
// shown in http://en.wikipedia.org/wiki/VCard support are defined here.
|
||||
public static final String PROPERTY_X_AIM = "X-AIM";
|
||||
public static final String PROPERTY_X_MSN = "X-MSN";
|
||||
@@ -65,15 +65,12 @@ package android.pim.vcard;
|
||||
public static final String PROPERTY_X_JABBER = "X-JABBER";
|
||||
public static final String PROPERTY_X_GOOGLE_TALK = "X-GOOGLE-TALK";
|
||||
public static final String PROPERTY_X_SKYPE_USERNAME = "X-SKYPE-USERNAME";
|
||||
// Properties only ContactsStruct has. We alse use this.
|
||||
public static final String PROPERTY_X_QQ = "X-QQ";
|
||||
public static final String PROPERTY_X_NETMEETING = "X-NETMEETING";
|
||||
|
||||
// Phone number for Skype, available as usual phone.
|
||||
public static final String PROPERTY_X_SKYPE_PSTNNUMBER = "X-SKYPE-PSTNNUMBER";
|
||||
// Some device emits this "X-" attribute, which is specifically invalid but should be
|
||||
// always properly accepted, and emitted in some special case (for that device/application).
|
||||
public static final String PROPERTY_X_GOOGLE_TALK_WITH_SPACE = "X-GOOGLE TALK";
|
||||
|
||||
// Android specific properties
|
||||
// Use only in vCard paser code.
|
||||
public static final String PROPERTY_X_NICKNAME = "X-NICKNAME";
|
||||
|
||||
// Properties for DoCoMo vCard.
|
||||
public static final String PROPERTY_X_CLASS = "X-CLASS";
|
||||
@@ -81,6 +78,11 @@ package android.pim.vcard;
|
||||
public static final String PROPERTY_X_NO = "X-NO";
|
||||
public static final String PROPERTY_X_DCM_HMN_MODE = "X-DCM-HMN-MODE";
|
||||
|
||||
// For some historical reason, we often use the term "ATTR"/"attribute" especially toward
|
||||
// what is called "param" in both vCard specs, while vCard, while vCard importer side uses
|
||||
// "param".
|
||||
//
|
||||
// TODO: Confusing. Fix it.
|
||||
public static final String ATTR_TYPE = "TYPE";
|
||||
|
||||
// How more than one TYPE fields are expressed is different between vCard 2.1 and vCard 3.0
|
||||
@@ -102,13 +104,19 @@ package android.pim.vcard;
|
||||
public static final String ATTR_TYPE_VOICE = "VOICE";
|
||||
public static final String ATTR_TYPE_INTERNET = "INTERNET";
|
||||
|
||||
// Abbreviation of "preferable"? We interpret this value as "primary" property.
|
||||
// Abbreviation of "prefered" according to vCard 2.1 specification.
|
||||
// We interpret this value as "primary" property during import/export.
|
||||
//
|
||||
// Note: Both vCard specs does anything about the requirement about this attribute,
|
||||
// but there may be some vCard importer which will get confused with more than
|
||||
// one "PREF"s in one property name, while Android accepts them.
|
||||
public static final String ATTR_TYPE_PREF = "PREF";
|
||||
|
||||
// Phone types valid in vCard and known to ContactsContract, but not so common.
|
||||
public static final String ATTR_TYPE_CAR = "CAR";
|
||||
public static final String ATTR_TYPE_ISDN = "ISDN";
|
||||
public static final String ATTR_TYPE_PAGER = "PAGER";
|
||||
public static final String ATTR_TYPE_TLX = "TLX"; // Telex
|
||||
|
||||
// Phone types existing in vCard 2.1 but not known to ContactsContract.
|
||||
// TODO: should make parser make these TYPE_CUSTOM.
|
||||
@@ -118,16 +126,16 @@ package android.pim.vcard;
|
||||
public static final String ATTR_TYPE_VIDEO = "VIDEO";
|
||||
|
||||
// Attribute for Phones, which are not formally valid in vCard (at least 2.1).
|
||||
// These types are encoded to "X-" attributes when composing vCard for now.
|
||||
// Parser passes these even if "X-" is added to the attribute.
|
||||
public static final String ATTR_PHONE_EXTRA_TYPE_OTHER = "OTHER";
|
||||
// These types are basically encoded to "X-" attributes when composing vCard.
|
||||
// Parser passes these when "X-" is added to the attribute or not.
|
||||
public static final String ATTR_PHONE_EXTRA_TYPE_CALLBACK = "CALLBACK";
|
||||
// TODO: may be "TYPE=COMPANY,PREF", not "COMPANY-MAIN".
|
||||
public static final String ATTR_PHONE_EXTRA_TYPE_COMPANY_MAIN = "COMPANY-MAIN";
|
||||
public static final String ATTR_PHONE_EXTRA_TYPE_RADIO = "RADIO";
|
||||
public static final String ATTR_PHONE_EXTRA_TYPE_TELEX = "TELEX";
|
||||
public static final String ATTR_PHONE_EXTRA_TYPE_TTY_TDD = "TTY-TDD";
|
||||
public static final String ATTR_PHONE_EXTRA_TYPE_ASSISTANT = "ASSISTANT";
|
||||
// vCard composer translates this type to "WORK" + "PREF". Just for parsing.
|
||||
public static final String ATTR_PHONE_EXTRA_TYPE_COMPANY_MAIN = "COMPANY-MAIN";
|
||||
// vCard composer translates this type to "VOICE" Just for parsing.
|
||||
public static final String ATTR_PHONE_EXTRA_TYPE_OTHER = "OTHER";
|
||||
|
||||
// Attribute for addresses.
|
||||
public static final String ATTR_ADR_TYPE_PARCEL = "PARCEL";
|
||||
@@ -142,6 +150,14 @@ package android.pim.vcard;
|
||||
// vCard 3.0.
|
||||
public static final String ATTR_TYPE_X_IRMC_N = "X-IRMC-N";
|
||||
|
||||
public interface ImportOnly {
|
||||
public static final String PROPERTY_X_NICKNAME = "X-NICKNAME";
|
||||
// Some device emits this "X-" attribute for expressing Google Talk,
|
||||
// which is specifically invalid but should be always properly accepted, and emitted
|
||||
// in some special case (for that device/application).
|
||||
public static final String PROPERTY_X_GOOGLE_TALK_WITH_SPACE = "X-GOOGLE TALK";
|
||||
}
|
||||
|
||||
private Constants() {
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,8 @@ public class ContactStruct {
|
||||
sImMap.put(Constants.PROPERTY_X_JABBER, Im.PROTOCOL_JABBER);
|
||||
sImMap.put(Constants.PROPERTY_X_SKYPE_USERNAME, Im.PROTOCOL_SKYPE);
|
||||
sImMap.put(Constants.PROPERTY_X_GOOGLE_TALK, Im.PROTOCOL_GOOGLE_TALK);
|
||||
sImMap.put(Constants.PROPERTY_X_GOOGLE_TALK_WITH_SPACE, Im.PROTOCOL_GOOGLE_TALK);
|
||||
sImMap.put(Constants.ImportOnly.PROPERTY_X_GOOGLE_TALK_WITH_SPACE,
|
||||
Im.PROTOCOL_GOOGLE_TALK);
|
||||
}
|
||||
|
||||
static public class PhoneData {
|
||||
@@ -292,16 +293,18 @@ public class ContactStruct {
|
||||
}
|
||||
|
||||
static public class ImData {
|
||||
public final int protocol;
|
||||
public final String customProtocol;
|
||||
public final int type;
|
||||
public final String data;
|
||||
public final String label;
|
||||
public final boolean isPrimary;
|
||||
|
||||
// TODO: ContactsConstant#PROTOCOL, ContactsConstant#CUSTOM_PROTOCOL should be used?
|
||||
public ImData(int type, String data, String label, boolean isPrimary) {
|
||||
public ImData(int protocol, String customProtocol, int type,
|
||||
String data, boolean isPrimary) {
|
||||
this.protocol = protocol;
|
||||
this.customProtocol = customProtocol;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
this.label = label;
|
||||
this.isPrimary = isPrimary;
|
||||
}
|
||||
|
||||
@@ -311,14 +314,18 @@ public class ContactStruct {
|
||||
return false;
|
||||
}
|
||||
ImData imData = (ImData)obj;
|
||||
return (type == imData.type && data.equals(imData.data) &&
|
||||
label.equals(imData.label) && isPrimary == imData.isPrimary);
|
||||
return (type == imData.type && protocol == imData.protocol
|
||||
&& (customProtocol != null ? customProtocol.equals(imData.customProtocol) :
|
||||
(imData.customProtocol == null))
|
||||
&& (data != null ? data.equals(imData.data) : (imData.data == null))
|
||||
&& isPrimary == imData.isPrimary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("type: %d, data: %s, label: %s, isPrimary: %s",
|
||||
type, data, label, isPrimary);
|
||||
return String.format(
|
||||
"type: %d, protocol: %d, custom_protcol: %s, data: %s, isPrimary: %s",
|
||||
type, protocol, customProtocol, data, isPrimary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +447,7 @@ public class ContactStruct {
|
||||
private final Account mAccount;
|
||||
|
||||
public ContactStruct() {
|
||||
this(VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
this(VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
}
|
||||
|
||||
public ContactStruct(int vcardType) {
|
||||
@@ -619,11 +626,12 @@ public class ContactStruct {
|
||||
addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, false);
|
||||
}
|
||||
|
||||
private void addIm(int type, String data, String label, boolean isPrimary) {
|
||||
private void addIm(int protocol, String customProtocol, int type,
|
||||
String propValue, boolean isPrimary) {
|
||||
if (mImList == null) {
|
||||
mImList = new ArrayList<ImData>();
|
||||
}
|
||||
mImList.add(new ImData(type, data, label, isPrimary));
|
||||
mImList.add(new ImData(protocol, customProtocol, type, propValue, isPrimary));
|
||||
}
|
||||
|
||||
private void addNote(final String note) {
|
||||
@@ -720,7 +728,7 @@ public class ContactStruct {
|
||||
} else if (propName.equals(Constants.PROPERTY_NICKNAME)) {
|
||||
mPhoneticFullName = propValue;
|
||||
} else if (propName.equals(Constants.PROPERTY_NICKNAME) ||
|
||||
propName.equals(Constants.PROPERTY_X_NICKNAME)) {
|
||||
propName.equals(Constants.ImportOnly.PROPERTY_X_NICKNAME)) {
|
||||
addNickName(propValue);
|
||||
} else if (propName.equals(Constants.PROPERTY_SOUND)) {
|
||||
Collection<String> typeCollection = paramMap.get(Constants.ATTR_TYPE);
|
||||
@@ -891,25 +899,28 @@ public class ContactStruct {
|
||||
isPrimary = false;
|
||||
}
|
||||
addPhone(type, propValue, label, isPrimary);
|
||||
} else if (sImMap.containsKey(propName)){
|
||||
int type = sImMap.get(propName);
|
||||
} else if (sImMap.containsKey(propName)) {
|
||||
final int protocol = sImMap.get(propName);
|
||||
boolean isPrimary = false;
|
||||
int type = -1;
|
||||
final Collection<String> typeCollection = paramMap.get(Constants.ATTR_TYPE);
|
||||
if (typeCollection != null) {
|
||||
for (String typeString : typeCollection) {
|
||||
if (typeString.equals(Constants.ATTR_TYPE_PREF)) {
|
||||
isPrimary = true;
|
||||
} else if (typeString.equalsIgnoreCase(Constants.ATTR_TYPE_HOME)) {
|
||||
type = Phone.TYPE_HOME;
|
||||
} else if (typeString.equalsIgnoreCase(Constants.ATTR_TYPE_WORK)) {
|
||||
type = Phone.TYPE_WORK;
|
||||
} else if (type < 0) {
|
||||
if (typeString.equalsIgnoreCase(Constants.ATTR_TYPE_HOME)) {
|
||||
type = Im.TYPE_HOME;
|
||||
} else if (typeString.equalsIgnoreCase(Constants.ATTR_TYPE_WORK)) {
|
||||
type = Im.TYPE_WORK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type < 0) {
|
||||
type = Phone.TYPE_HOME;
|
||||
}
|
||||
addIm(type, propValue, null, isPrimary);
|
||||
addIm(protocol, null, type, propValue, isPrimary);
|
||||
} else if (propName.equals(Constants.PROPERTY_NOTE)) {
|
||||
addNote(propValue);
|
||||
} else if (propName.equals(Constants.PROPERTY_URL)) {
|
||||
@@ -1158,10 +1169,10 @@ public class ContactStruct {
|
||||
builder.withValueBackReference(Im.RAW_CONTACT_ID, 0);
|
||||
builder.withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
|
||||
builder.withValue(Im.TYPE, imData.type);
|
||||
if (imData.type == Im.TYPE_CUSTOM) {
|
||||
builder.withValue(Im.LABEL, imData.label);
|
||||
builder.withValue(Im.PROTOCOL, imData.protocol);
|
||||
if (imData.protocol == Im.PROTOCOL_CUSTOM) {
|
||||
builder.withValue(Im.CUSTOM_PROTOCOL, imData.customProtocol);
|
||||
}
|
||||
builder.withValue(Im.DATA, imData.data);
|
||||
if (imData.isPrimary) {
|
||||
builder.withValue(Data.IS_PRIMARY, 1);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,14 +15,20 @@
|
||||
*/
|
||||
package android.pim.vcard;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The class representing VCard related configurations. Useful static methods are not in this class
|
||||
* but in VCardUtils.
|
||||
*/
|
||||
public class VCardConfig {
|
||||
private static final String LOG_TAG = "vcard.VCardConfig";
|
||||
|
||||
// TODO: may be better to make the instance of this available and stop using static methods and
|
||||
// one integer.
|
||||
|
||||
@@ -95,18 +101,63 @@ public class VCardConfig {
|
||||
private static final int FLAG_DOCOMO = 0x20000000;
|
||||
|
||||
/**
|
||||
* The flag indicating the vCard composer use Quoted-Printable toward even "primary" types.
|
||||
* In this context, "primary" types means "N", "FN", etc. which are usually "not" encoded
|
||||
* into Quoted-Printable format in external exporters.
|
||||
* This flag is useful when some target importer does not accept "primary" property values
|
||||
* without Quoted-Printable encoding.
|
||||
*
|
||||
* @hide Temporaly made public. We don't strictly define "primary", so we may change the
|
||||
* behavior around this flag in the future. Do not use this flag without any reason.
|
||||
* <P>
|
||||
* The flag indicating the vCard composer does "NOT" use Quoted-Printable toward "primary"
|
||||
* properties even though it is required by vCard 2.1 (QP is prohibited in vCard 3.0).
|
||||
* </P>
|
||||
* <P>
|
||||
* We actually cannot define what is the "primary" property. Note that this is NOT defined
|
||||
* in vCard specification either. Also be aware that it is NOT related to "primary" notion
|
||||
* used in {@link android.provider.ContactsContract}.
|
||||
* This notion is just for vCard composition in Android.
|
||||
* </P>
|
||||
* <P>
|
||||
* We added this Android-specific notion since some (incomplete) vCard exporters for vCard 2.1
|
||||
* do NOT use Quoted-Printable encoding toward some properties like "N", "FN", etc. even when
|
||||
* their values contain non-ascii or/and CR/LF, while they use the encoding in the other
|
||||
* properties like "ADR", "ORG", etc.
|
||||
* <P>
|
||||
* We are afraid of the case where some vCard importer also forget handling QP presuming QP is
|
||||
* not used in such fields.
|
||||
* </P>
|
||||
* <P>
|
||||
* This flag is useful when some target importer you are going to focus on does not accept
|
||||
* such "primary" property values with Quoted-Printable encoding.
|
||||
* </P>
|
||||
* <P>
|
||||
* Again, we should not use this flag at all for complying vCard 2.1 spec.
|
||||
* </P>
|
||||
* <P>
|
||||
* We will change the behavior around this flag in the future, after understanding the other
|
||||
* real vCard cases around this problem. Please use this flag with extreme caution even when
|
||||
* needed.
|
||||
* </P>
|
||||
* <P>
|
||||
* In vCard 3.0, Quoted-Printable is explicitly "prohibitted", so we don't need to care this
|
||||
* kind of problem (hopefully).
|
||||
* </P>
|
||||
*/
|
||||
public static final int FLAG_USE_QP_TO_PRIMARY_PROPERTIES = 0x10000000;
|
||||
public static final int FLAG_REFRAIN_QP_TO_PRIMARY_PROPERTIES = 0x10000000;
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* The flag indicating that phonetic name related fields must be converted to
|
||||
* appropriate form. Note that "appropriate" is not defined in any vCard specification.
|
||||
* This is Android-specific.
|
||||
* </P>
|
||||
* <P>
|
||||
* One typical (and currently sole) example where we need this flag is the time when
|
||||
* we need to emit Japanese phonetic names into vCard entries. The property values
|
||||
* should be encoded into half-width katakana when the target importer is Japanese mobile
|
||||
* phones', which are probably not able to parse full-width hiragana/katakana for
|
||||
* historical reasons, while the vCard importers embedded to softwares for PC should be
|
||||
* able to parse them as we expect.
|
||||
* </P>
|
||||
*/
|
||||
public static final int FLAG_CONVERT_PHONETIC_NAME_STRINGS = 0x0800000;
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* The flag indicating the vCard composer "for 2.1" emits "TYPE=" string every time
|
||||
* possible. The default behavior does not emit it and is valid, while adding "TYPE="
|
||||
* is also valid. In vCrad 3.0, this flag is unnecessary, since "TYPE=" is MUST in
|
||||
@@ -119,87 +170,118 @@ public class VCardConfig {
|
||||
*
|
||||
* e.g. int vcardType = (VCARD_TYPE_V21_GENERIC | FLAG_APPEND_TYPE_PARAM);
|
||||
*/
|
||||
public static final int FLAG_APPEND_TYPE_PARAM = 0x08000000;
|
||||
public static final int FLAG_APPEND_TYPE_PARAM = 0x04000000;
|
||||
|
||||
//// The followings are VCard types available from importer/exporter. ////
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* General vCard format with the version 2.1. Uses UTF-8 for the charset.
|
||||
* When composing a vCard entry, the US convension will be used.
|
||||
*
|
||||
* When composing a vCard entry, the US convension will be used toward formatting
|
||||
* some values
|
||||
* </P>
|
||||
* <P>
|
||||
* e.g. The order of the display name would be "Prefix Given Middle Family Suffix",
|
||||
* while in Japan, it should be "Prefix Family Middle Given Suffix".
|
||||
* while it should be "Prefix Family Middle Given Suffix" in Japan.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V21_GENERIC =
|
||||
public static final int VCARD_TYPE_V21_GENERIC_UTF8 =
|
||||
(FLAG_V21 | NAME_ORDER_DEFAULT | FLAG_CHARSET_UTF8 |
|
||||
FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);
|
||||
|
||||
/* package */ static String VCARD_TYPE_V21_GENERIC_STR = "v21_generic";
|
||||
/* package */ static String VCARD_TYPE_V21_GENERIC_UTF8_STR = "v21_generic";
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* General vCard format with the version 3.0. Uses UTF-8 for the charset.
|
||||
*
|
||||
* Note that this type is not fully implemented, so probably some bugs remain both in
|
||||
* parsing and composing.
|
||||
*
|
||||
* TODO: implement this type correctly.
|
||||
* </P>
|
||||
* <P>
|
||||
* Not ready yet. Use with caution when you use this.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V30_GENERIC =
|
||||
public static final int VCARD_TYPE_V30_GENERIC_UTF8 =
|
||||
(FLAG_V30 | NAME_ORDER_DEFAULT | FLAG_CHARSET_UTF8 |
|
||||
FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);
|
||||
|
||||
/* package */ static final String VCARD_TYPE_V30_GENERIC_STR = "v30_generic";
|
||||
/* package */ static final String VCARD_TYPE_V30_GENERIC_UTF8_STR = "v30_generic";
|
||||
|
||||
/**
|
||||
* General vCard format with the version 2.1 with some Europe convension. Uses Utf-8.
|
||||
* <P>
|
||||
* General vCard format for the vCard 2.1 with some Europe convension. Uses Utf-8.
|
||||
* Currently, only name order is considered ("Prefix Middle Given Family Suffix")
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V21_EUROPE =
|
||||
public static final int VCARD_TYPE_V21_EUROPE_UTF8 =
|
||||
(FLAG_V21 | NAME_ORDER_EUROPE | FLAG_CHARSET_UTF8 |
|
||||
FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);
|
||||
|
||||
/* package */ static final String VCARD_TYPE_V21_EUROPE_STR = "v21_europe";
|
||||
/* package */ static final String VCARD_TYPE_V21_EUROPE_UTF8_STR = "v21_europe";
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* General vCard format with the version 3.0 with some Europe convension. Uses UTF-8
|
||||
* </P>
|
||||
* <P>
|
||||
* Not ready yet. Use with caution when you use this.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V30_EUROPE =
|
||||
public static final int VCARD_TYPE_V30_EUROPE_UTF8 =
|
||||
(FLAG_V30 | NAME_ORDER_EUROPE | FLAG_CHARSET_UTF8 |
|
||||
FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);
|
||||
|
||||
/* package */ static final String VCARD_TYPE_V30_EUROPE_STR = "v30_europe";
|
||||
|
||||
/**
|
||||
* vCard 2.1 format for miscellaneous Japanese devices. Shift_Jis is used for
|
||||
* parsing/composing the vCard data.
|
||||
*/
|
||||
public static final int VCARD_TYPE_V21_JAPANESE =
|
||||
(FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS |
|
||||
FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);
|
||||
|
||||
/* package */ static final String VCARD_TYPE_V21_JAPANESE_STR = "v21_japanese";
|
||||
|
||||
/**
|
||||
* vCard 2.1 format for miscellaneous Japanese devices, using UTF-8 as default charset.
|
||||
* <P>
|
||||
* The vCard 2.1 format for miscellaneous Japanese devices, using UTF-8 as default charset.
|
||||
* </P>
|
||||
* <P>
|
||||
* Not ready yet. Use with caution when you use this.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V21_JAPANESE_UTF8 =
|
||||
(FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_UTF8 |
|
||||
FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);
|
||||
|
||||
/* package */ static final String VCARD_TYPE_V21_JAPANESE_UTF8_STR = "v21_japanese_utf8";
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* vCard 2.1 format for miscellaneous Japanese devices. Shift_Jis is used for
|
||||
* parsing/composing the vCard data.
|
||||
* </P>
|
||||
* <P>
|
||||
* Not ready yet. Use with caution when you use this.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V21_JAPANESE_SJIS =
|
||||
(FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS |
|
||||
FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);
|
||||
|
||||
/* package */ static final String VCARD_TYPE_V21_JAPANESE_SJIS_STR = "v21_japanese_sjis";
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* vCard format for miscellaneous Japanese devices, using Shift_Jis for
|
||||
* parsing/composing the vCard data.
|
||||
* </P>
|
||||
* <P>
|
||||
* Not ready yet. Use with caution when you use this.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V30_JAPANESE =
|
||||
public static final int VCARD_TYPE_V30_JAPANESE_SJIS =
|
||||
(FLAG_V30 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS |
|
||||
FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);
|
||||
|
||||
/* package */ static final String VCARD_TYPE_V30_JAPANESE_STR = "v30_japanese";
|
||||
/* package */ static final String VCARD_TYPE_V30_JAPANESE_SJIS_STR = "v30_japanese_sjis";
|
||||
|
||||
/**
|
||||
* vCard 3.0 format for miscellaneous Japanese devices, using UTF-8 as default charset.
|
||||
* <P>
|
||||
* The vCard 3.0 format for miscellaneous Japanese devices, using UTF-8 as default charset.
|
||||
* </P>
|
||||
* <P>
|
||||
* Not ready yet. Use with caution when you use this.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V30_JAPANESE_UTF8 =
|
||||
(FLAG_V30 | NAME_ORDER_JAPANESE | FLAG_CHARSET_UTF8 |
|
||||
@@ -208,38 +290,72 @@ public class VCardConfig {
|
||||
/* package */ static final String VCARD_TYPE_V30_JAPANESE_UTF8_STR = "v30_japanese_utf8";
|
||||
|
||||
/**
|
||||
* VCard format used in DoCoMo, which is one of Japanese mobile phone careers.
|
||||
* Base version is vCard 2.1, but the data has several DoCoMo-specific convensions.
|
||||
* No Android-specific property nor defact property is included.
|
||||
* <P>
|
||||
* The vCard 2.1 based format which (partially) considers the convention in Japanese
|
||||
* mobile phones, where phonetic names are translated to half-width katakana if
|
||||
* possible, etc.
|
||||
* </P>
|
||||
* <P>
|
||||
* Not ready yet. Use with caution when you use this.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V21_JAPANESE_MOBILE =
|
||||
(FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS |
|
||||
FLAG_CONVERT_PHONETIC_NAME_STRINGS |
|
||||
FLAG_REFRAIN_QP_TO_PRIMARY_PROPERTIES);
|
||||
|
||||
public static final String VCARD_TYPE_V21_JAPANESE_MOBILE_STR = "v21_japanese_mobile";
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* VCard format used in DoCoMo, which is one of Japanese mobile phone careers.
|
||||
* </p>
|
||||
* <P>
|
||||
* Base version is vCard 2.1, but the data has several DoCoMo-specific convensions.
|
||||
* No Android-specific property nor defact property is included. The "Primary" properties
|
||||
* are NOT encoded to Quoted-Printable.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_DOCOMO =
|
||||
(FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS | FLAG_DOCOMO);
|
||||
(VCARD_TYPE_V21_JAPANESE_MOBILE | FLAG_DOCOMO);
|
||||
|
||||
private static final String VCARD_TYPE_DOCOMO_STR = "docomo";
|
||||
|
||||
public static int VCARD_TYPE_DEFAULT = VCARD_TYPE_V21_GENERIC;
|
||||
public static int VCARD_TYPE_DEFAULT = VCARD_TYPE_V21_GENERIC_UTF8;
|
||||
|
||||
private static final Map<String, Integer> VCARD_TYPES_MAP;
|
||||
private static final Map<String, Integer> sVCardTypeMap;
|
||||
private static final Set<Integer> sJapaneseMobileTypeSet;
|
||||
|
||||
static {
|
||||
VCARD_TYPES_MAP = new HashMap<String, Integer>();
|
||||
VCARD_TYPES_MAP.put(VCARD_TYPE_V21_GENERIC_STR, VCARD_TYPE_V21_GENERIC);
|
||||
VCARD_TYPES_MAP.put(VCARD_TYPE_V30_GENERIC_STR, VCARD_TYPE_V30_GENERIC);
|
||||
VCARD_TYPES_MAP.put(VCARD_TYPE_V21_EUROPE_STR, VCARD_TYPE_V21_EUROPE);
|
||||
VCARD_TYPES_MAP.put(VCARD_TYPE_V30_EUROPE_STR, VCARD_TYPE_V30_EUROPE);
|
||||
VCARD_TYPES_MAP.put(VCARD_TYPE_V21_JAPANESE_STR, VCARD_TYPE_V21_JAPANESE);
|
||||
VCARD_TYPES_MAP.put(VCARD_TYPE_V21_JAPANESE_UTF8_STR, VCARD_TYPE_V21_JAPANESE_UTF8);
|
||||
VCARD_TYPES_MAP.put(VCARD_TYPE_V30_JAPANESE_STR, VCARD_TYPE_V30_JAPANESE);
|
||||
VCARD_TYPES_MAP.put(VCARD_TYPE_V30_JAPANESE_UTF8_STR, VCARD_TYPE_V30_JAPANESE_UTF8);
|
||||
VCARD_TYPES_MAP.put(VCARD_TYPE_DOCOMO_STR, VCARD_TYPE_DOCOMO);
|
||||
sVCardTypeMap = new HashMap<String, Integer>();
|
||||
sVCardTypeMap.put(VCARD_TYPE_V21_GENERIC_UTF8_STR, VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
sVCardTypeMap.put(VCARD_TYPE_V30_GENERIC_UTF8_STR, VCARD_TYPE_V30_GENERIC_UTF8);
|
||||
sVCardTypeMap.put(VCARD_TYPE_V21_EUROPE_UTF8_STR, VCARD_TYPE_V21_EUROPE_UTF8);
|
||||
sVCardTypeMap.put(VCARD_TYPE_V30_EUROPE_STR, VCARD_TYPE_V30_EUROPE_UTF8);
|
||||
sVCardTypeMap.put(VCARD_TYPE_V21_JAPANESE_SJIS_STR, VCARD_TYPE_V21_JAPANESE_SJIS);
|
||||
sVCardTypeMap.put(VCARD_TYPE_V21_JAPANESE_UTF8_STR, VCARD_TYPE_V21_JAPANESE_UTF8);
|
||||
sVCardTypeMap.put(VCARD_TYPE_V30_JAPANESE_SJIS_STR, VCARD_TYPE_V30_JAPANESE_SJIS);
|
||||
sVCardTypeMap.put(VCARD_TYPE_V30_JAPANESE_UTF8_STR, VCARD_TYPE_V30_JAPANESE_UTF8);
|
||||
sVCardTypeMap.put(VCARD_TYPE_V21_JAPANESE_MOBILE_STR, VCARD_TYPE_V21_JAPANESE_MOBILE);
|
||||
sVCardTypeMap.put(VCARD_TYPE_DOCOMO_STR, VCARD_TYPE_DOCOMO);
|
||||
|
||||
sJapaneseMobileTypeSet = new HashSet<Integer>();
|
||||
sJapaneseMobileTypeSet.add(VCARD_TYPE_V21_JAPANESE_SJIS);
|
||||
sJapaneseMobileTypeSet.add(VCARD_TYPE_V21_JAPANESE_UTF8);
|
||||
sJapaneseMobileTypeSet.add(VCARD_TYPE_V21_JAPANESE_SJIS);
|
||||
sJapaneseMobileTypeSet.add(VCARD_TYPE_V30_JAPANESE_SJIS);
|
||||
sJapaneseMobileTypeSet.add(VCARD_TYPE_V30_JAPANESE_UTF8);
|
||||
sJapaneseMobileTypeSet.add(VCARD_TYPE_V21_JAPANESE_MOBILE);
|
||||
sJapaneseMobileTypeSet.add(VCARD_TYPE_DOCOMO);
|
||||
}
|
||||
|
||||
public static int getVCardTypeFromString(String vcardTypeString) {
|
||||
String loweredKey = vcardTypeString.toLowerCase();
|
||||
if (VCARD_TYPES_MAP.containsKey(loweredKey)) {
|
||||
return VCARD_TYPES_MAP.get(loweredKey);
|
||||
if (sVCardTypeMap.containsKey(loweredKey)) {
|
||||
return sVCardTypeMap.get(loweredKey);
|
||||
} else {
|
||||
// XXX: should return the value indicating the input is invalid?
|
||||
Log.e(LOG_TAG, "Unknown vCard type String: \"" + vcardTypeString + "\"");
|
||||
return VCARD_TYPE_DEFAULT;
|
||||
}
|
||||
}
|
||||
@@ -252,22 +368,6 @@ public class VCardConfig {
|
||||
return !isV30(vcardType);
|
||||
}
|
||||
|
||||
public static boolean isDoCoMo(int vcardType) {
|
||||
return ((vcardType & FLAG_DOCOMO) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
return ((vcardType == VCARD_TYPE_V21_JAPANESE) ||
|
||||
(vcardType == VCARD_TYPE_V21_JAPANESE_UTF8) ||
|
||||
(vcardType == VCARD_TYPE_V30_JAPANESE) ||
|
||||
(vcardType == VCARD_TYPE_V30_JAPANESE_UTF8) ||
|
||||
(vcardType == VCARD_TYPE_DOCOMO));
|
||||
}
|
||||
|
||||
public static boolean usesUtf8(int vcardType) {
|
||||
return ((vcardType & FLAG_CHARSET_UTF8) != 0);
|
||||
}
|
||||
@@ -276,17 +376,6 @@ public class VCardConfig {
|
||||
return ((vcardType & FLAG_CHARSET_SHIFT_JIS) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true when Japanese phonetic string must be converted to a string
|
||||
* containing only half-width katakana. This method exists since Japanese mobile
|
||||
* phones usually use only half-width katakana for expressing phonetic names and
|
||||
* some devices are not ready for parsing other phonetic strings like hiragana and
|
||||
* full-width katakana.
|
||||
*/
|
||||
public static boolean needsToConvertPhoneticString(int vcardType) {
|
||||
return (vcardType == VCARD_TYPE_DOCOMO);
|
||||
}
|
||||
|
||||
public static int getNameOrderType(int vcardType) {
|
||||
return vcardType & NAME_ORDER_MASK;
|
||||
}
|
||||
@@ -299,24 +388,37 @@ public class VCardConfig {
|
||||
return ((vcardType & FLAG_USE_DEFACT_PROPERTY) != 0);
|
||||
}
|
||||
|
||||
public static boolean onlyOneNoteFieldIsAvailable(int vcardType) {
|
||||
return vcardType == VCARD_TYPE_DOCOMO;
|
||||
}
|
||||
|
||||
public static boolean showPerformanceLog() {
|
||||
return (VCardConfig.LOG_LEVEL & VCardConfig.LOG_LEVEL_PERFORMANCE_MEASUREMENT) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static boolean usesQPToPrimaryProperties(int vcardType) {
|
||||
return (usesQuotedPrintable(vcardType) &&
|
||||
((vcardType & FLAG_USE_QP_TO_PRIMARY_PROPERTIES) != 0));
|
||||
public static boolean refrainsQPToPrimaryProperties(int vcardType) {
|
||||
return (!usesQuotedPrintable(vcardType) ||
|
||||
((vcardType & FLAG_REFRAIN_QP_TO_PRIMARY_PROPERTIES) != 0));
|
||||
}
|
||||
|
||||
public static boolean appendTypeParamName(int vcardType) {
|
||||
return (vcardType & FLAG_APPEND_TYPE_PARAM) != 0;
|
||||
return (isV30(vcardType) || ((vcardType & FLAG_APPEND_TYPE_PARAM) != 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
return sJapaneseMobileTypeSet.contains(vcardType);
|
||||
}
|
||||
|
||||
public static boolean needsToConvertPhoneticString(int vcardType) {
|
||||
return ((vcardType & FLAG_CONVERT_PHONETIC_NAME_STRINGS) != 0);
|
||||
}
|
||||
|
||||
public static boolean onlyOneNoteFieldIsAvailable(int vcardType) {
|
||||
return vcardType == VCARD_TYPE_DOCOMO;
|
||||
}
|
||||
|
||||
public static boolean isDoCoMo(int vcardType) {
|
||||
return ((vcardType & FLAG_DOCOMO) != 0);
|
||||
}
|
||||
|
||||
private VCardConfig() {
|
||||
|
||||
@@ -69,7 +69,7 @@ public class VCardDataBuilder implements VCardBuilder {
|
||||
private List<EntryHandler> mEntryHandlers = new ArrayList<EntryHandler>();
|
||||
|
||||
public VCardDataBuilder() {
|
||||
this(null, null, false, VCardConfig.VCARD_TYPE_V21_GENERIC, null);
|
||||
this(null, null, false, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.pim.vcard;
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentValues;
|
||||
import android.provider.ContactsContract.Data;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Im;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
|
||||
import android.text.TextUtils;
|
||||
@@ -44,38 +45,49 @@ public class VCardUtils {
|
||||
private static final Map<Integer, String> sKnownPhoneTypesMap_ItoS;
|
||||
private static final Set<String> sPhoneTypesSetUnknownToContacts;
|
||||
|
||||
private static final Map<String, Integer> sKnownPhoneTypesMap_StoI;
|
||||
private static final Map<String, Integer> sKnownPhoneTypeMap_StoI;
|
||||
|
||||
private static final Map<Integer, String> sKnownImPropNameMap_ItoS;
|
||||
|
||||
static {
|
||||
sKnownPhoneTypesMap_ItoS = new HashMap<Integer, String>();
|
||||
sKnownPhoneTypesMap_StoI = new HashMap<String, Integer>();
|
||||
sKnownPhoneTypeMap_StoI = new HashMap<String, Integer>();
|
||||
|
||||
sKnownPhoneTypesMap_ItoS.put(Phone.TYPE_CAR, Constants.ATTR_TYPE_CAR);
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_CAR, Phone.TYPE_CAR);
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_CAR, Phone.TYPE_CAR);
|
||||
sKnownPhoneTypesMap_ItoS.put(Phone.TYPE_PAGER, Constants.ATTR_TYPE_PAGER);
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_PAGER, Phone.TYPE_PAGER);
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_PAGER, Phone.TYPE_PAGER);
|
||||
sKnownPhoneTypesMap_ItoS.put(Phone.TYPE_ISDN, Constants.ATTR_TYPE_ISDN);
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_ISDN, Phone.TYPE_ISDN);
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_ISDN, Phone.TYPE_ISDN);
|
||||
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_HOME, Phone.TYPE_HOME);
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_WORK, Phone.TYPE_WORK);
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_CELL, Phone.TYPE_MOBILE);
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_HOME, Phone.TYPE_HOME);
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_WORK, Phone.TYPE_WORK);
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_CELL, Phone.TYPE_MOBILE);
|
||||
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_OTHER, Phone.TYPE_OTHER);
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_CALLBACK, Phone.TYPE_CALLBACK);
|
||||
sKnownPhoneTypesMap_StoI.put(
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_OTHER, Phone.TYPE_OTHER);
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_CALLBACK, Phone.TYPE_CALLBACK);
|
||||
sKnownPhoneTypeMap_StoI.put(
|
||||
Constants.ATTR_PHONE_EXTRA_TYPE_COMPANY_MAIN, Phone.TYPE_COMPANY_MAIN);
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_RADIO, Phone.TYPE_RADIO);
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_TELEX, Phone.TYPE_TELEX);
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_TTY_TDD, Phone.TYPE_TTY_TDD);
|
||||
sKnownPhoneTypesMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_ASSISTANT,
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_RADIO, Phone.TYPE_RADIO);
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_TTY_TDD, Phone.TYPE_TTY_TDD);
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_ASSISTANT,
|
||||
Phone.TYPE_ASSISTANT);
|
||||
|
||||
sPhoneTypesSetUnknownToContacts = new HashSet<String>();
|
||||
sPhoneTypesSetUnknownToContacts.add(Constants.ATTR_TYPE_MODEM);
|
||||
sPhoneTypesSetUnknownToContacts.add(Constants.ATTR_TYPE_MSG);
|
||||
sPhoneTypesSetUnknownToContacts.add(Constants.ATTR_TYPE_BBS);
|
||||
sPhoneTypesSetUnknownToContacts.add(Constants.ATTR_TYPE_VIDEO);
|
||||
|
||||
sKnownImPropNameMap_ItoS = new HashMap<Integer, String>();
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_AIM, Constants.PROPERTY_X_AIM);
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_MSN, Constants.PROPERTY_X_MSN);
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_YAHOO, Constants.PROPERTY_X_YAHOO);
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_SKYPE, Constants.PROPERTY_X_SKYPE_USERNAME);
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_GOOGLE_TALK, Constants.PROPERTY_X_GOOGLE_TALK);
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_ICQ, Constants.PROPERTY_X_ICQ);
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_JABBER, Constants.PROPERTY_X_JABBER);
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_QQ, Constants.PROPERTY_X_QQ);
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_NETMEETING, Constants.PROPERTY_X_NETMEETING);
|
||||
}
|
||||
|
||||
public static String getPhoneAttributeString(Integer type) {
|
||||
@@ -103,7 +115,7 @@ public class VCardUtils {
|
||||
if (typeString.startsWith("X-") && type < 0) {
|
||||
typeString = typeString.substring(2);
|
||||
}
|
||||
Integer tmp = sKnownPhoneTypesMap_StoI.get(typeString);
|
||||
Integer tmp = sKnownPhoneTypeMap_StoI.get(typeString);
|
||||
if (tmp != null) {
|
||||
type = tmp;
|
||||
} else if (type < 0) {
|
||||
@@ -136,7 +148,11 @@ public class VCardUtils {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getPropertyNameForIm(int protocol) {
|
||||
return sKnownImPropNameMap_ItoS.get(protocol);
|
||||
}
|
||||
|
||||
public static boolean isValidPhoneAttribute(String phoneAttribute, int vcardType) {
|
||||
// TODO: check the following.
|
||||
// - it may violate vCard spec
|
||||
@@ -206,12 +222,12 @@ public class VCardUtils {
|
||||
builder.withValue(Data.IS_PRIMARY, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns String[] containing address information based on vCard spec
|
||||
* (PO Box, Extended Address, Street, Locality, Region, Postal Code, Country Name).
|
||||
* All String objects are non-null ("" is used when the relevant data is empty).
|
||||
*
|
||||
*
|
||||
* Note that the data structure of ContactsContract is different from that defined in vCard.
|
||||
* So some conversion may be performed in this method. See also
|
||||
* {{@link #insertStructuredPostalDataUsingContactsStruct(int,
|
||||
@@ -219,13 +235,20 @@ public class VCardUtils {
|
||||
* android.pim.vcard.ContactStruct.PostalData)}
|
||||
*/
|
||||
public static String[] getVCardPostalElements(ContentValues contentValues) {
|
||||
// adr-value = 0*6(text-value ";") text-value
|
||||
// ; PO Box, Extended Address, Street, Locality, Region, Postal
|
||||
// ; Code, Country Name
|
||||
String[] dataArray = new String[7];
|
||||
dataArray[0] = contentValues.getAsString(StructuredPostal.POBOX);
|
||||
if (dataArray[0] == null) {
|
||||
dataArray[0] = "";
|
||||
}
|
||||
// Extended addr. There's no relevant data in ContactsContract.
|
||||
dataArray[1] = "";
|
||||
// We keep all the data in StructuredPostal, presuming NEIGHBORHOOD is
|
||||
// similar to "Extended Address".
|
||||
dataArray[1] = contentValues.getAsString(StructuredPostal.NEIGHBORHOOD);
|
||||
if (dataArray[1] == null) {
|
||||
dataArray[1] = "";
|
||||
}
|
||||
dataArray[2] = contentValues.getAsString(StructuredPostal.STREET);
|
||||
if (dataArray[2] == null) {
|
||||
dataArray[2] = "";
|
||||
|
||||
@@ -230,6 +230,6 @@ public class PropertyNodesVerifier {
|
||||
}
|
||||
mTestCase.fail("Property \"" + propName + "\" has wrong value.\n"
|
||||
+ builder.toString()
|
||||
+ " actual: " + actualNode.toString());
|
||||
+ " actual: " + actualNode.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,17 @@ import android.pim.vcard.exception.VCardException;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
import android.provider.ContactsContract.Data;
|
||||
import android.provider.ContactsContract.RawContacts;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Email;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Event;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Im;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Nickname;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Note;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Organization;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Photo;
|
||||
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
||||
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Website;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.mock.MockContentResolver;
|
||||
import android.test.mock.MockContext;
|
||||
@@ -147,7 +156,10 @@ class MockContentProvider extends ContentProvider {
|
||||
* the result of this class will not be reliable.
|
||||
*/
|
||||
public class VCardExporterTests extends AndroidTestCase {
|
||||
/* package */ static final byte[] sPhotoByteArray =
|
||||
private static final int V21 = 0;
|
||||
private static final int V30 = 1;
|
||||
|
||||
private static final byte[] sPhotoByteArray =
|
||||
VCardImporterTests.sPhotoByteArrayForComplicatedCase;
|
||||
|
||||
public class ExportTestResolver extends MockContentResolver {
|
||||
@@ -282,17 +294,26 @@ public class VCardExporterTests extends AndroidTestCase {
|
||||
final private boolean mIsV30;
|
||||
int mCount;
|
||||
|
||||
public VCardVerificationHandler(TestCase testCase, boolean isV30) {
|
||||
public VCardVerificationHandler(TestCase testCase, int version) {
|
||||
mTestCase = testCase;
|
||||
mPropertyNodesVerifierList = new ArrayList<PropertyNodesVerifier>();
|
||||
mIsV30 = isV30;
|
||||
mIsV30 = (version == V30);
|
||||
mCount = 1;
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNewPropertyNodesVerifier() {
|
||||
PropertyNodesVerifier propertyNodesVerifier = new PropertyNodesVerifier(mTestCase);
|
||||
mPropertyNodesVerifierList.add(propertyNodesVerifier);
|
||||
return propertyNodesVerifier;
|
||||
public PropertyNodesVerifier addNewVerifier() {
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier(mTestCase);
|
||||
mPropertyNodesVerifierList.add(verifier);
|
||||
verifier.addNodeWithOrder("VERSION", mIsV30 ? "3.0" : "2.1");
|
||||
return verifier;
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNewVerifierWithEmptyName() {
|
||||
PropertyNodesVerifier verifier = addNewVerifier();
|
||||
if (mIsV30) {
|
||||
verifier.addNodeWithOrder("N", "").addNodeWithOrder("FN", "");
|
||||
}
|
||||
return verifier;
|
||||
}
|
||||
|
||||
public boolean onInit(Context context) {
|
||||
@@ -344,50 +365,12 @@ public class VCardExporterTests extends AndroidTestCase {
|
||||
|
||||
//// Followings are actual tests ////
|
||||
|
||||
public void testSimple() {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "Ando");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "Roid");
|
||||
private void verifyOneComposition(ExportTestResolver resolver,
|
||||
VCardVerificationHandler handler, int version) {
|
||||
final boolean isV30 = (version == V30);
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, false);
|
||||
handler.addNewPropertyNodesVerifier()
|
||||
.addNodeWithOrder("VERSION", "2.1")
|
||||
.addNodeWithoutOrder("FN", "Roid Ando")
|
||||
.addNodeWithoutOrder("N", "Ando;Roid;;;", Arrays.asList("Ando", "Roid", "", "", ""));
|
||||
|
||||
VCardComposer composer = new VCardComposer(new CustomMockContext(resolver),
|
||||
VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
composer.addHandler(handler);
|
||||
if (!composer.init(VCardComposer.CONTACTS_TEST_CONTENT_URI, null, null, null)) {
|
||||
fail("init failed. Reason: " + composer.getErrorReason());
|
||||
}
|
||||
assertFalse(composer.isAfterLast());
|
||||
assertTrue(composer.createOneEntry());
|
||||
assertTrue(composer.isAfterLast());
|
||||
composer.terminate();
|
||||
}
|
||||
|
||||
private void testPhotoCommon(boolean isV30) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "PhotoTest");
|
||||
|
||||
contentValues = resolver.buildData(Photo.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Photo.PHOTO, sPhotoByteArray);
|
||||
|
||||
ContentValues contentValuesForPhoto = new ContentValues();
|
||||
contentValuesForPhoto.put("ENCODING", (isV30 ? "b" : "BASE64"));
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, isV30);
|
||||
handler.addNewPropertyNodesVerifier()
|
||||
.addNodeWithOrder("VERSION", (isV30 ? "3.0" : "2.1"))
|
||||
.addNodeWithoutOrder("FN", "PhotoTest")
|
||||
.addNodeWithoutOrder("N", "PhotoTest;;;;", Arrays.asList("PhotoTest", "", "", "", ""))
|
||||
.addNodeWithOrder("PHOTO", null, null, sPhotoByteArray,
|
||||
contentValuesForPhoto, new TypeSet("JPEG"), null);
|
||||
|
||||
int vcardType = (isV30 ? VCardConfig.VCARD_TYPE_V30_GENERIC
|
||||
: VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
int vcardType = (isV30 ? VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8
|
||||
: VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
VCardComposer composer = new VCardComposer(new CustomMockContext(resolver), vcardType);
|
||||
composer.addHandler(handler);
|
||||
if (!composer.init(VCardComposer.CONTACTS_TEST_CONTENT_URI, null, null, null)) {
|
||||
@@ -399,11 +382,830 @@ public class VCardExporterTests extends AndroidTestCase {
|
||||
composer.terminate();
|
||||
}
|
||||
|
||||
public void testSimpleV21() {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "Ando");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "Roid");
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, V21);
|
||||
handler.addNewVerifier()
|
||||
.addNodeWithoutOrder("FN", "Roid Ando")
|
||||
.addNodeWithoutOrder("N", "Ando;Roid;;;", Arrays.asList("Ando", "Roid", "", "", ""));
|
||||
|
||||
verifyOneComposition(resolver, handler, V21);
|
||||
}
|
||||
|
||||
private void testStructuredNameBasic(int version) {
|
||||
final boolean isV30 = (version == V30);
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "AppropriateFamilyName");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "AppropriateGivenName");
|
||||
contentValues.put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName");
|
||||
contentValues.put(StructuredName.PREFIX, "AppropriatePrefix");
|
||||
contentValues.put(StructuredName.SUFFIX, "AppropriateSuffix");
|
||||
contentValues.put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily");
|
||||
contentValues.put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven");
|
||||
contentValues.put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle");
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
PropertyNodesVerifier verifier = handler.addNewVerifier()
|
||||
.addNodeWithOrder("N",
|
||||
"AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
|
||||
+ "AppropriatePrefix;AppropriateSuffix",
|
||||
Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
|
||||
"AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
|
||||
.addNodeWithOrder("FN",
|
||||
"AppropriatePrefix AppropriateGivenName "
|
||||
+ "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
|
||||
.addNodeWithoutOrder("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
|
||||
.addNodeWithoutOrder("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
|
||||
.addNodeWithoutOrder("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
|
||||
|
||||
if (isV30) {
|
||||
verifier.addNodeWithoutOrder("SORT-STRING",
|
||||
"AppropriatePhoneticGiven AppropriatePhoneticMiddle "
|
||||
+ "AppropriatePhoneticFamily");
|
||||
}
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testStructuredNameBasicV21() {
|
||||
testStructuredNameBasic(V21);
|
||||
}
|
||||
|
||||
public void testStructuredNameBasicV30() {
|
||||
testStructuredNameBasic(V30);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that only "primary" StructuredName is emitted, so that our vCard file
|
||||
* will not confuse the external importer, assuming there may be some importer
|
||||
* which presume that there's only one property toward each of "N", "FN", etc.
|
||||
* Note that more than one "N", "FN", etc. properties are acceptable in vCard spec.
|
||||
*/
|
||||
private void testStructuredNameUsePrimaryCommon(int version) {
|
||||
final boolean isV30 = (version == V30);
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1");
|
||||
contentValues.put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1");
|
||||
contentValues.put(StructuredName.PREFIX, "DoNotEmitPrefix1");
|
||||
contentValues.put(StructuredName.SUFFIX, "DoNotEmitSuffix1");
|
||||
contentValues.put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily1");
|
||||
contentValues.put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven1");
|
||||
contentValues.put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle1");
|
||||
|
||||
// With "IS_PRIMARY=1". This is what we should use.
|
||||
contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "AppropriateFamilyName");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "AppropriateGivenName");
|
||||
contentValues.put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName");
|
||||
contentValues.put(StructuredName.PREFIX, "AppropriatePrefix");
|
||||
contentValues.put(StructuredName.SUFFIX, "AppropriateSuffix");
|
||||
contentValues.put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily");
|
||||
contentValues.put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven");
|
||||
contentValues.put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle");
|
||||
contentValues.put(StructuredName.IS_PRIMARY, 1);
|
||||
|
||||
// With "IS_PRIMARY=1", but we should ignore this time, since this is second, not first.
|
||||
contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2");
|
||||
contentValues.put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2");
|
||||
contentValues.put(StructuredName.PREFIX, "DoNotEmitPrefix2");
|
||||
contentValues.put(StructuredName.SUFFIX, "DoNotEmitSuffix2");
|
||||
contentValues.put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily2");
|
||||
contentValues.put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven2");
|
||||
contentValues.put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle2");
|
||||
contentValues.put(StructuredName.IS_PRIMARY, 1);
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
PropertyNodesVerifier verifier = handler.addNewVerifier()
|
||||
.addNodeWithOrder("N",
|
||||
"AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
|
||||
+ "AppropriatePrefix;AppropriateSuffix",
|
||||
Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
|
||||
"AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
|
||||
.addNodeWithOrder("FN",
|
||||
"AppropriatePrefix AppropriateGivenName "
|
||||
+ "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
|
||||
.addNodeWithoutOrder("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
|
||||
.addNodeWithoutOrder("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
|
||||
.addNodeWithoutOrder("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
|
||||
|
||||
if (isV30) {
|
||||
verifier.addNodeWithoutOrder("SORT-STRING",
|
||||
"AppropriatePhoneticGiven AppropriatePhoneticMiddle "
|
||||
+ "AppropriatePhoneticFamily");
|
||||
}
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testStructuredNameUsePrimaryV21() {
|
||||
testStructuredNameUsePrimaryCommon(V21);
|
||||
}
|
||||
|
||||
public void testStructuredNameUsePrimaryV30() {
|
||||
testStructuredNameUsePrimaryCommon(V30);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that only "super primary" StructuredName is emitted.
|
||||
* See also the comment in {@link #testStructuredNameUsePrimaryCommon(int)}.
|
||||
*/
|
||||
private void testStructuredNameUseSuperPrimaryCommon(int version) {
|
||||
final boolean isV30 = (version == V30);
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1");
|
||||
contentValues.put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1");
|
||||
contentValues.put(StructuredName.PREFIX, "DoNotEmitPrefix1");
|
||||
contentValues.put(StructuredName.SUFFIX, "DoNotEmitSuffix1");
|
||||
contentValues.put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily1");
|
||||
contentValues.put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven1");
|
||||
contentValues.put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle1");
|
||||
|
||||
// With "IS_PRIMARY=1", but we should ignore this time.
|
||||
contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2");
|
||||
contentValues.put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2");
|
||||
contentValues.put(StructuredName.PREFIX, "DoNotEmitPrefix2");
|
||||
contentValues.put(StructuredName.SUFFIX, "DoNotEmitSuffix2");
|
||||
contentValues.put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily2");
|
||||
contentValues.put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven2");
|
||||
contentValues.put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle2");
|
||||
contentValues.put(StructuredName.IS_PRIMARY, 1);
|
||||
|
||||
// With "IS_SUPER_PRIMARY=1". This is what we should use.
|
||||
contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "AppropriateFamilyName");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "AppropriateGivenName");
|
||||
contentValues.put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName");
|
||||
contentValues.put(StructuredName.PREFIX, "AppropriatePrefix");
|
||||
contentValues.put(StructuredName.SUFFIX, "AppropriateSuffix");
|
||||
contentValues.put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily");
|
||||
contentValues.put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven");
|
||||
contentValues.put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle");
|
||||
contentValues.put(StructuredName.IS_SUPER_PRIMARY, 1);
|
||||
|
||||
contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName3");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName3");
|
||||
contentValues.put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName3");
|
||||
contentValues.put(StructuredName.PREFIX, "DoNotEmitPrefix3");
|
||||
contentValues.put(StructuredName.SUFFIX, "DoNotEmitSuffix3");
|
||||
contentValues.put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily3");
|
||||
contentValues.put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven3");
|
||||
contentValues.put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle3");
|
||||
contentValues.put(StructuredName.IS_PRIMARY, 1);
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
PropertyNodesVerifier verifier = handler.addNewVerifier()
|
||||
.addNodeWithOrder("N",
|
||||
"AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
|
||||
+ "AppropriatePrefix;AppropriateSuffix",
|
||||
Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
|
||||
"AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
|
||||
.addNodeWithOrder("FN",
|
||||
"AppropriatePrefix AppropriateGivenName "
|
||||
+ "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
|
||||
.addNodeWithoutOrder("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
|
||||
.addNodeWithoutOrder("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
|
||||
.addNodeWithoutOrder("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
|
||||
|
||||
if (isV30) {
|
||||
verifier.addNodeWithoutOrder("SORT-STRING",
|
||||
"AppropriatePhoneticGiven AppropriatePhoneticMiddle"
|
||||
+ " AppropriatePhoneticFamily");
|
||||
}
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testStructuredNameUseSuperPrimaryV21() {
|
||||
testStructuredNameUseSuperPrimaryCommon(V21);
|
||||
}
|
||||
|
||||
public void testStructuredNameUseSuperPrimaryV30() {
|
||||
testStructuredNameUseSuperPrimaryCommon(V30);
|
||||
}
|
||||
|
||||
/**
|
||||
* There's no property for nickname in vCard 2.1, so we don't have any requirement on it.
|
||||
*/
|
||||
public void testNickNameV30() {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContentValues contentValues = resolver.buildData(Nickname.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Nickname.NAME, "Nicky");
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, V30);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithOrder("NICKNAME", "Nicky");
|
||||
|
||||
verifyOneComposition(resolver, handler, V30);
|
||||
}
|
||||
|
||||
private void testPhoneBasicCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "1");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_HOME);
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("TEL", "1", new TypeSet("HOME", "VOICE"));
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testPhoneBasicV21() {
|
||||
testPhoneBasicCommon(V21);
|
||||
}
|
||||
|
||||
public void testPhoneBasicV30() {
|
||||
testPhoneBasicCommon(V30);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that vCard composer emits corresponding type param which we expect.
|
||||
*/
|
||||
private void testPhoneVariousTypeSupport(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "10");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_HOME);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "20");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_WORK);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "30");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_FAX_HOME);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "40");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_FAX_WORK);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "50");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_MOBILE);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "60");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_PAGER);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "70");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_OTHER);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "80");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_CAR);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "90");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_COMPANY_MAIN);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "100");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_ISDN);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "110");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_MAIN);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "120");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_OTHER_FAX);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "130");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_TELEX);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "140");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_WORK_MOBILE);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "150");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_WORK_PAGER);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "160");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_MMS);
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("TEL", "10", new TypeSet("HOME"))
|
||||
.addNodeWithoutOrder("TEL", "20", new TypeSet("WORK"))
|
||||
.addNodeWithoutOrder("TEL", "30", new TypeSet("HOME", "FAX"))
|
||||
.addNodeWithoutOrder("TEL", "40", new TypeSet("WORK", "FAX"))
|
||||
.addNodeWithoutOrder("TEL", "50", new TypeSet("CELL"))
|
||||
.addNodeWithoutOrder("TEL", "60", new TypeSet("PAGER"))
|
||||
.addNodeWithoutOrder("TEL", "70", new TypeSet("VOICE"))
|
||||
.addNodeWithoutOrder("TEL", "80", new TypeSet("CAR"))
|
||||
.addNodeWithoutOrder("TEL", "90", new TypeSet("WORK", "PREF"))
|
||||
.addNodeWithoutOrder("TEL", "100", new TypeSet("ISDN"))
|
||||
.addNodeWithoutOrder("TEL", "110", new TypeSet("PREF"))
|
||||
.addNodeWithoutOrder("TEL", "120", new TypeSet("FAX"))
|
||||
.addNodeWithoutOrder("TEL", "130", new TypeSet("TLX"))
|
||||
.addNodeWithoutOrder("TEL", "140", new TypeSet("WORK", "MOBILE"))
|
||||
.addNodeWithoutOrder("TEL", "150", new TypeSet("WORK", "PAGER"))
|
||||
.addNodeWithoutOrder("TEL", "160", new TypeSet("MSG"));
|
||||
}
|
||||
|
||||
public void testPhoneVariousTypeSupportV21() {
|
||||
testPhoneVariousTypeSupport(V21);
|
||||
}
|
||||
|
||||
public void testPhoneVariousTypeSupportV30() {
|
||||
testPhoneVariousTypeSupport(V30);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that "PREF"s are emitted appropriately.
|
||||
*/
|
||||
private void testPhonePrefHandlingCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "1");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_HOME);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "2");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_WORK);
|
||||
contentValues.put(Phone.IS_PRIMARY, 1);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "3");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_FAX_HOME);
|
||||
contentValues.put(Phone.IS_PRIMARY, 1);
|
||||
|
||||
contentValues = resolver.buildData(Phone.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Phone.NUMBER, "4");
|
||||
contentValues.put(Phone.TYPE, Phone.TYPE_FAX_WORK);
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("TEL", "4", new TypeSet("WORK", "FAX"))
|
||||
.addNodeWithoutOrder("TEL", "3", new TypeSet("HOME", "FAX", "PREF"))
|
||||
.addNodeWithoutOrder("TEL", "2", new TypeSet("WORK", "VOICE", "PREF"))
|
||||
.addNodeWithoutOrder("TEL", "1", new TypeSet("HOME", "VOICE"));
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testPhonePrefHandlingV21() {
|
||||
testPhonePrefHandlingCommon(V21);
|
||||
}
|
||||
|
||||
public void testPhonePrefHandlingV30() {
|
||||
testPhonePrefHandlingCommon(V30);
|
||||
}
|
||||
|
||||
private void testEmailBasicCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContentValues contentValues = resolver.buildData(Email.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Email.DATA, "sample@example.com");
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("EMAIL", "sample@example.com");
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testEmailBasicV21() {
|
||||
testEmailBasicCommon(V21);
|
||||
}
|
||||
|
||||
public void testEmailBasicV30() {
|
||||
testEmailBasicCommon(V30);
|
||||
}
|
||||
|
||||
private void testEmailVariousTypeSupportCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(Email.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Email.DATA, "type_home@example.com");
|
||||
contentValues.put(Email.TYPE, Email.TYPE_HOME);
|
||||
|
||||
contentValues = resolver.buildData(Email.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Email.DATA, "type_work@example.com");
|
||||
contentValues.put(Email.TYPE, Email.TYPE_WORK);
|
||||
|
||||
contentValues = resolver.buildData(Email.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Email.DATA, "type_mobile@example.com");
|
||||
contentValues.put(Email.TYPE, Email.TYPE_MOBILE);
|
||||
|
||||
contentValues = resolver.buildData(Email.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Email.DATA, "type_other@example.com");
|
||||
contentValues.put(Email.TYPE, Email.TYPE_OTHER);
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("EMAIL", "type_home@example.com", new TypeSet("HOME"))
|
||||
.addNodeWithoutOrder("EMAIL", "type_work@example.com", new TypeSet("WORK"))
|
||||
.addNodeWithoutOrder("EMAIL", "type_mobile@example.com", new TypeSet("CELL"))
|
||||
.addNodeWithoutOrder("EMAIL", "type_other@example.com");
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testEmailVariousTypeSupportV21() {
|
||||
testEmailVariousTypeSupportCommon(V21);
|
||||
}
|
||||
|
||||
public void testEmailVariousTypeSupportV30() {
|
||||
testEmailVariousTypeSupportCommon(V30);
|
||||
}
|
||||
|
||||
private void testEmailPrefHandlingCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(Email.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Email.DATA, "type_home@example.com");
|
||||
contentValues.put(Email.TYPE, Email.TYPE_HOME);
|
||||
contentValues.put(Email.IS_PRIMARY, 1);
|
||||
|
||||
contentValues = resolver.buildData(Email.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Email.DATA, "type_notype@example.com");
|
||||
contentValues.put(Email.IS_PRIMARY, 1);
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("EMAIL", "type_notype@example.com", new TypeSet("PREF"))
|
||||
.addNodeWithoutOrder("EMAIL", "type_home@example.com", new TypeSet("HOME", "PREF"));
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testEmailPrefHandlingV21() {
|
||||
testEmailPrefHandlingCommon(V21);
|
||||
}
|
||||
|
||||
public void testEmailPrefHandlingV30() {
|
||||
testEmailPrefHandlingCommon(V30);
|
||||
}
|
||||
|
||||
private void testPostalOnlyWithStructuredDataCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
// adr-value = 0*6(text-value ";") text-value
|
||||
// ; PO Box, Extended Address, Street, Locality, Region, Postal Code,
|
||||
// ; Country Name
|
||||
ContentValues contentValues = resolver.buildData(StructuredPostal.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredPostal.POBOX, "Pobox");
|
||||
contentValues.put(StructuredPostal.NEIGHBORHOOD, "Neighborhood");
|
||||
contentValues.put(StructuredPostal.STREET, "Street");
|
||||
contentValues.put(StructuredPostal.CITY, "City");
|
||||
contentValues.put(StructuredPostal.REGION, "Region");
|
||||
contentValues.put(StructuredPostal.POSTCODE, "100");
|
||||
contentValues.put(StructuredPostal.COUNTRY, "Country");
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("ADR", "Pobox;Neighborhood;Street;City;Region;100;Country",
|
||||
Arrays.asList("Pobox", "Neighborhood", "Street", "City",
|
||||
"Region", "100", "Country"), new TypeSet("HOME"));
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testPostalOnlyWithStructuredDataV21() {
|
||||
testPostalOnlyWithStructuredDataCommon(V21);
|
||||
}
|
||||
|
||||
public void testPostalOnlyWithStructuredDataV30() {
|
||||
testPostalOnlyWithStructuredDataCommon(V30);
|
||||
}
|
||||
|
||||
private void testPostalOnlyWithFormattedAddressCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(StructuredPostal.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredPostal.FORMATTED_ADDRESS,
|
||||
"Formatted address CA 123-334 United Statue");
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithOrder("ADR", ";Formatted address CA 123-334 United Statue;;;;;",
|
||||
Arrays.asList("", "Formatted address CA 123-334 United Statue",
|
||||
"", "", "", "", ""), new TypeSet("HOME"));
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testPostalOnlyWithFormattedAddressV21() {
|
||||
testPostalOnlyWithFormattedAddressCommon(V21);
|
||||
}
|
||||
|
||||
public void testPostalOnlyWithFormattedAddressV30() {
|
||||
testPostalOnlyWithFormattedAddressCommon(V30);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the vCard composer honors formatted data when it is available
|
||||
* even when it is partial.
|
||||
*/
|
||||
private void testPostalWithBothStructuredAndFormattedCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(StructuredPostal.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredPostal.POBOX, "Pobox");
|
||||
contentValues.put(StructuredPostal.COUNTRY, "Country");
|
||||
contentValues.put(StructuredPostal.FORMATTED_ADDRESS,
|
||||
"Formatted address CA 123-334 United Statue"); // Should be ignored
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("ADR", "Pobox;;;;;;Country",
|
||||
Arrays.asList("Pobox", "", "", "", "", "", "Country"), new TypeSet("HOME"));
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testPostalWithBothStructuredAndFormattedV21() {
|
||||
testPostalWithBothStructuredAndFormattedCommon(V21);
|
||||
}
|
||||
|
||||
public void testPostalWithBothStructuredAndFormattedV30() {
|
||||
testPostalWithBothStructuredAndFormattedCommon(V30);
|
||||
}
|
||||
|
||||
private void testOrganizationCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContentValues contentValues = resolver.buildData(Organization.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Organization.COMPANY, "CompanyX");
|
||||
contentValues.put(Organization.DEPARTMENT, "DepartmentY");
|
||||
contentValues.put(Organization.TITLE, "TitleZ");
|
||||
contentValues.put(Organization.JOB_DESCRIPTION, "Description Rambda"); // Ignored.
|
||||
contentValues.put(Organization.OFFICE_LOCATION, "Mountain View"); // Ignored.
|
||||
contentValues.put(Organization.PHONETIC_NAME, "PhoneticName!"); // Ignored
|
||||
contentValues.put(Organization.SYMBOL, "(^o^)/~~"); // Ignore him (her).
|
||||
|
||||
contentValues = resolver.buildData(Organization.CONTENT_ITEM_TYPE);
|
||||
contentValues.putNull(Organization.COMPANY);
|
||||
contentValues.put(Organization.DEPARTMENT, "DepartmentXX");
|
||||
contentValues.putNull(Organization.TITLE);
|
||||
|
||||
contentValues = resolver.buildData(Organization.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Organization.COMPANY, "CompanyXYZ");
|
||||
contentValues.putNull(Organization.DEPARTMENT);
|
||||
contentValues.put(Organization.TITLE, "TitleXYZYX");
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
|
||||
// Currently we do not use group but depend on the order.
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithOrder("ORG", "CompanyX;DepartmentY",
|
||||
Arrays.asList("CompanyX", "DepartmentY"))
|
||||
.addNodeWithOrder("TITLE", "TitleZ")
|
||||
.addNodeWithOrder("ORG", "DepartmentXX")
|
||||
.addNodeWithOrder("ORG", "CompanyXYZ")
|
||||
.addNodeWithOrder("TITLE", "TitleXYZYX");
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testOrganizationV21() {
|
||||
testOrganizationCommon(V21);
|
||||
}
|
||||
|
||||
public void testOrganizationV30() {
|
||||
testOrganizationCommon(V30);
|
||||
}
|
||||
|
||||
private void testImVariousTypeSupportCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_AIM);
|
||||
contentValues.put(Im.DATA, "aim");
|
||||
|
||||
contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_MSN);
|
||||
contentValues.put(Im.DATA, "msn");
|
||||
|
||||
contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_YAHOO);
|
||||
contentValues.put(Im.DATA, "yahoo");
|
||||
|
||||
contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_SKYPE);
|
||||
contentValues.put(Im.DATA, "skype");
|
||||
|
||||
contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_QQ);
|
||||
contentValues.put(Im.DATA, "qq");
|
||||
|
||||
contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
|
||||
contentValues.put(Im.DATA, "google talk");
|
||||
|
||||
contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_ICQ);
|
||||
contentValues.put(Im.DATA, "icq");
|
||||
|
||||
contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_JABBER);
|
||||
contentValues.put(Im.DATA, "jabber");
|
||||
|
||||
contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_NETMEETING);
|
||||
contentValues.put(Im.DATA, "netmeeting");
|
||||
|
||||
// No determined way to express unknown type...
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("X-JABBER", "jabber")
|
||||
.addNodeWithoutOrder("X-ICQ", "icq")
|
||||
.addNodeWithoutOrder("X-GOOGLE-TALK", "google talk")
|
||||
.addNodeWithoutOrder("X-QQ", "qq")
|
||||
.addNodeWithoutOrder("X-SKYPE-USERNAME", "skype")
|
||||
.addNodeWithoutOrder("X-YAHOO", "yahoo")
|
||||
.addNodeWithoutOrder("X-MSN", "msn")
|
||||
.addNodeWithoutOrder("X-NETMEETING", "netmeeting")
|
||||
.addNodeWithoutOrder("X-AIM", "aim");
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testImBasiV21() {
|
||||
testImVariousTypeSupportCommon(V21);
|
||||
}
|
||||
|
||||
public void testImBasicV30() {
|
||||
testImVariousTypeSupportCommon(V30);
|
||||
}
|
||||
|
||||
private void testImPrefHandlingCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_AIM);
|
||||
contentValues.put(Im.DATA, "aim1");
|
||||
|
||||
contentValues = resolver.buildData(Im.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Im.PROTOCOL, Im.PROTOCOL_AIM);
|
||||
contentValues.put(Im.DATA, "aim2");
|
||||
contentValues.put(Im.TYPE, Im.TYPE_HOME);
|
||||
contentValues.put(Im.IS_PRIMARY, 1);
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("X-AIM", "aim1")
|
||||
.addNodeWithoutOrder("X-AIM", "aim2", new TypeSet("HOME", "PREF"));
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testImPrefHandlingV21() {
|
||||
testImPrefHandlingCommon(V21);
|
||||
}
|
||||
|
||||
public void testImPrefHandlingV30() {
|
||||
testImPrefHandlingCommon(V30);
|
||||
}
|
||||
|
||||
private void testWebsiteCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(Website.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Website.URL, "http://website.example.android.com/index.html");
|
||||
contentValues.put(Website.TYPE, Website.TYPE_BLOG);
|
||||
|
||||
contentValues = resolver.buildData(Website.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Website.URL, "ftp://ftp.example.android.com/index.html");
|
||||
contentValues.put(Website.TYPE, Website.TYPE_FTP);
|
||||
|
||||
// We drop TYPE information since vCard (especially 3.0) does not allow us to emit it.
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("URL", "ftp://ftp.example.android.com/index.html")
|
||||
.addNodeWithoutOrder("URL", "http://website.example.android.com/index.html");
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testWebsiteV21() {
|
||||
testWebsiteCommon(V21);
|
||||
}
|
||||
|
||||
public void testWebsiteV30() {
|
||||
testWebsiteCommon(V30);
|
||||
}
|
||||
|
||||
private void testEventCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(Event.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Event.TYPE, Event.TYPE_ANNIVERSARY);
|
||||
contentValues.put(Event.START_DATE, "1982-06-16");
|
||||
|
||||
contentValues = resolver.buildData(Event.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Event.TYPE, Event.TYPE_BIRTHDAY);
|
||||
contentValues.put(Event.START_DATE, "2008-10-22");
|
||||
|
||||
contentValues = resolver.buildData(Event.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Event.TYPE, Event.TYPE_OTHER);
|
||||
contentValues.put(Event.START_DATE, "2018-03-12");
|
||||
|
||||
contentValues = resolver.buildData(Event.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Event.TYPE, Event.TYPE_CUSTOM);
|
||||
contentValues.put(Event.LABEL, "The last day");
|
||||
contentValues.put(Event.START_DATE, "When the Tower of Hanoi with 64 rings is completed.");
|
||||
|
||||
contentValues = resolver.buildData(Event.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Event.TYPE, Event.TYPE_BIRTHDAY);
|
||||
contentValues.put(Event.START_DATE, "2009-05-19");
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithoutOrder("BDAY", "2008-10-22");
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testEventV21() {
|
||||
testEventCommon(V21);
|
||||
}
|
||||
|
||||
public void testEventV30() {
|
||||
testEventCommon(V30);
|
||||
}
|
||||
|
||||
private void testNoteCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
|
||||
ContentValues contentValues = resolver.buildData(Note.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Note.NOTE, "note1");
|
||||
|
||||
contentValues = resolver.buildData(Note.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Note.NOTE, "note2");
|
||||
contentValues.put(Note.IS_PRIMARY, 1); // Just ignored.
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifierWithEmptyName()
|
||||
.addNodeWithOrder("NOTE", "note1")
|
||||
.addNodeWithOrder("NOTE", "note2");
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testNoteV21() {
|
||||
testNoteCommon(V21);
|
||||
}
|
||||
|
||||
public void testNoteV30() {
|
||||
testNoteCommon(V30);
|
||||
}
|
||||
|
||||
// TODO: test for non-ascii...
|
||||
|
||||
private void testPhotoCommon(int version) {
|
||||
final boolean isV30 = version == V30;
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "PhotoTest");
|
||||
|
||||
contentValues = resolver.buildData(Photo.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Photo.PHOTO, sPhotoByteArray);
|
||||
|
||||
ContentValues contentValuesForPhoto = new ContentValues();
|
||||
contentValuesForPhoto.put("ENCODING", (isV30 ? "b" : "BASE64"));
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||
handler.addNewVerifier()
|
||||
.addNodeWithoutOrder("FN", "PhotoTest")
|
||||
.addNodeWithoutOrder("N", "PhotoTest;;;;", Arrays.asList("PhotoTest", "", "", "", ""))
|
||||
.addNodeWithOrder("PHOTO", null, null, sPhotoByteArray,
|
||||
contentValuesForPhoto, new TypeSet("JPEG"), null);
|
||||
|
||||
verifyOneComposition(resolver, handler, version);
|
||||
}
|
||||
|
||||
public void testPhotoV21() {
|
||||
testPhotoCommon(false);
|
||||
testPhotoCommon(V21);
|
||||
}
|
||||
|
||||
public void testPhotoV30() {
|
||||
testPhotoCommon(true);
|
||||
testPhotoCommon(V30);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -722,7 +722,7 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
|
||||
public void testV21SimpleCase1_Type_Generic() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_simple_1, VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
R.raw.v21_simple_1, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "Ando");
|
||||
@@ -733,7 +733,7 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
|
||||
public void testV21SimpleCase1_Type_Japanese() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_simple_1, VCardConfig.VCARD_TYPE_V21_JAPANESE);
|
||||
R.raw.v21_simple_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "Ando");
|
||||
@@ -746,7 +746,7 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
|
||||
public void testV21SimpleCase2() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_simple_2, VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
R.raw.v21_simple_2, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.DISPLAY_NAME, "Ando Roid");
|
||||
@@ -755,7 +755,7 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
|
||||
public void testV21SimpleCase3() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_simple_3, VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
R.raw.v21_simple_3, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "Ando");
|
||||
@@ -790,7 +790,7 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
*/
|
||||
public void testV21BackslashCase() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_backslash, VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
R.raw.v21_backslash, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
// FAMILY_NAME is empty and removed in this test...
|
||||
@@ -804,7 +804,7 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
|
||||
public void testOrgBeforTitle() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_org_before_title, VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
R.raw.v21_org_before_title, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.DISPLAY_NAME, "Normal Guy");
|
||||
@@ -819,7 +819,7 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
|
||||
public void testTitleBeforOrg() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_title_before_org, VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
R.raw.v21_title_before_org, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.DISPLAY_NAME, "Nice Guy");
|
||||
@@ -838,7 +838,7 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
*/
|
||||
public void testV21PrefToIsPrimary() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_pref_handling, VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
R.raw.v21_pref_handling, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
|
||||
@@ -952,7 +952,7 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
*/
|
||||
public void testV21ComplicatedCase() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_complicated, VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
R.raw.v21_complicated, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "Gump");
|
||||
@@ -1068,7 +1068,7 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
|
||||
public void testV30Simple() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v30_simple, VCardConfig.VCARD_TYPE_V30_GENERIC);
|
||||
R.raw.v30_simple, VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "And");
|
||||
@@ -1139,25 +1139,28 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
verifier.verify();
|
||||
}
|
||||
/**
|
||||
* Verifies vCard with Japanese can be parsed correctly with VCARD_TYPE_V21_GENERIC.
|
||||
* Verifies vCard with Japanese can be parsed correctly with
|
||||
* {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_GENERIC_UTF8}.
|
||||
*/
|
||||
public void testV21Japanese1_Type_Generic() throws IOException, VCardException {
|
||||
public void testV21Japanese1_Type_Generic_Utf8() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
testV21Japanese1Common(verifier, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies vCard with Japanese can be parsed correctly with VCARD_TYPE_V21_JAPANESE.
|
||||
* Verifies vCard with Japanese can be parsed correctly with
|
||||
* {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_JAPANESE_SJIS}.
|
||||
*/
|
||||
public void testV21Japanese1_Type_Japanese() throws IOException, VCardException {
|
||||
public void testV21Japanese1_Type_Japanese_Sjis() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE);
|
||||
R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
|
||||
testV21Japanese1Common(verifier, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies vCard with Japanese can be parsed correctly with VCARD_TYPE_V21_JAPANESE_UTF8,
|
||||
* Verifies vCard with Japanese can be parsed correctly with
|
||||
* {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_JAPANESE_UTF8}.
|
||||
* since vCard 2.1 specifies the charset of each line if it contains non-Ascii.
|
||||
*/
|
||||
public void testV21Japanese1_Type_Japanese_Utf8() throws IOException, VCardException {
|
||||
@@ -1205,9 +1208,9 @@ public class VCardImporterTests extends AndroidTestCase {
|
||||
verifier.verify(builder.vNodeList.get(0));
|
||||
}
|
||||
|
||||
public void testV21Japanese2_Type_Generic() throws IOException, VCardException {
|
||||
public void testV21Japanese2_Type_Generic_Utf8() throws IOException, VCardException {
|
||||
ContactStructVerifier verifier = new ContactStructVerifier(
|
||||
R.raw.v21_japanese_2, VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
R.raw.v21_japanese_2, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
ContentValues contentValues =
|
||||
verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "\u5B89\u85E4");
|
||||
|
||||
Reference in New Issue
Block a user