diff options
author | Chiao Cheng <chiaocheng@google.com> | 2012-11-13 18:38:56 -0800 |
---|---|---|
committer | Chiao Cheng <chiaocheng@google.com> | 2012-11-13 18:38:56 -0800 |
commit | 428f008513d1591cc08fcfe2cf0c9237fb313241 (patch) | |
tree | 91d7e0ec7e18d839191f00046dc46627db51d95f /src/com | |
parent | e776d0366d5bf2f93a0cd0f14e48804e564bccf2 (diff) | |
download | packages_apps_Contacts-428f008513d1591cc08fcfe2cf0c9237fb313241.tar.gz packages_apps_Contacts-428f008513d1591cc08fcfe2cf0c9237fb313241.tar.bz2 packages_apps_Contacts-428f008513d1591cc08fcfe2cf0c9237fb313241.zip |
Move dependencies of AccountTypeManager into ContactsCommon.
Moving dependencies in preparation to move AccountTypeManager.
Bug: 6993891
Change-Id: I804cdbe64b9b8111ed286037943d593e11dc4044
Diffstat (limited to 'src/com')
71 files changed, 118 insertions, 3680 deletions
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java index f1a5a7289..64d553100 100644 --- a/src/com/android/contacts/ContactSaveService.java +++ b/src/com/android/contacts/ContactSaveService.java @@ -51,7 +51,7 @@ import com.android.contacts.model.AccountTypeManager; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDeltaList; import com.android.contacts.model.RawContactModifier; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.util.CallerInfoCacheUtils; import com.google.common.collect.Lists; import com.google.common.collect.Sets; diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java index 3575b8048..a53a423ef 100644 --- a/src/com/android/contacts/ContactsUtils.java +++ b/src/com/android/contacts/ContactsUtils.java @@ -27,9 +27,9 @@ import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; -import com.android.contacts.test.NeededForTesting; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; +import com.android.contacts.common.test.NeededForTesting; import java.util.List; diff --git a/src/com/android/contacts/SplitAggregateView.java b/src/com/android/contacts/SplitAggregateView.java index 1b42ca3e5..fabd58b1d 100644 --- a/src/com/android/contacts/SplitAggregateView.java +++ b/src/com/android/contacts/SplitAggregateView.java @@ -36,7 +36,7 @@ import android.widget.ListView; import android.widget.TextView; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import java.util.ArrayList; import java.util.Collections; diff --git a/src/com/android/contacts/activities/AttachPhotoActivity.java b/src/com/android/contacts/activities/AttachPhotoActivity.java index b6d7c2d8e..54f2de830 100644 --- a/src/com/android/contacts/activities/AttachPhotoActivity.java +++ b/src/com/android/contacts/activities/AttachPhotoActivity.java @@ -38,7 +38,7 @@ import com.android.contacts.model.ContactLoader; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDeltaList; import com.android.contacts.model.RawContactModifier; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import com.android.contacts.util.ContactPhotoUtils; import java.io.File; diff --git a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java index 84206f80f..9bd4f45b5 100644 --- a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java +++ b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java @@ -67,9 +67,9 @@ import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; import com.android.contacts.model.RawContactDeltaList; import com.android.contacts.model.RawContactModifier; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.util.DialogManager; import com.android.contacts.util.EmptyService; diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java index b03a976b7..3cbc39deb 100644 --- a/src/com/android/contacts/activities/ContactDetailActivity.java +++ b/src/com/android/contacts/activities/ContactDetailActivity.java @@ -47,7 +47,7 @@ import com.android.contacts.detail.ContactLoaderFragment; import com.android.contacts.detail.ContactLoaderFragment.ContactLoaderFragmentListener; import com.android.contacts.interactions.ContactDeletionInteraction; import com.android.contacts.model.Contact; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.util.PhoneCapabilityTester; import java.util.ArrayList; diff --git a/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java b/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java index f5852e50d..13c49e127 100644 --- a/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java +++ b/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java @@ -31,7 +31,7 @@ import android.widget.TextView; import com.android.contacts.R; import com.android.contacts.editor.ContactEditorUtils; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.util.AccountsListAdapter; import com.android.contacts.util.AccountsListAdapter.AccountListFilter; @@ -189,4 +189,4 @@ public class ContactEditorAccountsChangedActivity extends Activity { setResult(RESULT_OK, intent); finish(); } -}
\ No newline at end of file +} diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java index 77ed85702..efdf7da76 100644 --- a/src/com/android/contacts/activities/ContactEditorActivity.java +++ b/src/com/android/contacts/activities/ContactEditorActivity.java @@ -37,8 +37,8 @@ import com.android.contacts.R; import com.android.contacts.editor.ContactEditorFragment; import com.android.contacts.editor.ContactEditorFragment.SaveMode; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.util.DialogManager; import java.util.ArrayList; diff --git a/src/com/android/contacts/activities/GroupDetailActivity.java b/src/com/android/contacts/activities/GroupDetailActivity.java index 492a2ffbb..c2764c323 100644 --- a/src/com/android/contacts/activities/GroupDetailActivity.java +++ b/src/com/android/contacts/activities/GroupDetailActivity.java @@ -34,7 +34,7 @@ import com.android.contacts.R; import com.android.contacts.group.GroupDetailDisplayUtils; import com.android.contacts.group.GroupDetailFragment; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; public class GroupDetailActivity extends ContactsActivity { diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java index 66b3ca338..53ffca956 100644 --- a/src/com/android/contacts/activities/PeopleActivity.java +++ b/src/com/android/contacts/activities/PeopleActivity.java @@ -80,7 +80,7 @@ import com.android.contacts.list.OnContactsUnavailableActionListener; import com.android.contacts.list.ProviderStatusWatcher; import com.android.contacts.list.ProviderStatusWatcher.ProviderStatusListener; import com.android.contacts.model.Contact; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.preference.ContactsPreferenceActivity; import com.android.contacts.preference.DisplayOptionsPreferenceFragment; import com.android.contacts.util.AccountFilterUtil; diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java index 7cc95b9ad..cf1595dff 100644 --- a/src/com/android/contacts/detail/ContactDetailFragment.java +++ b/src/com/android/contacts/detail/ContactDetailFragment.java @@ -89,11 +89,11 @@ import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; import com.android.contacts.model.RawContactDeltaList; import com.android.contacts.model.RawContactModifier; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountType.EditType; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType.EditType; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.model.dataitem.DataItem; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.model.dataitem.EmailDataItem; import com.android.contacts.model.dataitem.EventDataItem; import com.android.contacts.model.dataitem.GroupMembershipDataItem; diff --git a/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java b/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java index 88c30c248..46e4dad75 100644 --- a/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java +++ b/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java @@ -33,7 +33,7 @@ import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener import com.android.contacts.detail.ContactDetailDisplayUtils.StreamPhotoTag; import com.android.contacts.model.AccountTypeManager; import com.android.contacts.model.Contact; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import com.android.contacts.util.StreamItemEntry; public class ContactDetailUpdatesFragment extends ListFragment implements FragmentKeyListener { diff --git a/src/com/android/contacts/detail/PhotoSelectionHandler.java b/src/com/android/contacts/detail/PhotoSelectionHandler.java index b5e406a24..d544b305b 100644 --- a/src/com/android/contacts/detail/PhotoSelectionHandler.java +++ b/src/com/android/contacts/detail/PhotoSelectionHandler.java @@ -43,7 +43,7 @@ import com.android.contacts.model.AccountTypeManager; import com.android.contacts.model.RawContactModifier; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import com.android.contacts.model.RawContactDeltaList; import com.android.contacts.util.ContactPhotoUtils; diff --git a/src/com/android/contacts/detail/StreamItemAdapter.java b/src/com/android/contacts/detail/StreamItemAdapter.java index 15219cd5c..398ac69d6 100644 --- a/src/com/android/contacts/detail/StreamItemAdapter.java +++ b/src/com/android/contacts/detail/StreamItemAdapter.java @@ -24,7 +24,7 @@ import android.widget.BaseAdapter; import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import com.android.contacts.util.StreamItemEntry; import com.google.common.collect.Lists; diff --git a/src/com/android/contacts/editor/AggregationSuggestionView.java b/src/com/android/contacts/editor/AggregationSuggestionView.java index 7327a4caa..19481fe98 100644 --- a/src/com/android/contacts/editor/AggregationSuggestionView.java +++ b/src/com/android/contacts/editor/AggregationSuggestionView.java @@ -29,7 +29,7 @@ import com.android.contacts.R; import com.android.contacts.editor.AggregationSuggestionEngine.RawContact; import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import com.google.common.collect.Lists; import java.util.ArrayList; diff --git a/src/com/android/contacts/editor/BaseRawContactEditorView.java b/src/com/android/contacts/editor/BaseRawContactEditorView.java index 66fc8642b..1ff9ac284 100644 --- a/src/com/android/contacts/editor/BaseRawContactEditorView.java +++ b/src/com/android/contacts/editor/BaseRawContactEditorView.java @@ -31,8 +31,8 @@ import com.android.contacts.R; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; import com.android.contacts.model.RawContactModifier; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountType.EditType; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType.EditType; /** * Base view that provides common code for the editor interaction for a specific diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java index f840bb5cb..17b6e505d 100644 --- a/src/com/android/contacts/editor/ContactEditorFragment.java +++ b/src/com/android/contacts/editor/ContactEditorFragment.java @@ -78,9 +78,9 @@ import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; import com.android.contacts.model.RawContactDeltaList; import com.android.contacts.model.RawContactModifier; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; -import com.android.contacts.model.account.GoogleAccountType; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.GoogleAccountType; import com.android.contacts.util.AccountsListAdapter; import com.android.contacts.util.AccountsListAdapter.AccountListFilter; import com.android.contacts.util.ContactPhotoUtils; diff --git a/src/com/android/contacts/editor/ContactEditorUtils.java b/src/com/android/contacts/editor/ContactEditorUtils.java index 2791c2dfc..735f8beb2 100644 --- a/src/com/android/contacts/editor/ContactEditorUtils.java +++ b/src/com/android/contacts/editor/ContactEditorUtils.java @@ -26,10 +26,10 @@ import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.Log; +import com.android.contacts.common.test.NeededForTesting; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; -import com.android.contacts.test.NeededForTesting; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import com.google.common.collect.Sets; diff --git a/src/com/android/contacts/editor/Editor.java b/src/com/android/contacts/editor/Editor.java index 05336f2bd..ec816f7a9 100644 --- a/src/com/android/contacts/editor/Editor.java +++ b/src/com/android/contacts/editor/Editor.java @@ -20,7 +20,7 @@ import android.provider.ContactsContract.Data; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.dataitem.DataKind; /** * Generic definition of something that edits a {@link Data} row through an diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java index 77f20107c..1f6cd4351 100644 --- a/src/com/android/contacts/editor/EventFieldEditorView.java +++ b/src/com/android/contacts/editor/EventFieldEditorView.java @@ -31,9 +31,9 @@ import com.android.contacts.datepicker.DatePickerDialog; import com.android.contacts.datepicker.DatePickerDialog.OnDateSetListener; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.account.AccountType.EditField; -import com.android.contacts.model.account.AccountType.EventEditType; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.account.AccountType.EditField; +import com.android.contacts.common.model.account.AccountType.EventEditType; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.util.DateUtils; import java.text.ParsePosition; diff --git a/src/com/android/contacts/editor/GroupMembershipView.java b/src/com/android/contacts/editor/GroupMembershipView.java index b84e22bbb..8f9b65a45 100644 --- a/src/com/android/contacts/editor/GroupMembershipView.java +++ b/src/com/android/contacts/editor/GroupMembershipView.java @@ -42,7 +42,7 @@ import com.android.contacts.interactions.GroupCreationDialogFragment.OnGroupCrea import com.android.contacts.model.RawContactModifier; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.internal.util.Objects; import java.util.ArrayList; diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java index 9cfe0a377..4f70cd414 100644 --- a/src/com/android/contacts/editor/KindSectionView.java +++ b/src/com/android/contacts/editor/KindSectionView.java @@ -31,7 +31,7 @@ import com.android.contacts.editor.Editor.EditorListener; import com.android.contacts.model.RawContactModifier; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.dataitem.DataKind; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java index 789f42591..91339ae81 100644 --- a/src/com/android/contacts/editor/LabeledEditorView.java +++ b/src/com/android/contacts/editor/LabeledEditorView.java @@ -49,8 +49,8 @@ import com.android.contacts.R; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; import com.android.contacts.model.RawContactModifier; -import com.android.contacts.model.account.AccountType.EditType; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.account.AccountType.EditType; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.util.DialogManager; import com.android.contacts.util.DialogManager.DialogShowingView; diff --git a/src/com/android/contacts/editor/PhoneticNameEditorView.java b/src/com/android/contacts/editor/PhoneticNameEditorView.java index 8cbb9211f..1ee7e217d 100644 --- a/src/com/android/contacts/editor/PhoneticNameEditorView.java +++ b/src/com/android/contacts/editor/PhoneticNameEditorView.java @@ -23,7 +23,7 @@ import android.util.AttributeSet; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.model.dataitem.StructuredNameDataItem; /** diff --git a/src/com/android/contacts/editor/PhotoEditorView.java b/src/com/android/contacts/editor/PhotoEditorView.java index 30c3bb42e..e106eac6e 100644 --- a/src/com/android/contacts/editor/PhotoEditorView.java +++ b/src/com/android/contacts/editor/PhotoEditorView.java @@ -29,7 +29,7 @@ import com.android.contacts.ContactsUtils; import com.android.contacts.R; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.util.ContactPhotoUtils; /** diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java index daccdd85c..2f531555a 100644 --- a/src/com/android/contacts/editor/RawContactEditorView.java +++ b/src/com/android/contacts/editor/RawContactEditorView.java @@ -41,9 +41,9 @@ import com.android.contacts.R; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; import com.android.contacts.model.RawContactModifier; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountType.EditType; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType.EditType; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.internal.util.Objects; import java.util.ArrayList; diff --git a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java index e963d485f..8f9dcb986 100644 --- a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java +++ b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java @@ -42,9 +42,9 @@ import com.android.contacts.common.GeoUtil; import com.android.contacts.model.RawContactModifier; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; +import com.android.contacts.common.model.dataitem.DataKind; import java.util.ArrayList; diff --git a/src/com/android/contacts/editor/SelectAccountDialogFragment.java b/src/com/android/contacts/editor/SelectAccountDialogFragment.java index 3e7ad0e6c..a57507431 100644 --- a/src/com/android/contacts/editor/SelectAccountDialogFragment.java +++ b/src/com/android/contacts/editor/SelectAccountDialogFragment.java @@ -24,7 +24,7 @@ import android.app.FragmentManager; import android.content.DialogInterface; import android.os.Bundle; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.util.AccountsListAdapter; import com.android.contacts.util.AccountsListAdapter.AccountListFilter; diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java index bac3b7958..fcafe75f5 100644 --- a/src/com/android/contacts/editor/StructuredNameEditorView.java +++ b/src/com/android/contacts/editor/StructuredNameEditorView.java @@ -28,7 +28,7 @@ import android.util.AttributeSet; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; import com.android.contacts.model.dataitem.DataItem; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.model.dataitem.StructuredNameDataItem; import com.android.contacts.util.NameConverter; diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java index e48ba5154..970bbbfc8 100644 --- a/src/com/android/contacts/editor/TextFieldsEditorView.java +++ b/src/com/android/contacts/editor/TextFieldsEditorView.java @@ -39,8 +39,8 @@ import com.android.contacts.ContactsUtils; import com.android.contacts.R; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.account.AccountType.EditField; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.account.AccountType.EditField; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.common.util.PhoneNumberFormatter; /** diff --git a/src/com/android/contacts/editor/ViewIdGenerator.java b/src/com/android/contacts/editor/ViewIdGenerator.java index 55a42a738..9f4162320 100644 --- a/src/com/android/contacts/editor/ViewIdGenerator.java +++ b/src/com/android/contacts/editor/ViewIdGenerator.java @@ -22,7 +22,7 @@ import android.os.Parcelable; import com.android.contacts.model.RawContactDelta; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.dataitem.DataKind; /** * A class that provides unique view ids for {@link ContentEditorView}, {@link KindSectionView}, diff --git a/src/com/android/contacts/group/GroupBrowseListAdapter.java b/src/com/android/contacts/group/GroupBrowseListAdapter.java index acea625a2..88756e151 100644 --- a/src/com/android/contacts/group/GroupBrowseListAdapter.java +++ b/src/com/android/contacts/group/GroupBrowseListAdapter.java @@ -30,7 +30,7 @@ import android.widget.TextView; import com.android.contacts.GroupListLoader; import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import com.android.internal.util.Objects; /** diff --git a/src/com/android/contacts/group/GroupDetailDisplayUtils.java b/src/com/android/contacts/group/GroupDetailDisplayUtils.java index d4e43a0e7..1cf783138 100644 --- a/src/com/android/contacts/group/GroupDetailDisplayUtils.java +++ b/src/com/android/contacts/group/GroupDetailDisplayUtils.java @@ -24,7 +24,7 @@ import android.widget.TextView; import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; public class GroupDetailDisplayUtils { diff --git a/src/com/android/contacts/group/GroupDetailFragment.java b/src/com/android/contacts/group/GroupDetailFragment.java index 020e30a9f..89cb63c7e 100644 --- a/src/com/android/contacts/group/GroupDetailFragment.java +++ b/src/com/android/contacts/group/GroupDetailFragment.java @@ -54,7 +54,7 @@ import com.android.contacts.common.list.ContactTileAdapter; import com.android.contacts.common.list.ContactTileView; import com.android.contacts.list.GroupMemberTileAdapter; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; /** * Displays the details of a group and shows a list of actions possible for the group. diff --git a/src/com/android/contacts/group/GroupEditorFragment.java b/src/com/android/contacts/group/GroupEditorFragment.java index 355cca722..7089fc60d 100644 --- a/src/com/android/contacts/group/GroupEditorFragment.java +++ b/src/com/android/contacts/group/GroupEditorFragment.java @@ -67,8 +67,8 @@ import com.android.contacts.activities.GroupEditorActivity; import com.android.contacts.editor.SelectAccountDialogFragment; import com.android.contacts.group.SuggestedMemberListAdapter.SuggestedMember; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.util.AccountsListAdapter.AccountListFilter; import com.android.contacts.util.ViewUtil; import com.android.internal.util.Objects; diff --git a/src/com/android/contacts/interactions/ContactDeletionInteraction.java b/src/com/android/contacts/interactions/ContactDeletionInteraction.java index ea6e6dc6f..c4387f3ab 100644 --- a/src/com/android/contacts/interactions/ContactDeletionInteraction.java +++ b/src/com/android/contacts/interactions/ContactDeletionInteraction.java @@ -36,7 +36,7 @@ import android.provider.ContactsContract.Contacts.Entity; import com.android.contacts.ContactSaveService; import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Sets; diff --git a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java index 5731bc1cd..b2860eae2 100644 --- a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java +++ b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java @@ -23,7 +23,7 @@ import android.widget.EditText; import com.android.contacts.ContactSaveService; import com.android.contacts.R; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; /** * A dialog for creating a new group. diff --git a/src/com/android/contacts/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/interactions/ImportExportDialogFragment.java index f63f84c48..3f409cba3 100644 --- a/src/com/android/contacts/interactions/ImportExportDialogFragment.java +++ b/src/com/android/contacts/interactions/ImportExportDialogFragment.java @@ -40,7 +40,7 @@ import android.widget.Toast; import com.android.contacts.R; import com.android.contacts.editor.SelectAccountDialogFragment; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.util.AccountSelectionUtil; import com.android.contacts.util.AccountsListAdapter.AccountListFilter; import com.android.contacts.vcard.ExportVCardActivity; diff --git a/src/com/android/contacts/list/AccountFilterActivity.java b/src/com/android/contacts/list/AccountFilterActivity.java index 18d703fdf..cc986ad7b 100644 --- a/src/com/android/contacts/list/AccountFilterActivity.java +++ b/src/com/android/contacts/list/AccountFilterActivity.java @@ -38,8 +38,8 @@ import com.android.contacts.ContactsActivity; import com.android.contacts.R; import com.android.contacts.common.list.ContactListFilter; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.google.common.collect.Lists; import java.util.ArrayList; diff --git a/src/com/android/contacts/list/ContactListFilterController.java b/src/com/android/contacts/list/ContactListFilterController.java index b8086b020..569dd5dc4 100644 --- a/src/com/android/contacts/list/ContactListFilterController.java +++ b/src/com/android/contacts/list/ContactListFilterController.java @@ -21,7 +21,7 @@ import android.preference.PreferenceManager; import com.android.contacts.common.list.ContactListFilter; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/contacts/list/ContactListFilterView.java b/src/com/android/contacts/list/ContactListFilterView.java index a71809b3f..8102f65db 100644 --- a/src/com/android/contacts/list/ContactListFilterView.java +++ b/src/com/android/contacts/list/ContactListFilterView.java @@ -28,7 +28,7 @@ import android.widget.TextView; import com.android.contacts.R; import com.android.contacts.common.list.ContactListFilter; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; /** * Contact list filter parameters. diff --git a/src/com/android/contacts/list/CustomContactListFilterActivity.java b/src/com/android/contacts/list/CustomContactListFilterActivity.java index c62b38955..532bbee6f 100644 --- a/src/com/android/contacts/list/CustomContactListFilterActivity.java +++ b/src/com/android/contacts/list/CustomContactListFilterActivity.java @@ -57,9 +57,9 @@ import com.android.contacts.ContactsActivity; import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; -import com.android.contacts.model.account.GoogleAccountType; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.GoogleAccountType; import com.android.contacts.util.EmptyService; import com.android.contacts.util.LocalizedNameResolver; import com.android.contacts.util.WeakAsyncTask; diff --git a/src/com/android/contacts/model/AccountTypeManager.java b/src/com/android/contacts/model/AccountTypeManager.java index 5205ee076..75e50f844 100644 --- a/src/com/android/contacts/model/AccountTypeManager.java +++ b/src/com/android/contacts/model/AccountTypeManager.java @@ -45,15 +45,15 @@ import android.util.TimingLogger; import com.android.contacts.ContactsUtils; import com.android.contacts.list.ContactListFilterController; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountTypeWithDataSet; -import com.android.contacts.model.account.AccountWithDataSet; -import com.android.contacts.model.account.ExchangeAccountType; -import com.android.contacts.model.account.ExternalAccountType; -import com.android.contacts.model.account.FallbackAccountType; -import com.android.contacts.model.account.GoogleAccountType; -import com.android.contacts.model.dataitem.DataKind; -import com.android.contacts.test.NeededForTesting; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountTypeWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.ExchangeAccountType; +import com.android.contacts.common.model.account.ExternalAccountType; +import com.android.contacts.common.model.account.FallbackAccountType; +import com.android.contacts.common.model.account.GoogleAccountType; +import com.android.contacts.common.model.dataitem.DataKind; +import com.android.contacts.common.test.NeededForTesting; import com.android.contacts.util.Constants; import com.android.internal.util.Objects; import com.google.common.annotations.VisibleForTesting; diff --git a/src/com/android/contacts/model/Contact.java b/src/com/android/contacts/model/Contact.java index a097a256c..0314c3ca2 100644 --- a/src/com/android/contacts/model/Contact.java +++ b/src/com/android/contacts/model/Contact.java @@ -25,7 +25,7 @@ import android.provider.ContactsContract.Directory; import android.provider.ContactsContract.DisplayNameSources; import com.android.contacts.GroupMetaData; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import com.android.contacts.util.DataStatus; import com.android.contacts.util.StreamItemEntry; import com.google.common.annotations.VisibleForTesting; diff --git a/src/com/android/contacts/model/ContactLoader.java b/src/com/android/contacts/model/ContactLoader.java index bbab0f5cb..625980030 100644 --- a/src/com/android/contacts/model/ContactLoader.java +++ b/src/com/android/contacts/model/ContactLoader.java @@ -43,8 +43,8 @@ import android.util.LongSparseArray; import com.android.contacts.GroupMetaData; import com.android.contacts.common.GeoUtil; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountTypeWithDataSet; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountTypeWithDataSet; import com.android.contacts.model.dataitem.DataItem; import com.android.contacts.model.dataitem.PhoneDataItem; import com.android.contacts.model.dataitem.PhotoDataItem; diff --git a/src/com/android/contacts/model/RawContact.java b/src/com/android/contacts/model/RawContact.java index 823a853b4..c4e5f3e35 100644 --- a/src/com/android/contacts/model/RawContact.java +++ b/src/com/android/contacts/model/RawContact.java @@ -26,8 +26,8 @@ import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.RawContacts; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.model.dataitem.DataItem; import com.google.common.base.Objects; import com.google.common.collect.Lists; diff --git a/src/com/android/contacts/model/RawContactDelta.java b/src/com/android/contacts/model/RawContactDelta.java index b38117422..f7ddcc97f 100644 --- a/src/com/android/contacts/model/RawContactDelta.java +++ b/src/com/android/contacts/model/RawContactDelta.java @@ -34,8 +34,8 @@ import android.provider.ContactsContract.Profile; import android.provider.ContactsContract.RawContacts; import android.util.Log; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.test.NeededForTesting; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.test.NeededForTesting; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; diff --git a/src/com/android/contacts/model/RawContactModifier.java b/src/com/android/contacts/model/RawContactModifier.java index 0c12c9449..1b8d0fef8 100644 --- a/src/com/android/contacts/model/RawContactModifier.java +++ b/src/com/android/contacts/model/RawContactModifier.java @@ -47,15 +47,16 @@ import android.util.SparseArray; import android.util.SparseIntArray; import com.android.contacts.ContactsUtils; +import com.android.contacts.common.util.CommonDateUtils; import com.android.contacts.editor.EventFieldEditorView; import com.android.contacts.editor.PhoneticNameEditorView; import com.android.contacts.model.RawContactDelta.ValuesDelta; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountType.EditField; -import com.android.contacts.model.account.AccountType.EditType; -import com.android.contacts.model.account.AccountType.EventEditType; -import com.android.contacts.model.account.GoogleAccountType; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType.EditField; +import com.android.contacts.common.model.account.AccountType.EditType; +import com.android.contacts.common.model.account.AccountType.EventEditType; +import com.android.contacts.common.model.account.GoogleAccountType; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.model.dataitem.StructuredNameDataItem; import com.android.contacts.util.DateUtils; import com.android.contacts.util.NameConverter; @@ -1263,10 +1264,10 @@ public class RawContactModifier { final ParsePosition position = new ParsePosition(0); boolean yearOptional = false; - Date date = DateUtils.DATE_AND_TIME_FORMAT.parse(dateString, position); + Date date = CommonDateUtils.DATE_AND_TIME_FORMAT.parse(dateString, position); if (date == null) { yearOptional = true; - date = DateUtils.NO_YEAR_DATE_FORMAT.parse(dateString, position); + date = CommonDateUtils.NO_YEAR_DATE_FORMAT.parse(dateString, position); } if (date != null) { if (yearOptional && !suitableType.isYearOptional()) { @@ -1283,7 +1284,7 @@ public class RawContactModifier { calendar.set(defaultYear, month, day, EventFieldEditorView.getDefaultHourForBirthday(), 0, 0); values.put(Event.START_DATE, - DateUtils.FULL_DATE_FORMAT.format(calendar.getTime())); + CommonDateUtils.FULL_DATE_FORMAT.format(calendar.getTime())); } } newState.addEntry(ValuesDelta.fromAfter(values)); diff --git a/src/com/android/contacts/model/account/AccountType.java b/src/com/android/contacts/model/account/AccountType.java deleted file mode 100644 index ca3dc6872..000000000 --- a/src/com/android/contacts/model/account/AccountType.java +++ /dev/null @@ -1,531 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.contacts.model.account; - -import android.content.ContentValues; -import android.content.Context; -import android.content.pm.PackageManager; -import android.graphics.drawable.Drawable; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; -import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.RawContacts; -import android.view.inputmethod.EditorInfo; -import android.widget.EditText; - -import com.android.contacts.R; -import com.android.contacts.model.dataitem.DataKind; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import java.text.Collator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; - -/** - * Internal structure that represents constraints and styles for a specific data - * source, such as the various data types they support, including details on how - * those types should be rendered and edited. - * <p> - * In the future this may be inflated from XML defined by a data source. - */ -public abstract class AccountType { - private static final String TAG = "AccountType"; - - /** - * The {@link RawContacts#ACCOUNT_TYPE} these constraints apply to. - */ - public String accountType = null; - - /** - * The {@link RawContacts#DATA_SET} these constraints apply to. - */ - public String dataSet = null; - - /** - * Package that resources should be loaded from. Will be null for embedded types, in which - * case resources are stored in this package itself. - * - * TODO Clean up {@link #resourcePackageName}, {@link #syncAdapterPackageName} and - * {@link #getViewContactNotifyServicePackageName()}. - * - * There's the following invariants: - * - {@link #syncAdapterPackageName} is always set to the actual sync adapter package name. - * - {@link #resourcePackageName} too is set to the same value, unless {@link #isEmbedded()}, - * in which case it'll be null. - * There's an unfortunate exception of {@link FallbackAccountType}. Even though it - * {@link #isEmbedded()}, but we set non-null to {@link #resourcePackageName} for unit tests. - */ - public String resourcePackageName; - /** - * The package name for the authenticator (for the embedded types, i.e. Google and Exchange) - * or the sync adapter (for external type, including extensions). - */ - public String syncAdapterPackageName; - - public int titleRes; - public int iconRes; - - /** - * Set of {@link DataKind} supported by this source. - */ - private ArrayList<DataKind> mKinds = Lists.newArrayList(); - - /** - * Lookup map of {@link #mKinds} on {@link DataKind#mimeType}. - */ - private HashMap<String, DataKind> mMimeKinds = Maps.newHashMap(); - - protected boolean mIsInitialized; - - protected static class DefinitionException extends Exception { - public DefinitionException(String message) { - super(message); - } - - public DefinitionException(String message, Exception inner) { - super(message, inner); - } - } - - /** - * Whether this account type was able to be fully initialized. This may be false if - * (for example) the package name associated with the account type could not be found. - */ - public final boolean isInitialized() { - return mIsInitialized; - } - - /** - * @return Whether this type is an "embedded" type. i.e. any of {@link FallbackAccountType}, - * {@link GoogleAccountType} or {@link ExternalAccountType}. - * - * If an embedded type cannot be initialized (i.e. if {@link #isInitialized()} returns - * {@code false}) it's considered critical, and the application will crash. On the other - * hand if it's not an embedded type, we just skip loading the type. - */ - public boolean isEmbedded() { - return true; - } - - public boolean isExtension() { - return false; - } - - /** - * @return True if contacts can be created and edited using this app. If false, - * there could still be an external editor as provided by - * {@link #getEditContactActivityClassName()} or {@link #getCreateContactActivityClassName()} - */ - public abstract boolean areContactsWritable(); - - /** - * Returns an optional custom edit activity. - * - * Only makes sense for non-embedded account types. - * The activity class should reside in the sync adapter package as determined by - * {@link #syncAdapterPackageName}. - */ - public String getEditContactActivityClassName() { - return null; - } - - /** - * Returns an optional custom new contact activity. - * - * Only makes sense for non-embedded account types. - * The activity class should reside in the sync adapter package as determined by - * {@link #syncAdapterPackageName}. - */ - public String getCreateContactActivityClassName() { - return null; - } - - /** - * Returns an optional custom invite contact activity. - * - * Only makes sense for non-embedded account types. - * The activity class should reside in the sync adapter package as determined by - * {@link #syncAdapterPackageName}. - */ - public String getInviteContactActivityClassName() { - return null; - } - - /** - * Returns an optional service that can be launched whenever a contact is being looked at. - * This allows the sync adapter to provide more up-to-date information. - * - * The service class should reside in the sync adapter package as determined by - * {@link #getViewContactNotifyServicePackageName()}. - */ - public String getViewContactNotifyServiceClassName() { - return null; - } - - /** - * TODO This is way too hacky should be removed. - * - * This is introduced for {@link GoogleAccountType} where {@link #syncAdapterPackageName} - * is the authenticator package name but the notification service is in the sync adapter - * package. See {@link #resourcePackageName} -- we should clean up those. - */ - public String getViewContactNotifyServicePackageName() { - return syncAdapterPackageName; - } - - /** Returns an optional Activity string that can be used to view the group. */ - public String getViewGroupActivity() { - return null; - } - - /** Returns an optional Activity string that can be used to view the stream item. */ - public String getViewStreamItemActivity() { - return null; - } - - /** Returns an optional Activity string that can be used to view the stream item photo. */ - public String getViewStreamItemPhotoActivity() { - return null; - } - - public CharSequence getDisplayLabel(Context context) { - // Note this resource is defined in the sync adapter package, not resourcePackageName. - return getResourceText(context, syncAdapterPackageName, titleRes, accountType); - } - - /** - * @return resource ID for the "invite contact" action label, or -1 if not defined. - */ - protected int getInviteContactActionResId() { - return -1; - } - - /** - * @return resource ID for the "view group" label, or -1 if not defined. - */ - protected int getViewGroupLabelResId() { - return -1; - } - - /** - * Returns {@link AccountTypeWithDataSet} for this type. - */ - public AccountTypeWithDataSet getAccountTypeAndDataSet() { - return AccountTypeWithDataSet.get(accountType, dataSet); - } - - /** - * Returns a list of additional package names that should be inspected as additional - * external account types. This allows for a primary account type to indicate other packages - * that may not be sync adapters but which still provide contact data, perhaps under a - * separate data set within the account. - */ - public List<String> getExtensionPackageNames() { - return new ArrayList<String>(); - } - - /** - * Returns an optional custom label for the "invite contact" action, which will be shown on - * the contact card. (If not defined, returns null.) - */ - public CharSequence getInviteContactActionLabel(Context context) { - // Note this resource is defined in the sync adapter package, not resourcePackageName. - return getResourceText(context, syncAdapterPackageName, getInviteContactActionResId(), ""); - } - - /** - * Returns a label for the "view group" action. If not defined, this falls back to our - * own "View Updates" string - */ - public CharSequence getViewGroupLabel(Context context) { - // Note this resource is defined in the sync adapter package, not resourcePackageName. - final CharSequence customTitle = - getResourceText(context, syncAdapterPackageName, getViewGroupLabelResId(), null); - - return customTitle == null - ? context.getText(R.string.view_updates_from_group) - : customTitle; - } - - /** - * Return a string resource loaded from the given package (or the current package - * if {@code packageName} is null), unless {@code resId} is -1, in which case it returns - * {@code defaultValue}. - * - * (The behavior is undefined if the resource or package doesn't exist.) - */ - @VisibleForTesting - static CharSequence getResourceText(Context context, String packageName, int resId, - String defaultValue) { - if (resId != -1 && packageName != null) { - final PackageManager pm = context.getPackageManager(); - return pm.getText(packageName, resId, null); - } else if (resId != -1) { - return context.getText(resId); - } else { - return defaultValue; - } - } - - public Drawable getDisplayIcon(Context context) { - if (this.titleRes != -1 && this.syncAdapterPackageName != null) { - final PackageManager pm = context.getPackageManager(); - return pm.getDrawable(this.syncAdapterPackageName, this.iconRes, null); - } else if (this.titleRes != -1) { - return context.getResources().getDrawable(this.iconRes); - } else { - return null; - } - } - - /** - * Whether or not groups created under this account type have editable membership lists. - */ - abstract public boolean isGroupMembershipEditable(); - - /** - * {@link Comparator} to sort by {@link DataKind#weight}. - */ - private static Comparator<DataKind> sWeightComparator = new Comparator<DataKind>() { - @Override - public int compare(DataKind object1, DataKind object2) { - return object1.weight - object2.weight; - } - }; - - /** - * Return list of {@link DataKind} supported, sorted by - * {@link DataKind#weight}. - */ - public ArrayList<DataKind> getSortedDataKinds() { - // TODO: optimize by marking if already sorted - Collections.sort(mKinds, sWeightComparator); - return mKinds; - } - - /** - * Find the {@link DataKind} for a specific MIME-type, if it's handled by - * this data source. - */ - public DataKind getKindForMimetype(String mimeType) { - return this.mMimeKinds.get(mimeType); - } - - /** - * Add given {@link DataKind} to list of those provided by this source. - */ - public DataKind addKind(DataKind kind) throws DefinitionException { - if (kind.mimeType == null) { - throw new DefinitionException("null is not a valid mime type"); - } - if (mMimeKinds.get(kind.mimeType) != null) { - throw new DefinitionException( - "mime type '" + kind.mimeType + "' is already registered"); - } - - kind.resourcePackageName = this.resourcePackageName; - this.mKinds.add(kind); - this.mMimeKinds.put(kind.mimeType, kind); - return kind; - } - - /** - * Description of a specific "type" or "label" of a {@link DataKind} row, - * such as {@link Phone#TYPE_WORK}. Includes constraints on total number of - * rows a {@link Contacts} may have of this type, and details on how - * user-defined labels are stored. - */ - public static class EditType { - public int rawValue; - public int labelRes; - public boolean secondary; - /** - * The number of entries allowed for the type. -1 if not specified. - * @see DataKind#typeOverallMax - */ - public int specificMax; - public String customColumn; - - public EditType(int rawValue, int labelRes) { - this.rawValue = rawValue; - this.labelRes = labelRes; - this.specificMax = -1; - } - - public EditType setSecondary(boolean secondary) { - this.secondary = secondary; - return this; - } - - public EditType setSpecificMax(int specificMax) { - this.specificMax = specificMax; - return this; - } - - public EditType setCustomColumn(String customColumn) { - this.customColumn = customColumn; - return this; - } - - @Override - public boolean equals(Object object) { - if (object instanceof EditType) { - final EditType other = (EditType)object; - return other.rawValue == rawValue; - } - return false; - } - - @Override - public int hashCode() { - return rawValue; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() - + " rawValue=" + rawValue - + " labelRes=" + labelRes - + " secondary=" + secondary - + " specificMax=" + specificMax - + " customColumn=" + customColumn; - } - } - - public static class EventEditType extends EditType { - private boolean mYearOptional; - - public EventEditType(int rawValue, int labelRes) { - super(rawValue, labelRes); - } - - public boolean isYearOptional() { - return mYearOptional; - } - - public EventEditType setYearOptional(boolean yearOptional) { - mYearOptional = yearOptional; - return this; - } - - @Override - public String toString() { - return super.toString() + " mYearOptional=" + mYearOptional; - } - } - - /** - * Description of a user-editable field on a {@link DataKind} row, such as - * {@link Phone#NUMBER}. Includes flags to apply to an {@link EditText}, and - * the column where this field is stored. - */ - public static final class EditField { - public String column; - public int titleRes; - public int inputType; - public int minLines; - public boolean optional; - public boolean shortForm; - public boolean longForm; - - public EditField(String column, int titleRes) { - this.column = column; - this.titleRes = titleRes; - } - - public EditField(String column, int titleRes, int inputType) { - this(column, titleRes); - this.inputType = inputType; - } - - public EditField setOptional(boolean optional) { - this.optional = optional; - return this; - } - - public EditField setShortForm(boolean shortForm) { - this.shortForm = shortForm; - return this; - } - - public EditField setLongForm(boolean longForm) { - this.longForm = longForm; - return this; - } - - public EditField setMinLines(int minLines) { - this.minLines = minLines; - return this; - } - - public boolean isMultiLine() { - return (inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) != 0; - } - - - @Override - public String toString() { - return this.getClass().getSimpleName() + ":" - + " column=" + column - + " titleRes=" + titleRes - + " inputType=" + inputType - + " minLines=" + minLines - + " optional=" + optional - + " shortForm=" + shortForm - + " longForm=" + longForm; - } - } - - /** - * Generic method of inflating a given {@link ContentValues} into a user-readable - * {@link CharSequence}. For example, an inflater could combine the multiple - * columns of {@link StructuredPostal} together using a string resource - * before presenting to the user. - */ - public interface StringInflater { - public CharSequence inflateUsing(Context context, ContentValues values); - } - - /** - * Compare two {@link AccountType} by their {@link AccountType#getDisplayLabel} with the - * current locale. - */ - public static class DisplayLabelComparator implements Comparator<AccountType> { - private final Context mContext; - /** {@link Comparator} for the current locale. */ - private final Collator mCollator = Collator.getInstance(); - - public DisplayLabelComparator(Context context) { - mContext = context; - } - - private String getDisplayLabel(AccountType type) { - CharSequence label = type.getDisplayLabel(mContext); - return (label == null) ? "" : label.toString(); - } - - @Override - public int compare(AccountType lhs, AccountType rhs) { - return mCollator.compare(getDisplayLabel(lhs), getDisplayLabel(rhs)); - } - } -} diff --git a/src/com/android/contacts/model/account/AccountTypeWithDataSet.java b/src/com/android/contacts/model/account/AccountTypeWithDataSet.java deleted file mode 100644 index ab0a8913e..000000000 --- a/src/com/android/contacts/model/account/AccountTypeWithDataSet.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.contacts.model.account; - -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.provider.BaseColumns; -import android.provider.ContactsContract; -import android.provider.ContactsContract.RawContacts; -import android.text.TextUtils; - -import com.google.common.base.Objects; - - -/** - * Encapsulates an "account type" string and a "data set" string. - */ -public class AccountTypeWithDataSet { - - private static final String[] ID_PROJECTION = new String[] {BaseColumns._ID}; - private static final Uri RAW_CONTACTS_URI_LIMIT_1 = RawContacts.CONTENT_URI.buildUpon() - .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY, "1").build(); - - /** account type. Can be null for fallback type. */ - public final String accountType; - - /** dataSet may be null, but never be "". */ - public final String dataSet; - - private AccountTypeWithDataSet(String accountType, String dataSet) { - this.accountType = TextUtils.isEmpty(accountType) ? null : accountType; - this.dataSet = TextUtils.isEmpty(dataSet) ? null : dataSet; - } - - public static AccountTypeWithDataSet get(String accountType, String dataSet) { - return new AccountTypeWithDataSet(accountType, dataSet); - } - - /** - * Return true if there are any contacts in the database with this account type and data set. - * Touches DB. Don't use in the UI thread. - */ - public boolean hasData(Context context) { - final String BASE_SELECTION = RawContacts.ACCOUNT_TYPE + " = ?"; - final String selection; - final String[] args; - if (TextUtils.isEmpty(dataSet)) { - selection = BASE_SELECTION + " AND " + RawContacts.DATA_SET + " IS NULL"; - args = new String[] {accountType}; - } else { - selection = BASE_SELECTION + " AND " + RawContacts.DATA_SET + " = ?"; - args = new String[] {accountType, dataSet}; - } - - final Cursor c = context.getContentResolver().query(RAW_CONTACTS_URI_LIMIT_1, - ID_PROJECTION, selection, args, null); - if (c == null) return false; - try { - return c.moveToFirst(); - } finally { - c.close(); - } - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof AccountTypeWithDataSet)) return false; - - AccountTypeWithDataSet other = (AccountTypeWithDataSet) o; - return Objects.equal(accountType, other.accountType) - && Objects.equal(dataSet, other.dataSet); - } - - @Override - public int hashCode() { - return (accountType == null ? 0 : accountType.hashCode()) - ^ (dataSet == null ? 0 : dataSet.hashCode()); - } - - @Override - public String toString() { - return "[" + accountType + "/" + dataSet + "]"; - } -} diff --git a/src/com/android/contacts/model/account/AccountWithDataSet.java b/src/com/android/contacts/model/account/AccountWithDataSet.java deleted file mode 100644 index 03fcc02f4..000000000 --- a/src/com/android/contacts/model/account/AccountWithDataSet.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.contacts.model.account; - -import android.accounts.Account; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.Parcel; -import android.provider.BaseColumns; -import android.provider.ContactsContract; -import android.provider.ContactsContract.RawContacts; -import android.text.TextUtils; - -import com.android.internal.util.Objects; -import com.google.common.collect.Lists; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - -/** - * Wrapper for an account that includes a data set (which may be null). - */ -public class AccountWithDataSet extends Account { - private static final String STRINGIFY_SEPARATOR = "\u0001"; - private static final String ARRAY_STRINGIFY_SEPARATOR = "\u0002"; - - private static final Pattern STRINGIFY_SEPARATOR_PAT = - Pattern.compile(Pattern.quote(STRINGIFY_SEPARATOR)); - private static final Pattern ARRAY_STRINGIFY_SEPARATOR_PAT = - Pattern.compile(Pattern.quote(ARRAY_STRINGIFY_SEPARATOR)); - - public final String dataSet; - private final AccountTypeWithDataSet mAccountTypeWithDataSet; - - private static final String[] ID_PROJECTION = new String[] {BaseColumns._ID}; - private static final Uri RAW_CONTACTS_URI_LIMIT_1 = RawContacts.CONTENT_URI.buildUpon() - .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY, "1").build(); - - - public AccountWithDataSet(String name, String type, String dataSet) { - super(name, type); - this.dataSet = dataSet; - mAccountTypeWithDataSet = AccountTypeWithDataSet.get(type, dataSet); - } - - public AccountWithDataSet(Parcel in) { - super(in); - this.dataSet = in.readString(); - mAccountTypeWithDataSet = AccountTypeWithDataSet.get(type, dataSet); - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeString(dataSet); - } - - // For Parcelable - public static final Creator<AccountWithDataSet> CREATOR = new Creator<AccountWithDataSet>() { - public AccountWithDataSet createFromParcel(Parcel source) { - return new AccountWithDataSet(source); - } - - public AccountWithDataSet[] newArray(int size) { - return new AccountWithDataSet[size]; - } - }; - - public AccountTypeWithDataSet getAccountTypeWithDataSet() { - return mAccountTypeWithDataSet; - } - - /** - * Return {@code true} if this account has any contacts in the database. - * Touches DB. Don't use in the UI thread. - */ - public boolean hasData(Context context) { - final String BASE_SELECTION = - RawContacts.ACCOUNT_TYPE + " = ?" + " AND " + RawContacts.ACCOUNT_NAME + " = ?"; - final String selection; - final String[] args; - if (TextUtils.isEmpty(dataSet)) { - selection = BASE_SELECTION + " AND " + RawContacts.DATA_SET + " IS NULL"; - args = new String[] {type, name}; - } else { - selection = BASE_SELECTION + " AND " + RawContacts.DATA_SET + " = ?"; - args = new String[] {type, name, dataSet}; - } - - final Cursor c = context.getContentResolver().query(RAW_CONTACTS_URI_LIMIT_1, - ID_PROJECTION, selection, args, null); - if (c == null) return false; - try { - return c.moveToFirst(); - } finally { - c.close(); - } - } - - @Override - public boolean equals(Object o) { - return (o instanceof AccountWithDataSet) && super.equals(o) - && Objects.equal(((AccountWithDataSet) o).dataSet, dataSet); - } - - @Override - public int hashCode() { - return 31 * super.hashCode() - + (dataSet == null ? 0 : dataSet.hashCode()); - } - - @Override - public String toString() { - return "AccountWithDataSet {name=" + name + ", type=" + type + ", dataSet=" + dataSet + "}"; - } - - private static StringBuilder addStringified(StringBuilder sb, AccountWithDataSet account) { - sb.append(account.name); - sb.append(STRINGIFY_SEPARATOR); - sb.append(account.type); - sb.append(STRINGIFY_SEPARATOR); - if (!TextUtils.isEmpty(account.dataSet)) sb.append(account.dataSet); - - return sb; - } - - /** - * Pack the instance into a string. - */ - public String stringify() { - return addStringified(new StringBuilder(), this).toString(); - } - - /** - * Unpack a string created by {@link #stringify}. - * - * @throws IllegalArgumentException if it's an invalid string. - */ - public static AccountWithDataSet unstringify(String s) { - final String[] array = STRINGIFY_SEPARATOR_PAT.split(s, 3); - if (array.length < 3) { - throw new IllegalArgumentException("Invalid string " + s); - } - return new AccountWithDataSet(array[0], array[1], - TextUtils.isEmpty(array[2]) ? null : array[2]); - } - - /** - * Pack a list of {@link AccountWithDataSet} into a string. - */ - public static String stringifyList(List<AccountWithDataSet> accounts) { - final StringBuilder sb = new StringBuilder(); - - for (AccountWithDataSet account : accounts) { - if (sb.length() > 0) { - sb.append(ARRAY_STRINGIFY_SEPARATOR); - } - addStringified(sb, account); - } - - return sb.toString(); - } - - /** - * Unpack a list of {@link AccountWithDataSet} into a string. - * - * @throws IllegalArgumentException if it's an invalid string. - */ - public static List<AccountWithDataSet> unstringifyList(String s) { - final ArrayList<AccountWithDataSet> ret = Lists.newArrayList(); - if (TextUtils.isEmpty(s)) { - return ret; - } - - final String[] array = ARRAY_STRINGIFY_SEPARATOR_PAT.split(s); - - for (int i = 0; i < array.length; i++) { - ret.add(unstringify(array[i])); - } - - return ret; - } -} diff --git a/src/com/android/contacts/model/account/BaseAccountType.java b/src/com/android/contacts/model/account/BaseAccountType.java deleted file mode 100644 index 6b4d6234f..000000000 --- a/src/com/android/contacts/model/account/BaseAccountType.java +++ /dev/null @@ -1,1482 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.contacts.model.account; - -import android.content.ContentValues; -import android.content.Context; -import android.content.res.Resources; -import android.provider.ContactsContract.CommonDataKinds.BaseTypes; -import android.provider.ContactsContract.CommonDataKinds.Email; -import android.provider.ContactsContract.CommonDataKinds.Event; -import android.provider.ContactsContract.CommonDataKinds.GroupMembership; -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.Relation; -import android.provider.ContactsContract.CommonDataKinds.SipAddress; -import android.provider.ContactsContract.CommonDataKinds.StructuredName; -import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; -import android.provider.ContactsContract.CommonDataKinds.Website; -import android.util.AttributeSet; -import android.util.Log; -import android.view.inputmethod.EditorInfo; - -import com.android.contacts.R; -import com.android.contacts.common.util.ContactDisplayUtils; -import com.android.contacts.model.dataitem.DataKind; -import com.android.contacts.test.NeededForTesting; -import com.android.contacts.util.DateUtils; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -public abstract class BaseAccountType extends AccountType { - private static final String TAG = "BaseAccountType"; - - protected static final int FLAGS_PHONE = EditorInfo.TYPE_CLASS_PHONE; - protected static final int FLAGS_EMAIL = EditorInfo.TYPE_CLASS_TEXT - | EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; - protected static final int FLAGS_PERSON_NAME = EditorInfo.TYPE_CLASS_TEXT - | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS | EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME; - protected static final int FLAGS_PHONETIC = EditorInfo.TYPE_CLASS_TEXT - | EditorInfo.TYPE_TEXT_VARIATION_PHONETIC; - protected static final int FLAGS_GENERIC_NAME = EditorInfo.TYPE_CLASS_TEXT - | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS; - protected static final int FLAGS_NOTE = EditorInfo.TYPE_CLASS_TEXT - | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE; - protected static final int FLAGS_EVENT = EditorInfo.TYPE_CLASS_TEXT; - protected static final int FLAGS_WEBSITE = EditorInfo.TYPE_CLASS_TEXT - | EditorInfo.TYPE_TEXT_VARIATION_URI; - protected static final int FLAGS_POSTAL = EditorInfo.TYPE_CLASS_TEXT - | EditorInfo.TYPE_TEXT_VARIATION_POSTAL_ADDRESS | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS - | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE; - protected static final int FLAGS_SIP_ADDRESS = EditorInfo.TYPE_CLASS_TEXT - | EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; // since SIP addresses have the same - // basic format as email addresses - protected static final int FLAGS_RELATION = EditorInfo.TYPE_CLASS_TEXT - | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS | EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME; - - // Specify the maximum number of lines that can be used to display various field types. If no - // value is specified for a particular type, we use the default value from {@link DataKind}. - protected static final int MAX_LINES_FOR_POSTAL_ADDRESS = 10; - protected static final int MAX_LINES_FOR_GROUP = 10; - protected static final int MAX_LINES_FOR_NOTE = 100; - - private interface Tag { - static final String DATA_KIND = "DataKind"; - static final String TYPE = "Type"; - } - - private interface Attr { - static final String MAX_OCCURRENCE = "maxOccurs"; - static final String DATE_WITH_TIME = "dateWithTime"; - static final String YEAR_OPTIONAL = "yearOptional"; - static final String KIND = "kind"; - static final String TYPE = "type"; - } - - private interface Weight { - static final int NONE = -1; - static final int ORGANIZATION = 5; - static final int PHONE = 10; - static final int EMAIL = 15; - static final int IM = 20; - static final int STRUCTURED_POSTAL = 25; - static final int NOTE = 110; - static final int NICKNAME = 115; - static final int WEBSITE = 120; - static final int SIP_ADDRESS = 130; - static final int EVENT = 150; - static final int RELATIONSHIP = 160; - static final int GROUP_MEMBERSHIP = 999; - } - - public BaseAccountType() { - this.accountType = null; - this.dataSet = null; - this.titleRes = R.string.account_phone; - this.iconRes = R.mipmap.ic_launcher_contacts; - } - - protected static EditType buildPhoneType(int type) { - return new EditType(type, Phone.getTypeLabelResource(type)); - } - - protected static EditType buildEmailType(int type) { - return new EditType(type, Email.getTypeLabelResource(type)); - } - - protected static EditType buildPostalType(int type) { - return new EditType(type, StructuredPostal.getTypeLabelResource(type)); - } - - protected static EditType buildImType(int type) { - return new EditType(type, Im.getProtocolLabelResource(type)); - } - - protected static EditType buildEventType(int type, boolean yearOptional) { - return new EventEditType(type, Event.getTypeResource(type)).setYearOptional(yearOptional); - } - - protected static EditType buildRelationType(int type) { - return new EditType(type, Relation.getTypeLabelResource(type)); - } - - protected DataKind addDataKindStructuredName(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(StructuredName.CONTENT_ITEM_TYPE, - R.string.nameLabelsGroup, -1, true, R.layout.structured_name_editor_view)); - kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup); - kind.actionBody = new SimpleInflater(Nickname.NAME); - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(StructuredName.DISPLAY_NAME, - R.string.full_name, FLAGS_PERSON_NAME)); - kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME, - R.string.name_phonetic_family, FLAGS_PHONETIC)); - kind.fieldList.add(new EditField(StructuredName.PHONETIC_MIDDLE_NAME, - R.string.name_phonetic_middle, FLAGS_PHONETIC)); - kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME, - R.string.name_phonetic_given, FLAGS_PHONETIC)); - - return kind; - } - - protected DataKind addDataKindDisplayName(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME, - R.string.nameLabelsGroup, -1, true, R.layout.text_fields_editor_view)); - kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup); - kind.actionBody = new SimpleInflater(Nickname.NAME); - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(StructuredName.DISPLAY_NAME, - R.string.full_name, FLAGS_PERSON_NAME).setShortForm(true)); - - boolean displayOrderPrimary = - context.getResources().getBoolean(R.bool.config_editor_field_order_primary); - - if (!displayOrderPrimary) { - kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix, - FLAGS_PERSON_NAME).setLongForm(true)); - } else { - kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family, - FLAGS_PERSON_NAME).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix, - FLAGS_PERSON_NAME).setLongForm(true)); - } - - return kind; - } - - protected DataKind addDataKindPhoneticName(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME, - R.string.name_phonetic, -1, true, R.layout.phonetic_name_editor_view)); - kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup); - kind.actionBody = new SimpleInflater(Nickname.NAME); - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(DataKind.PSEUDO_COLUMN_PHONETIC_NAME, - R.string.name_phonetic, FLAGS_PHONETIC).setShortForm(true)); - kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME, - R.string.name_phonetic_family, FLAGS_PHONETIC).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.PHONETIC_MIDDLE_NAME, - R.string.name_phonetic_middle, FLAGS_PHONETIC).setLongForm(true)); - kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME, - R.string.name_phonetic_given, FLAGS_PHONETIC).setLongForm(true)); - - return kind; - } - - protected DataKind addDataKindNickname(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(Nickname.CONTENT_ITEM_TYPE, - R.string.nicknameLabelsGroup, 115, true, R.layout.text_fields_editor_view)); - kind.typeOverallMax = 1; - kind.actionHeader = new SimpleInflater(R.string.nicknameLabelsGroup); - kind.actionBody = new SimpleInflater(Nickname.NAME); - kind.defaultValues = new ContentValues(); - kind.defaultValues.put(Nickname.TYPE, Nickname.TYPE_DEFAULT); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Nickname.NAME, R.string.nicknameLabelsGroup, - FLAGS_PERSON_NAME)); - - return kind; - } - - protected DataKind addDataKindPhone(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(Phone.CONTENT_ITEM_TYPE, R.string.phoneLabelsGroup, - 10, true, R.layout.text_fields_editor_view)); - kind.iconAltRes = R.drawable.ic_text_holo_light; - kind.iconAltDescriptionRes = R.string.sms; - kind.actionHeader = new PhoneActionInflater(); - kind.actionAltHeader = new PhoneActionAltInflater(); - kind.actionBody = new SimpleInflater(Phone.NUMBER); - kind.typeColumn = Phone.TYPE; - kind.typeList = Lists.newArrayList(); - kind.typeList.add(buildPhoneType(Phone.TYPE_MOBILE)); - kind.typeList.add(buildPhoneType(Phone.TYPE_HOME)); - kind.typeList.add(buildPhoneType(Phone.TYPE_WORK)); - kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_WORK).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_HOME).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_PAGER).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_OTHER)); - kind.typeList.add( - buildPhoneType(Phone.TYPE_CUSTOM).setSecondary(true).setCustomColumn(Phone.LABEL)); - kind.typeList.add(buildPhoneType(Phone.TYPE_CALLBACK).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_CAR).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_COMPANY_MAIN).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_ISDN).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_MAIN).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_OTHER_FAX).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_RADIO).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_TELEX).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_TTY_TDD).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_WORK_MOBILE).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_WORK_PAGER).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_ASSISTANT).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_MMS).setSecondary(true)); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Phone.NUMBER, R.string.phoneLabelsGroup, FLAGS_PHONE)); - - return kind; - } - - protected DataKind addDataKindEmail(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(Email.CONTENT_ITEM_TYPE, R.string.emailLabelsGroup, - 15, true, R.layout.text_fields_editor_view)); - kind.actionHeader = new EmailActionInflater(); - kind.actionBody = new SimpleInflater(Email.DATA); - kind.typeColumn = Email.TYPE; - kind.typeList = Lists.newArrayList(); - kind.typeList.add(buildEmailType(Email.TYPE_HOME)); - kind.typeList.add(buildEmailType(Email.TYPE_WORK)); - kind.typeList.add(buildEmailType(Email.TYPE_OTHER)); - kind.typeList.add(buildEmailType(Email.TYPE_MOBILE)); - kind.typeList.add( - buildEmailType(Email.TYPE_CUSTOM).setSecondary(true).setCustomColumn(Email.LABEL)); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Email.DATA, R.string.emailLabelsGroup, FLAGS_EMAIL)); - - return kind; - } - - protected DataKind addDataKindStructuredPostal(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(StructuredPostal.CONTENT_ITEM_TYPE, - R.string.postalLabelsGroup, 25, true, R.layout.text_fields_editor_view)); - kind.actionHeader = new PostalActionInflater(); - kind.actionBody = new SimpleInflater(StructuredPostal.FORMATTED_ADDRESS); - kind.typeColumn = StructuredPostal.TYPE; - kind.typeList = Lists.newArrayList(); - kind.typeList.add(buildPostalType(StructuredPostal.TYPE_HOME)); - kind.typeList.add(buildPostalType(StructuredPostal.TYPE_WORK)); - kind.typeList.add(buildPostalType(StructuredPostal.TYPE_OTHER)); - kind.typeList.add(buildPostalType(StructuredPostal.TYPE_CUSTOM).setSecondary(true) - .setCustomColumn(StructuredPostal.LABEL)); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add( - new EditField(StructuredPostal.FORMATTED_ADDRESS, R.string.postal_address, - FLAGS_POSTAL)); - - kind.maxLinesForDisplay = MAX_LINES_FOR_POSTAL_ADDRESS; - - return kind; - } - - protected DataKind addDataKindIm(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(Im.CONTENT_ITEM_TYPE, R.string.imLabelsGroup, 20, true, - R.layout.text_fields_editor_view)); - kind.actionHeader = new ImActionInflater(); - kind.actionBody = new SimpleInflater(Im.DATA); - - // NOTE: even though a traditional "type" exists, for editing - // purposes we're using the protocol to pick labels - - kind.defaultValues = new ContentValues(); - kind.defaultValues.put(Im.TYPE, Im.TYPE_OTHER); - - kind.typeColumn = Im.PROTOCOL; - kind.typeList = Lists.newArrayList(); - kind.typeList.add(buildImType(Im.PROTOCOL_AIM)); - kind.typeList.add(buildImType(Im.PROTOCOL_MSN)); - kind.typeList.add(buildImType(Im.PROTOCOL_YAHOO)); - kind.typeList.add(buildImType(Im.PROTOCOL_SKYPE)); - kind.typeList.add(buildImType(Im.PROTOCOL_QQ)); - kind.typeList.add(buildImType(Im.PROTOCOL_GOOGLE_TALK)); - kind.typeList.add(buildImType(Im.PROTOCOL_ICQ)); - kind.typeList.add(buildImType(Im.PROTOCOL_JABBER)); - kind.typeList.add(buildImType(Im.PROTOCOL_CUSTOM).setSecondary(true).setCustomColumn( - Im.CUSTOM_PROTOCOL)); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Im.DATA, R.string.imLabelsGroup, FLAGS_EMAIL)); - - return kind; - } - - protected DataKind addDataKindOrganization(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(Organization.CONTENT_ITEM_TYPE, - R.string.organizationLabelsGroup, 5, true, - R.layout.text_fields_editor_view)); - kind.actionHeader = new SimpleInflater(Organization.COMPANY); - kind.actionBody = new SimpleInflater(Organization.TITLE); - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Organization.COMPANY, R.string.ghostData_company, - FLAGS_GENERIC_NAME)); - kind.fieldList.add(new EditField(Organization.TITLE, R.string.ghostData_title, - FLAGS_GENERIC_NAME)); - - return kind; - } - - protected DataKind addDataKindPhoto(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(Photo.CONTENT_ITEM_TYPE, -1, -1, true, -1)); - kind.typeOverallMax = 1; - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Photo.PHOTO, -1, -1)); - return kind; - } - - protected DataKind addDataKindNote(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(Note.CONTENT_ITEM_TYPE, - R.string.label_notes, 110, true, R.layout.text_fields_editor_view)); - kind.typeOverallMax = 1; - kind.actionHeader = new SimpleInflater(R.string.label_notes); - kind.actionBody = new SimpleInflater(Note.NOTE); - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Note.NOTE, R.string.label_notes, FLAGS_NOTE)); - - kind.maxLinesForDisplay = MAX_LINES_FOR_NOTE; - - return kind; - } - - protected DataKind addDataKindWebsite(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(Website.CONTENT_ITEM_TYPE, - R.string.websiteLabelsGroup, 120, true, R.layout.text_fields_editor_view)); - kind.actionHeader = new SimpleInflater(R.string.websiteLabelsGroup); - kind.actionBody = new SimpleInflater(Website.URL); - kind.defaultValues = new ContentValues(); - kind.defaultValues.put(Website.TYPE, Website.TYPE_OTHER); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Website.URL, R.string.websiteLabelsGroup, FLAGS_WEBSITE)); - - return kind; - } - - protected DataKind addDataKindSipAddress(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(SipAddress.CONTENT_ITEM_TYPE, - R.string.label_sip_address, 130, true, R.layout.text_fields_editor_view)); - - kind.typeOverallMax = 1; - kind.actionHeader = new SimpleInflater(R.string.label_sip_address); - kind.actionBody = new SimpleInflater(SipAddress.SIP_ADDRESS); - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(SipAddress.SIP_ADDRESS, - R.string.label_sip_address, FLAGS_SIP_ADDRESS)); - - return kind; - } - - protected DataKind addDataKindGroupMembership(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(GroupMembership.CONTENT_ITEM_TYPE, - R.string.groupsLabel, 999, true, -1)); - - kind.typeOverallMax = 1; - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(GroupMembership.GROUP_ROW_ID, -1, -1)); - - kind.maxLinesForDisplay = MAX_LINES_FOR_GROUP; - - return kind; - } - - /** - * Simple inflater that assumes a string resource has a "%s" that will be - * filled from the given column. - */ - public static class SimpleInflater implements StringInflater { - private final int mStringRes; - private final String mColumnName; - - public SimpleInflater(int stringRes) { - this(stringRes, null); - } - - public SimpleInflater(String columnName) { - this(-1, columnName); - } - - public SimpleInflater(int stringRes, String columnName) { - mStringRes = stringRes; - mColumnName = columnName; - } - - @Override - public CharSequence inflateUsing(Context context, ContentValues values) { - final boolean validColumn = values.containsKey(mColumnName); - final boolean validString = mStringRes > 0; - - final CharSequence stringValue = validString ? context.getText(mStringRes) : null; - final CharSequence columnValue = validColumn ? values.getAsString(mColumnName) : null; - - if (validString && validColumn) { - return String.format(stringValue.toString(), columnValue); - } else if (validString) { - return stringValue; - } else if (validColumn) { - return columnValue; - } else { - return null; - } - } - - @Override - public String toString() { - return this.getClass().getSimpleName() - + " mStringRes=" + mStringRes - + " mColumnName" + mColumnName; - } - - @NeededForTesting - public String getColumnNameForTest() { - return mColumnName; - } - } - - public static abstract class CommonInflater implements StringInflater { - protected abstract int getTypeLabelResource(Integer type); - - protected boolean isCustom(Integer type) { - return type == BaseTypes.TYPE_CUSTOM; - } - - protected String getTypeColumn() { - return Phone.TYPE; - } - - protected String getLabelColumn() { - return Phone.LABEL; - } - - protected CharSequence getTypeLabel(Resources res, Integer type, CharSequence label) { - final int labelRes = getTypeLabelResource(type); - if (type == null) { - return res.getText(labelRes); - } else if (isCustom(type)) { - return res.getString(labelRes, label == null ? "" : label); - } else { - return res.getText(labelRes); - } - } - - @Override - public CharSequence inflateUsing(Context context, ContentValues values) { - final Integer type = values.getAsInteger(getTypeColumn()); - final String label = values.getAsString(getLabelColumn()); - return getTypeLabel(context.getResources(), type, label); - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - } - - public static class PhoneActionInflater extends CommonInflater { - @Override - protected boolean isCustom(Integer type) { - return ContactDisplayUtils.isCustomPhoneType(type); - } - - @Override - protected int getTypeLabelResource(Integer type) { - return ContactDisplayUtils.getPhoneLabelResourceId(type); - } - } - - public static class PhoneActionAltInflater extends CommonInflater { - @Override - protected boolean isCustom(Integer type) { - return ContactDisplayUtils.isCustomPhoneType(type); - } - - @Override - protected int getTypeLabelResource(Integer type) { - return ContactDisplayUtils.getSmsLabelResourceId(type); - } - } - - public static class EmailActionInflater extends CommonInflater { - @Override - protected int getTypeLabelResource(Integer type) { - if (type == null) return R.string.email; - switch (type) { - case Email.TYPE_HOME: return R.string.email_home; - case Email.TYPE_WORK: return R.string.email_work; - case Email.TYPE_OTHER: return R.string.email_other; - case Email.TYPE_MOBILE: return R.string.email_mobile; - default: return R.string.email_custom; - } - } - } - - public static class EventActionInflater extends CommonInflater { - @Override - protected int getTypeLabelResource(Integer type) { - return Event.getTypeResource(type); - } - } - - public static class RelationActionInflater extends CommonInflater { - @Override - protected int getTypeLabelResource(Integer type) { - return Relation.getTypeLabelResource(type == null ? Relation.TYPE_CUSTOM : type); - } - } - - public static class PostalActionInflater extends CommonInflater { - @Override - protected int getTypeLabelResource(Integer type) { - if (type == null) return R.string.map_other; - switch (type) { - case StructuredPostal.TYPE_HOME: return R.string.map_home; - case StructuredPostal.TYPE_WORK: return R.string.map_work; - case StructuredPostal.TYPE_OTHER: return R.string.map_other; - default: return R.string.map_custom; - } - } - } - - public static class ImActionInflater extends CommonInflater { - @Override - protected String getTypeColumn() { - return Im.PROTOCOL; - } - - @Override - protected String getLabelColumn() { - return Im.CUSTOM_PROTOCOL; - } - - @Override - protected int getTypeLabelResource(Integer type) { - if (type == null) return R.string.chat; - switch (type) { - case Im.PROTOCOL_AIM: return R.string.chat_aim; - case Im.PROTOCOL_MSN: return R.string.chat_msn; - case Im.PROTOCOL_YAHOO: return R.string.chat_yahoo; - case Im.PROTOCOL_SKYPE: return R.string.chat_skype; - case Im.PROTOCOL_QQ: return R.string.chat_qq; - case Im.PROTOCOL_GOOGLE_TALK: return R.string.chat_gtalk; - case Im.PROTOCOL_ICQ: return R.string.chat_icq; - case Im.PROTOCOL_JABBER: return R.string.chat_jabber; - case Im.PROTOCOL_NETMEETING: return R.string.chat; - default: return R.string.chat; - } - } - } - - @Override - public boolean isGroupMembershipEditable() { - return false; - } - - /** - * Parses the content of the EditSchema tag in contacts.xml. - */ - protected final void parseEditSchema(Context context, XmlPullParser parser, AttributeSet attrs) - throws XmlPullParserException, IOException, DefinitionException { - - final int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - final int depth = parser.getDepth(); - if (type != XmlPullParser.START_TAG || depth != outerDepth + 1) { - continue; // Not direct child tag - } - - final String tag = parser.getName(); - - if (Tag.DATA_KIND.equals(tag)) { - for (DataKind kind : KindParser.INSTANCE.parseDataKindTag(context, parser, attrs)) { - addKind(kind); - } - } else { - Log.w(TAG, "Skipping unknown tag " + tag); - } - } - } - - // Utility methods to keep code shorter. - private static boolean getAttr(AttributeSet attrs, String attribute, boolean defaultValue) { - return attrs.getAttributeBooleanValue(null, attribute, defaultValue); - } - - private static int getAttr(AttributeSet attrs, String attribute, int defaultValue) { - return attrs.getAttributeIntValue(null, attribute, defaultValue); - } - - private static String getAttr(AttributeSet attrs, String attribute) { - return attrs.getAttributeValue(null, attribute); - } - - // TODO Extract it to its own class, and move all KindBuilders to it as well. - private static class KindParser { - public static final KindParser INSTANCE = new KindParser(); - - private final Map<String, KindBuilder> mBuilders = Maps.newHashMap(); - - private KindParser() { - addBuilder(new NameKindBuilder()); - addBuilder(new NicknameKindBuilder()); - addBuilder(new PhoneKindBuilder()); - addBuilder(new EmailKindBuilder()); - addBuilder(new StructuredPostalKindBuilder()); - addBuilder(new ImKindBuilder()); - addBuilder(new OrganizationKindBuilder()); - addBuilder(new PhotoKindBuilder()); - addBuilder(new NoteKindBuilder()); - addBuilder(new WebsiteKindBuilder()); - addBuilder(new SipAddressKindBuilder()); - addBuilder(new GroupMembershipKindBuilder()); - addBuilder(new EventKindBuilder()); - addBuilder(new RelationshipKindBuilder()); - } - - private void addBuilder(KindBuilder builder) { - mBuilders.put(builder.getTagName(), builder); - } - - /** - * Takes a {@link XmlPullParser} at the start of a DataKind tag, parses it and returns - * {@link DataKind}s. (Usually just one, but there are three for the "name" kind.) - * - * This method returns a list, because we need to add 3 kinds for the name data kind. - * (structured, display and phonetic) - */ - public List<DataKind> parseDataKindTag(Context context, XmlPullParser parser, - AttributeSet attrs) - throws DefinitionException, XmlPullParserException, IOException { - final String kind = getAttr(attrs, Attr.KIND); - final KindBuilder builder = mBuilders.get(kind); - if (builder != null) { - return builder.parseDataKind(context, parser, attrs); - } else { - throw new DefinitionException("Undefined data kind '" + kind + "'"); - } - } - } - - private static abstract class KindBuilder { - - public abstract String getTagName(); - - /** - * DataKind tag parser specific to each kind. Subclasses must implement it. - */ - public abstract List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, IOException; - - /** - * Creates a new {@link DataKind}, and also parses the child Type tags in the DataKind - * tag. - */ - protected final DataKind newDataKind(Context context, XmlPullParser parser, - AttributeSet attrs, boolean isPseudo, String mimeType, String typeColumn, - int titleRes, int weight, int editorLayoutResourceId, - StringInflater actionHeader, StringInflater actionBody) - throws DefinitionException, XmlPullParserException, IOException { - - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Adding DataKind: " + mimeType); - } - - final DataKind kind = new DataKind(mimeType, titleRes, weight, true, - editorLayoutResourceId); - kind.typeColumn = typeColumn; - kind.actionHeader = actionHeader; - kind.actionBody = actionBody; - kind.fieldList = Lists.newArrayList(); - - // Get more information from the tag... - // A pseudo data kind doesn't have corresponding tag the XML, so we skip this. - if (!isPseudo) { - kind.typeOverallMax = getAttr(attrs, Attr.MAX_OCCURRENCE, -1); - - // Process "Type" tags. - // If a kind has the type column, contacts.xml must have at least one type - // definition. Otherwise, it mustn't have a type definition. - if (kind.typeColumn != null) { - // Parse and add types. - kind.typeList = Lists.newArrayList(); - parseTypes(context, parser, attrs, kind, true); - if (kind.typeList.size() == 0) { - throw new DefinitionException( - "Kind " + kind.mimeType + " must have at least one type"); - } - } else { - // Make sure it has no types. - parseTypes(context, parser, attrs, kind, false /* can't have types */); - } - } - - return kind; - } - - /** - * Parses Type elements in a DataKind element, and if {@code canHaveTypes} is true adds - * them to the given {@link DataKind}. Otherwise the {@link DataKind} can't have a type, - * so throws {@link DefinitionException}. - */ - private void parseTypes(Context context, XmlPullParser parser, AttributeSet attrs, - DataKind kind, boolean canHaveTypes) - throws DefinitionException, XmlPullParserException, IOException { - final int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - final int depth = parser.getDepth(); - if (type != XmlPullParser.START_TAG || depth != outerDepth + 1) { - continue; // Not direct child tag - } - - final String tag = parser.getName(); - if (Tag.TYPE.equals(tag)) { - if (canHaveTypes) { - kind.typeList.add(parseTypeTag(parser, attrs, kind)); - } else { - throw new DefinitionException( - "Kind " + kind.mimeType + " can't have types"); - } - } else { - throw new DefinitionException("Unknown tag: " + tag); - } - } - } - - /** - * Parses a single Type element and returns an {@link EditType} built from it. Uses - * {@link #buildEditTypeForTypeTag} defined in subclasses to actually build an - * {@link EditType}. - */ - private EditType parseTypeTag(XmlPullParser parser, AttributeSet attrs, DataKind kind) - throws DefinitionException { - - final String typeName = getAttr(attrs, Attr.TYPE); - - final EditType et = buildEditTypeForTypeTag(attrs, typeName); - if (et == null) { - throw new DefinitionException( - "Undefined type '" + typeName + "' for data kind '" + kind.mimeType + "'"); - } - et.specificMax = getAttr(attrs, Attr.MAX_OCCURRENCE, -1); - - return et; - } - - /** - * Returns an {@link EditType} for the given "type". Subclasses may optionally use - * the attributes in the tag to set optional values. - * (e.g. "yearOptional" for the event kind) - */ - protected EditType buildEditTypeForTypeTag(AttributeSet attrs, String type) { - return null; - } - - protected final void throwIfList(DataKind kind) throws DefinitionException { - if (kind.typeOverallMax != 1) { - throw new DefinitionException( - "Kind " + kind.mimeType + " must have 'overallMax=\"1\"'"); - } - } - } - - /** - * DataKind parser for Name. (structured, display, phonetic) - */ - private static class NameKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "name"; - } - - private static void checkAttributeTrue(boolean value, String attrName) - throws DefinitionException { - if (!value) { - throw new DefinitionException(attrName + " must be true"); - } - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - - // Build 3 data kinds: - // - StructuredName.CONTENT_ITEM_TYPE - // - DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME - // - DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME - - final boolean displayOrderPrimary = - context.getResources().getBoolean(R.bool.config_editor_field_order_primary); - - final boolean supportsDisplayName = getAttr(attrs, "supportsDisplayName", false); - final boolean supportsPrefix = getAttr(attrs, "supportsPrefix", false); - final boolean supportsMiddleName = getAttr(attrs, "supportsMiddleName", false); - final boolean supportsSuffix = getAttr(attrs, "supportsSuffix", false); - final boolean supportsPhoneticFamilyName = - getAttr(attrs, "supportsPhoneticFamilyName", false); - final boolean supportsPhoneticMiddleName = - getAttr(attrs, "supportsPhoneticMiddleName", false); - final boolean supportsPhoneticGivenName = - getAttr(attrs, "supportsPhoneticGivenName", false); - - // For now, every things must be supported. - checkAttributeTrue(supportsDisplayName, "supportsDisplayName"); - checkAttributeTrue(supportsPrefix, "supportsPrefix"); - checkAttributeTrue(supportsMiddleName, "supportsMiddleName"); - checkAttributeTrue(supportsSuffix, "supportsSuffix"); - checkAttributeTrue(supportsPhoneticFamilyName, "supportsPhoneticFamilyName"); - checkAttributeTrue(supportsPhoneticMiddleName, "supportsPhoneticMiddleName"); - checkAttributeTrue(supportsPhoneticGivenName, "supportsPhoneticGivenName"); - - final List<DataKind> kinds = Lists.newArrayList(); - - // Structured name - final DataKind ks = newDataKind(context, parser, attrs, false, - StructuredName.CONTENT_ITEM_TYPE, null, R.string.nameLabelsGroup, Weight.NONE, - R.layout.structured_name_editor_view, - new SimpleInflater(R.string.nameLabelsGroup), - new SimpleInflater(Nickname.NAME)); - - throwIfList(ks); - kinds.add(ks); - - // Note about setLongForm/setShortForm below. - // We need to set this only when the type supports display name. (=supportsDisplayName) - // Otherwise (i.e. Exchange) we don't set these flags, but instead make some fields - // "optional". - - ks.fieldList.add(new EditField(StructuredName.DISPLAY_NAME, R.string.full_name, - FLAGS_PERSON_NAME)); - ks.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix, - FLAGS_PERSON_NAME).setLongForm(true)); - ks.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family, - FLAGS_PERSON_NAME).setLongForm(true)); - ks.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle, - FLAGS_PERSON_NAME).setLongForm(true)); - ks.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given, - FLAGS_PERSON_NAME).setLongForm(true)); - ks.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix, - FLAGS_PERSON_NAME).setLongForm(true)); - ks.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME, - R.string.name_phonetic_family, FLAGS_PHONETIC)); - ks.fieldList.add(new EditField(StructuredName.PHONETIC_MIDDLE_NAME, - R.string.name_phonetic_middle, FLAGS_PHONETIC)); - ks.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME, - R.string.name_phonetic_given, FLAGS_PHONETIC)); - - // Display name - final DataKind kd = newDataKind(context, parser, attrs, true, - DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME, null, - R.string.nameLabelsGroup, Weight.NONE, R.layout.text_fields_editor_view, - new SimpleInflater(R.string.nameLabelsGroup), - new SimpleInflater(Nickname.NAME)); - kd.typeOverallMax = 1; - kinds.add(kd); - - kd.fieldList.add(new EditField(StructuredName.DISPLAY_NAME, - R.string.full_name, FLAGS_PERSON_NAME).setShortForm(true)); - - if (!displayOrderPrimary) { - kd.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix, - FLAGS_PERSON_NAME).setLongForm(true)); - kd.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family, - FLAGS_PERSON_NAME).setLongForm(true)); - kd.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle, - FLAGS_PERSON_NAME).setLongForm(true)); - kd.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given, - FLAGS_PERSON_NAME).setLongForm(true)); - kd.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix, - FLAGS_PERSON_NAME).setLongForm(true)); - } else { - kd.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix, - FLAGS_PERSON_NAME).setLongForm(true)); - kd.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given, - FLAGS_PERSON_NAME).setLongForm(true)); - kd.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle, - FLAGS_PERSON_NAME).setLongForm(true)); - kd.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family, - FLAGS_PERSON_NAME).setLongForm(true)); - kd.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix, - FLAGS_PERSON_NAME).setLongForm(true)); - } - - // Phonetic name - final DataKind kp = newDataKind(context, parser, attrs, true, - DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME, null, - R.string.name_phonetic, Weight.NONE, R.layout.phonetic_name_editor_view, - new SimpleInflater(R.string.nameLabelsGroup), - new SimpleInflater(Nickname.NAME)); - kp.typeOverallMax = 1; - kinds.add(kp); - - // We may want to change the order depending on displayOrderPrimary too. - kp.fieldList.add(new EditField(DataKind.PSEUDO_COLUMN_PHONETIC_NAME, - R.string.name_phonetic, FLAGS_PHONETIC).setShortForm(true)); - kp.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME, - R.string.name_phonetic_family, FLAGS_PHONETIC).setLongForm(true)); - kp.fieldList.add(new EditField(StructuredName.PHONETIC_MIDDLE_NAME, - R.string.name_phonetic_middle, FLAGS_PHONETIC).setLongForm(true)); - kp.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME, - R.string.name_phonetic_given, FLAGS_PHONETIC).setLongForm(true)); - return kinds; - } - } - - private static class NicknameKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "nickname"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - Nickname.CONTENT_ITEM_TYPE, null, R.string.nicknameLabelsGroup, Weight.NICKNAME, - R.layout.text_fields_editor_view, - new SimpleInflater(R.string.nicknameLabelsGroup), - new SimpleInflater(Nickname.NAME)); - - kind.fieldList.add(new EditField(Nickname.NAME, R.string.nicknameLabelsGroup, - FLAGS_PERSON_NAME)); - - kind.defaultValues = new ContentValues(); - kind.defaultValues.put(Nickname.TYPE, Nickname.TYPE_DEFAULT); - - throwIfList(kind); - return Lists.newArrayList(kind); - } - } - - private static class PhoneKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "phone"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - Phone.CONTENT_ITEM_TYPE, Phone.TYPE, R.string.phoneLabelsGroup, Weight.PHONE, - R.layout.text_fields_editor_view, - new PhoneActionInflater(), new SimpleInflater(Phone.NUMBER)); - - kind.iconAltRes = R.drawable.ic_text_holo_light; - kind.iconAltDescriptionRes = R.string.sms; - kind.actionAltHeader = new PhoneActionAltInflater(); - - kind.fieldList.add(new EditField(Phone.NUMBER, R.string.phoneLabelsGroup, FLAGS_PHONE)); - - return Lists.newArrayList(kind); - } - - /** Just to avoid line-wrapping... */ - protected static EditType build(int type, boolean secondary) { - return new EditType(type, Phone.getTypeLabelResource(type)).setSecondary(secondary); - } - - @Override - protected EditType buildEditTypeForTypeTag(AttributeSet attrs, String type) { - if ("home".equals(type)) return build(Phone.TYPE_HOME, false); - if ("mobile".equals(type)) return build(Phone.TYPE_MOBILE, false); - if ("work".equals(type)) return build(Phone.TYPE_WORK, false); - if ("fax_work".equals(type)) return build(Phone.TYPE_FAX_WORK, true); - if ("fax_home".equals(type)) return build(Phone.TYPE_FAX_HOME, true); - if ("pager".equals(type)) return build(Phone.TYPE_PAGER, true); - if ("other".equals(type)) return build(Phone.TYPE_OTHER, false); - if ("callback".equals(type)) return build(Phone.TYPE_CALLBACK, true); - if ("car".equals(type)) return build(Phone.TYPE_CAR, true); - if ("company_main".equals(type)) return build(Phone.TYPE_COMPANY_MAIN, true); - if ("isdn".equals(type)) return build(Phone.TYPE_ISDN, true); - if ("main".equals(type)) return build(Phone.TYPE_MAIN, true); - if ("other_fax".equals(type)) return build(Phone.TYPE_OTHER_FAX, true); - if ("radio".equals(type)) return build(Phone.TYPE_RADIO, true); - if ("telex".equals(type)) return build(Phone.TYPE_TELEX, true); - if ("tty_tdd".equals(type)) return build(Phone.TYPE_TTY_TDD, true); - if ("work_mobile".equals(type)) return build(Phone.TYPE_WORK_MOBILE, true); - if ("work_pager".equals(type)) return build(Phone.TYPE_WORK_PAGER, true); - - // Note "assistant" used to be a custom column for the fallback type, but not anymore. - if ("assistant".equals(type)) return build(Phone.TYPE_ASSISTANT, true); - if ("mms".equals(type)) return build(Phone.TYPE_MMS, true); - if ("custom".equals(type)) { - return build(Phone.TYPE_CUSTOM, true).setCustomColumn(Phone.LABEL); - } - return null; - } - } - - private static class EmailKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "email"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - Email.CONTENT_ITEM_TYPE, Email.TYPE, R.string.emailLabelsGroup, Weight.EMAIL, - R.layout.text_fields_editor_view, - new EmailActionInflater(), new SimpleInflater(Email.DATA)); - kind.fieldList.add(new EditField(Email.DATA, R.string.emailLabelsGroup, FLAGS_EMAIL)); - - return Lists.newArrayList(kind); - } - - @Override - protected EditType buildEditTypeForTypeTag(AttributeSet attrs, String type) { - // EditType is mutable, so we need to create a new instance every time. - if ("home".equals(type)) return buildEmailType(Email.TYPE_HOME); - if ("work".equals(type)) return buildEmailType(Email.TYPE_WORK); - if ("other".equals(type)) return buildEmailType(Email.TYPE_OTHER); - if ("mobile".equals(type)) return buildEmailType(Email.TYPE_MOBILE); - if ("custom".equals(type)) { - return buildEmailType(Email.TYPE_CUSTOM) - .setSecondary(true).setCustomColumn(Email.LABEL); - } - return null; - } - } - - private static class StructuredPostalKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "postal"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - StructuredPostal.CONTENT_ITEM_TYPE, StructuredPostal.TYPE, - R.string.postalLabelsGroup, Weight.STRUCTURED_POSTAL, - R.layout.text_fields_editor_view, new PostalActionInflater(), - new SimpleInflater(StructuredPostal.FORMATTED_ADDRESS)); - - if (getAttr(attrs, "needsStructured", false)) { - if (Locale.JAPANESE.getLanguage().equals(Locale.getDefault().getLanguage())) { - // Japanese order - kind.fieldList.add(new EditField(StructuredPostal.COUNTRY, - R.string.postal_country, FLAGS_POSTAL).setOptional(true)); - kind.fieldList.add(new EditField(StructuredPostal.POSTCODE, - R.string.postal_postcode, FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.REGION, - R.string.postal_region, FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.CITY, - R.string.postal_city,FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.STREET, - R.string.postal_street, FLAGS_POSTAL)); - } else { - // Generic order - kind.fieldList.add(new EditField(StructuredPostal.STREET, - R.string.postal_street, FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.CITY, - R.string.postal_city,FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.REGION, - R.string.postal_region, FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.POSTCODE, - R.string.postal_postcode, FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.COUNTRY, - R.string.postal_country, FLAGS_POSTAL).setOptional(true)); - } - } else { - kind.maxLinesForDisplay= MAX_LINES_FOR_POSTAL_ADDRESS; - kind.fieldList.add( - new EditField(StructuredPostal.FORMATTED_ADDRESS, R.string.postal_address, - FLAGS_POSTAL)); - } - - return Lists.newArrayList(kind); - } - - @Override - protected EditType buildEditTypeForTypeTag(AttributeSet attrs, String type) { - // EditType is mutable, so we need to create a new instance every time. - if ("home".equals(type)) return buildPostalType(StructuredPostal.TYPE_HOME); - if ("work".equals(type)) return buildPostalType(StructuredPostal.TYPE_WORK); - if ("other".equals(type)) return buildPostalType(StructuredPostal.TYPE_OTHER); - if ("custom".equals(type)) { - return buildPostalType(StructuredPostal.TYPE_CUSTOM) - .setSecondary(true).setCustomColumn(Email.LABEL); - } - return null; - } - } - - private static class ImKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "im"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - - // IM is special: - // - It uses "protocol" as the custom label field - // - Its TYPE is fixed to TYPE_OTHER - - final DataKind kind = newDataKind(context, parser, attrs, false, - Im.CONTENT_ITEM_TYPE, Im.PROTOCOL, R.string.imLabelsGroup, Weight.IM, - R.layout.text_fields_editor_view, - new ImActionInflater(), new SimpleInflater(Im.DATA) // header / action - ); - kind.fieldList.add(new EditField(Im.DATA, R.string.imLabelsGroup, FLAGS_EMAIL)); - - kind.defaultValues = new ContentValues(); - kind.defaultValues.put(Im.TYPE, Im.TYPE_OTHER); - - return Lists.newArrayList(kind); - } - - @Override - protected EditType buildEditTypeForTypeTag(AttributeSet attrs, String type) { - if ("aim".equals(type)) return buildImType(Im.PROTOCOL_AIM); - if ("msn".equals(type)) return buildImType(Im.PROTOCOL_MSN); - if ("yahoo".equals(type)) return buildImType(Im.PROTOCOL_YAHOO); - if ("skype".equals(type)) return buildImType(Im.PROTOCOL_SKYPE); - if ("qq".equals(type)) return buildImType(Im.PROTOCOL_QQ); - if ("google_talk".equals(type)) return buildImType(Im.PROTOCOL_GOOGLE_TALK); - if ("icq".equals(type)) return buildImType(Im.PROTOCOL_ICQ); - if ("jabber".equals(type)) return buildImType(Im.PROTOCOL_JABBER); - if ("custom".equals(type)) { - return buildImType(Im.PROTOCOL_CUSTOM).setSecondary(true) - .setCustomColumn(Im.CUSTOM_PROTOCOL); - } - return null; - } - } - - private static class OrganizationKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "organization"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - Organization.CONTENT_ITEM_TYPE, null, R.string.organizationLabelsGroup, - Weight.ORGANIZATION, R.layout.text_fields_editor_view , - new SimpleInflater(Organization.COMPANY), - new SimpleInflater(Organization.TITLE)); - - kind.fieldList.add(new EditField(Organization.COMPANY, R.string.ghostData_company, - FLAGS_GENERIC_NAME)); - kind.fieldList.add(new EditField(Organization.TITLE, R.string.ghostData_title, - FLAGS_GENERIC_NAME)); - - throwIfList(kind); - - return Lists.newArrayList(kind); - } - } - - private static class PhotoKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "photo"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - Photo.CONTENT_ITEM_TYPE, null /* no type */, -1, Weight.NONE, -1, - null, null // no header, no body - ); - - kind.fieldList.add(new EditField(Photo.PHOTO, -1, -1)); - - throwIfList(kind); - - return Lists.newArrayList(kind); - } - } - - private static class NoteKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "note"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - Note.CONTENT_ITEM_TYPE, null, R.string.label_notes, Weight.NOTE, - R.layout.text_fields_editor_view, - new SimpleInflater(R.string.label_notes), new SimpleInflater(Note.NOTE)); - - kind.fieldList.add(new EditField(Note.NOTE, R.string.label_notes, FLAGS_NOTE)); - kind.maxLinesForDisplay = MAX_LINES_FOR_NOTE; - - throwIfList(kind); - - return Lists.newArrayList(kind); - } - } - - private static class WebsiteKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "website"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - Website.CONTENT_ITEM_TYPE, null, R.string.websiteLabelsGroup, Weight.WEBSITE, - R.layout.text_fields_editor_view, - new SimpleInflater(R.string.websiteLabelsGroup), - new SimpleInflater(Website.URL)); - - kind.fieldList.add(new EditField(Website.URL, R.string.websiteLabelsGroup, - FLAGS_WEBSITE)); - - kind.defaultValues = new ContentValues(); - kind.defaultValues.put(Website.TYPE, Website.TYPE_OTHER); - - return Lists.newArrayList(kind); - } - } - - private static class SipAddressKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "sip_address"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - SipAddress.CONTENT_ITEM_TYPE, null, R.string.label_sip_address, - Weight.SIP_ADDRESS, R.layout.text_fields_editor_view, - new SimpleInflater(R.string.label_sip_address), - new SimpleInflater(SipAddress.SIP_ADDRESS)); - - kind.fieldList.add(new EditField(SipAddress.SIP_ADDRESS, - R.string.label_sip_address, FLAGS_SIP_ADDRESS)); - - throwIfList(kind); - - return Lists.newArrayList(kind); - } - } - - private static class GroupMembershipKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "group_membership"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - GroupMembership.CONTENT_ITEM_TYPE, null, - R.string.groupsLabel, Weight.GROUP_MEMBERSHIP, -1, null, null); - - kind.fieldList.add(new EditField(GroupMembership.GROUP_ROW_ID, -1, -1)); - kind.maxLinesForDisplay = MAX_LINES_FOR_GROUP; - - throwIfList(kind); - - return Lists.newArrayList(kind); - } - } - - /** - * Event DataKind parser. - * - * Event DataKind is used only for Google/Exchange types, so this parser is not used for now. - */ - private static class EventKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "event"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - Event.CONTENT_ITEM_TYPE, Event.TYPE, R.string.eventLabelsGroup, Weight.EVENT, - R.layout.event_field_editor_view, - new EventActionInflater(), new SimpleInflater(Event.START_DATE)); - - kind.fieldList.add(new EditField(Event.DATA, R.string.eventLabelsGroup, FLAGS_EVENT)); - - if (getAttr(attrs, Attr.DATE_WITH_TIME, false)) { - kind.dateFormatWithoutYear = DateUtils.NO_YEAR_DATE_AND_TIME_FORMAT; - kind.dateFormatWithYear = DateUtils.DATE_AND_TIME_FORMAT; - } else { - kind.dateFormatWithoutYear = DateUtils.NO_YEAR_DATE_FORMAT; - kind.dateFormatWithYear = DateUtils.FULL_DATE_FORMAT; - } - - return Lists.newArrayList(kind); - } - - @Override - protected EditType buildEditTypeForTypeTag(AttributeSet attrs, String type) { - final boolean yo = getAttr(attrs, Attr.YEAR_OPTIONAL, false); - - if ("birthday".equals(type)) { - return buildEventType(Event.TYPE_BIRTHDAY, yo).setSpecificMax(1); - } - if ("anniversary".equals(type)) return buildEventType(Event.TYPE_ANNIVERSARY, yo); - if ("other".equals(type)) return buildEventType(Event.TYPE_OTHER, yo); - if ("custom".equals(type)) { - return buildEventType(Event.TYPE_CUSTOM, yo) - .setSecondary(true).setCustomColumn(Event.LABEL); - } - return null; - } - } - - /** - * Relationship DataKind parser. - * - * Relationship DataKind is used only for Google/Exchange types, so this parser is not used for - * now. - */ - private static class RelationshipKindBuilder extends KindBuilder { - @Override - public String getTagName() { - return "relationship"; - } - - @Override - public List<DataKind> parseDataKind(Context context, XmlPullParser parser, - AttributeSet attrs) throws DefinitionException, XmlPullParserException, - IOException { - final DataKind kind = newDataKind(context, parser, attrs, false, - Relation.CONTENT_ITEM_TYPE, Relation.TYPE, - R.string.relationLabelsGroup, Weight.RELATIONSHIP, - R.layout.text_fields_editor_view, - new RelationActionInflater(), new SimpleInflater(Relation.NAME)); - - kind.fieldList.add(new EditField(Relation.DATA, R.string.relationLabelsGroup, - FLAGS_RELATION)); - - kind.defaultValues = new ContentValues(); - kind.defaultValues.put(Relation.TYPE, Relation.TYPE_SPOUSE); - - return Lists.newArrayList(kind); - } - - @Override - protected EditType buildEditTypeForTypeTag(AttributeSet attrs, String type) { - // EditType is mutable, so we need to create a new instance every time. - if ("assistant".equals(type)) return buildRelationType(Relation.TYPE_ASSISTANT); - if ("brother".equals(type)) return buildRelationType(Relation.TYPE_BROTHER); - if ("child".equals(type)) return buildRelationType(Relation.TYPE_CHILD); - if ("domestic_partner".equals(type)) { - return buildRelationType(Relation.TYPE_DOMESTIC_PARTNER); - } - if ("father".equals(type)) return buildRelationType(Relation.TYPE_FATHER); - if ("friend".equals(type)) return buildRelationType(Relation.TYPE_FRIEND); - if ("manager".equals(type)) return buildRelationType(Relation.TYPE_MANAGER); - if ("mother".equals(type)) return buildRelationType(Relation.TYPE_MOTHER); - if ("parent".equals(type)) return buildRelationType(Relation.TYPE_PARENT); - if ("partner".equals(type)) return buildRelationType(Relation.TYPE_PARTNER); - if ("referred_by".equals(type)) return buildRelationType(Relation.TYPE_REFERRED_BY); - if ("relative".equals(type)) return buildRelationType(Relation.TYPE_RELATIVE); - if ("sister".equals(type)) return buildRelationType(Relation.TYPE_SISTER); - if ("spouse".equals(type)) return buildRelationType(Relation.TYPE_SPOUSE); - if ("custom".equals(type)) { - return buildRelationType(Relation.TYPE_CUSTOM).setSecondary(true) - .setCustomColumn(Relation.LABEL); - } - return null; - } - } -} diff --git a/src/com/android/contacts/model/account/ExchangeAccountType.java b/src/com/android/contacts/model/account/ExchangeAccountType.java deleted file mode 100644 index 28b1f5c60..000000000 --- a/src/com/android/contacts/model/account/ExchangeAccountType.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.contacts.model.account; - -import android.content.ContentValues; -import android.content.Context; -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.util.Log; - -import com.android.contacts.R; -import com.android.contacts.model.dataitem.DataKind; -import com.android.contacts.util.DateUtils; -import com.google.common.collect.Lists; - -import java.util.Locale; - -public class ExchangeAccountType extends BaseAccountType { - private static final String TAG = "ExchangeAccountType"; - - public static final String ACCOUNT_TYPE_AOSP = "com.android.exchange"; - public static final String ACCOUNT_TYPE_GOOGLE = "com.google.android.exchange"; - - public ExchangeAccountType(Context context, String authenticatorPackageName, String type) { - this.accountType = type; - this.resourcePackageName = null; - this.syncAdapterPackageName = authenticatorPackageName; - - try { - addDataKindStructuredName(context); - addDataKindDisplayName(context); - addDataKindPhoneticName(context); - addDataKindNickname(context); - addDataKindPhone(context); - addDataKindEmail(context); - addDataKindStructuredPostal(context); - addDataKindIm(context); - addDataKindOrganization(context); - addDataKindPhoto(context); - addDataKindNote(context); - addDataKindEvent(context); - addDataKindWebsite(context); - addDataKindGroupMembership(context); - - mIsInitialized = true; - } catch (DefinitionException e) { - Log.e(TAG, "Problem building account type", e); - } - } - - public static boolean isExchangeType(String type) { - return ACCOUNT_TYPE_AOSP.equals(type) || ACCOUNT_TYPE_GOOGLE.equals(type); - } - - @Override - protected DataKind addDataKindStructuredName(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(StructuredName.CONTENT_ITEM_TYPE, - R.string.nameLabelsGroup, -1, true, R.layout.structured_name_editor_view)); - kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup); - kind.actionBody = new SimpleInflater(Nickname.NAME); - - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix, - FLAGS_PERSON_NAME).setOptional(true)); - kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, - R.string.name_family, FLAGS_PERSON_NAME)); - kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, - R.string.name_middle, FLAGS_PERSON_NAME)); - kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, - R.string.name_given, FLAGS_PERSON_NAME)); - kind.fieldList.add(new EditField(StructuredName.SUFFIX, - R.string.name_suffix, FLAGS_PERSON_NAME)); - - kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME, - R.string.name_phonetic_family, FLAGS_PHONETIC)); - kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME, - R.string.name_phonetic_given, FLAGS_PHONETIC)); - - return kind; - } - - @Override - protected DataKind addDataKindDisplayName(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME, - R.string.nameLabelsGroup, -1, true, R.layout.text_fields_editor_view)); - - boolean displayOrderPrimary = - context.getResources().getBoolean(R.bool.config_editor_field_order_primary); - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix, - FLAGS_PERSON_NAME).setOptional(true)); - if (!displayOrderPrimary) { - kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, - R.string.name_family, FLAGS_PERSON_NAME)); - kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, - R.string.name_middle, FLAGS_PERSON_NAME).setOptional(true)); - kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, - R.string.name_given, FLAGS_PERSON_NAME)); - } else { - kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, - R.string.name_given, FLAGS_PERSON_NAME)); - kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, - R.string.name_middle, FLAGS_PERSON_NAME).setOptional(true)); - kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, - R.string.name_family, FLAGS_PERSON_NAME)); - } - kind.fieldList.add(new EditField(StructuredName.SUFFIX, - R.string.name_suffix, FLAGS_PERSON_NAME).setOptional(true)); - - return kind; - } - - @Override - protected DataKind addDataKindPhoneticName(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME, - R.string.name_phonetic, -1, true, R.layout.phonetic_name_editor_view)); - kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup); - kind.actionBody = new SimpleInflater(Nickname.NAME); - - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME, - R.string.name_phonetic_family, FLAGS_PHONETIC)); - kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME, - R.string.name_phonetic_given, FLAGS_PHONETIC)); - - return kind; - } - - @Override - protected DataKind addDataKindNickname(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindNickname(context); - - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Nickname.NAME, R.string.nicknameLabelsGroup, - FLAGS_PERSON_NAME)); - - return kind; - } - - @Override - protected DataKind addDataKindPhone(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindPhone(context); - - kind.typeColumn = Phone.TYPE; - kind.typeList = Lists.newArrayList(); - kind.typeList.add(buildPhoneType(Phone.TYPE_MOBILE).setSpecificMax(1)); - kind.typeList.add(buildPhoneType(Phone.TYPE_HOME).setSpecificMax(2)); - kind.typeList.add(buildPhoneType(Phone.TYPE_WORK).setSpecificMax(2)); - kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_WORK).setSecondary(true) - .setSpecificMax(1)); - kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_HOME).setSecondary(true) - .setSpecificMax(1)); - kind.typeList - .add(buildPhoneType(Phone.TYPE_PAGER).setSecondary(true).setSpecificMax(1)); - kind.typeList.add(buildPhoneType(Phone.TYPE_CAR).setSecondary(true).setSpecificMax(1)); - kind.typeList.add(buildPhoneType(Phone.TYPE_COMPANY_MAIN).setSecondary(true) - .setSpecificMax(1)); - kind.typeList.add(buildPhoneType(Phone.TYPE_MMS).setSecondary(true).setSpecificMax(1)); - kind.typeList - .add(buildPhoneType(Phone.TYPE_RADIO).setSecondary(true).setSpecificMax(1)); - kind.typeList.add(buildPhoneType(Phone.TYPE_ASSISTANT).setSecondary(true) - .setSpecificMax(1)); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Phone.NUMBER, R.string.phoneLabelsGroup, FLAGS_PHONE)); - - return kind; - } - - @Override - protected DataKind addDataKindEmail(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindEmail(context); - - kind.typeOverallMax = 3; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Email.DATA, R.string.emailLabelsGroup, FLAGS_EMAIL)); - - return kind; - } - - @Override - protected DataKind addDataKindStructuredPostal(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindStructuredPostal(context); - - final boolean useJapaneseOrder = - Locale.JAPANESE.getLanguage().equals(Locale.getDefault().getLanguage()); - kind.typeColumn = StructuredPostal.TYPE; - kind.typeList = Lists.newArrayList(); - kind.typeList.add(buildPostalType(StructuredPostal.TYPE_WORK).setSpecificMax(1)); - kind.typeList.add(buildPostalType(StructuredPostal.TYPE_HOME).setSpecificMax(1)); - kind.typeList.add(buildPostalType(StructuredPostal.TYPE_OTHER).setSpecificMax(1)); - - kind.fieldList = Lists.newArrayList(); - if (useJapaneseOrder) { - kind.fieldList.add(new EditField(StructuredPostal.COUNTRY, - R.string.postal_country, FLAGS_POSTAL).setOptional(true)); - kind.fieldList.add(new EditField(StructuredPostal.POSTCODE, - R.string.postal_postcode, FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.REGION, - R.string.postal_region, FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.CITY, - R.string.postal_city,FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.STREET, - R.string.postal_street, FLAGS_POSTAL)); - } else { - kind.fieldList.add(new EditField(StructuredPostal.STREET, - R.string.postal_street, FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.CITY, - R.string.postal_city,FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.REGION, - R.string.postal_region, FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.POSTCODE, - R.string.postal_postcode, FLAGS_POSTAL)); - kind.fieldList.add(new EditField(StructuredPostal.COUNTRY, - R.string.postal_country, FLAGS_POSTAL).setOptional(true)); - } - - return kind; - } - - @Override - protected DataKind addDataKindIm(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindIm(context); - - // Types are not supported for IM. There can be 3 IMs, but OWA only shows only the first - kind.typeOverallMax = 3; - - kind.defaultValues = new ContentValues(); - kind.defaultValues.put(Im.TYPE, Im.TYPE_OTHER); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Im.DATA, R.string.imLabelsGroup, FLAGS_EMAIL)); - - return kind; - } - - @Override - protected DataKind addDataKindOrganization(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindOrganization(context); - - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Organization.COMPANY, R.string.ghostData_company, - FLAGS_GENERIC_NAME)); - kind.fieldList.add(new EditField(Organization.TITLE, R.string.ghostData_title, - FLAGS_GENERIC_NAME)); - - return kind; - } - - @Override - protected DataKind addDataKindPhoto(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindPhoto(context); - - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Photo.PHOTO, -1, -1)); - - return kind; - } - - @Override - protected DataKind addDataKindNote(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindNote(context); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Note.NOTE, R.string.label_notes, FLAGS_NOTE)); - - return kind; - } - - protected DataKind addDataKindEvent(Context context) throws DefinitionException { - DataKind kind = addKind( - new DataKind(Event.CONTENT_ITEM_TYPE, R.string.eventLabelsGroup, 150, true, - R.layout.event_field_editor_view)); - kind.actionHeader = new EventActionInflater(); - kind.actionBody = new SimpleInflater(Event.START_DATE); - - kind.typeOverallMax = 1; - - kind.typeColumn = Event.TYPE; - kind.typeList = Lists.newArrayList(); - kind.typeList.add(buildEventType(Event.TYPE_BIRTHDAY, false).setSpecificMax(1)); - - kind.dateFormatWithYear = DateUtils.DATE_AND_TIME_FORMAT; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Event.DATA, R.string.eventLabelsGroup, FLAGS_EVENT)); - - return kind; - } - - @Override - protected DataKind addDataKindWebsite(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindWebsite(context); - - kind.typeOverallMax = 1; - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Website.URL, R.string.websiteLabelsGroup, FLAGS_WEBSITE)); - - return kind; - } - - @Override - public boolean isGroupMembershipEditable() { - return true; - } - - @Override - public boolean areContactsWritable() { - return true; - } -} diff --git a/src/com/android/contacts/model/account/ExternalAccountType.java b/src/com/android/contacts/model/account/ExternalAccountType.java deleted file mode 100644 index 71dbebf6d..000000000 --- a/src/com/android/contacts/model/account/ExternalAccountType.java +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.contacts.model.account; - -import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ServiceInfo; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.provider.ContactsContract.CommonDataKinds.Photo; -import android.provider.ContactsContract.CommonDataKinds.StructuredName; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; -import android.util.Xml; - -import com.android.contacts.model.dataitem.DataKind; -import com.google.common.annotations.VisibleForTesting; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * A general contacts account type descriptor. - */ -public class ExternalAccountType extends BaseAccountType { - private static final String TAG = "ExternalAccountType"; - - private static final String METADATA_CONTACTS = "android.provider.CONTACTS_STRUCTURE"; - - private static final String TAG_CONTACTS_SOURCE_LEGACY = "ContactsSource"; - private static final String TAG_CONTACTS_ACCOUNT_TYPE = "ContactsAccountType"; - private static final String TAG_CONTACTS_DATA_KIND = "ContactsDataKind"; - private static final String TAG_EDIT_SCHEMA = "EditSchema"; - - private static final String ATTR_EDIT_CONTACT_ACTIVITY = "editContactActivity"; - private static final String ATTR_CREATE_CONTACT_ACTIVITY = "createContactActivity"; - private static final String ATTR_INVITE_CONTACT_ACTIVITY = "inviteContactActivity"; - private static final String ATTR_INVITE_CONTACT_ACTION_LABEL = "inviteContactActionLabel"; - private static final String ATTR_VIEW_CONTACT_NOTIFY_SERVICE = "viewContactNotifyService"; - private static final String ATTR_VIEW_GROUP_ACTIVITY = "viewGroupActivity"; - private static final String ATTR_VIEW_GROUP_ACTION_LABEL = "viewGroupActionLabel"; - private static final String ATTR_VIEW_STREAM_ITEM_ACTIVITY = "viewStreamItemActivity"; - private static final String ATTR_VIEW_STREAM_ITEM_PHOTO_ACTIVITY = - "viewStreamItemPhotoActivity"; - private static final String ATTR_DATA_SET = "dataSet"; - private static final String ATTR_EXTENSION_PACKAGE_NAMES = "extensionPackageNames"; - - // The following attributes should only be set in non-sync-adapter account types. They allow - // for the account type and resource IDs to be specified without an associated authenticator. - private static final String ATTR_ACCOUNT_TYPE = "accountType"; - private static final String ATTR_ACCOUNT_LABEL = "accountTypeLabel"; - private static final String ATTR_ACCOUNT_ICON = "accountTypeIcon"; - - private final boolean mIsExtension; - - private String mEditContactActivityClassName; - private String mCreateContactActivityClassName; - private String mInviteContactActivity; - private String mInviteActionLabelAttribute; - private int mInviteActionLabelResId; - private String mViewContactNotifyService; - private String mViewGroupActivity; - private String mViewGroupLabelAttribute; - private int mViewGroupLabelResId; - private String mViewStreamItemActivity; - private String mViewStreamItemPhotoActivity; - private List<String> mExtensionPackageNames; - private String mAccountTypeLabelAttribute; - private String mAccountTypeIconAttribute; - private boolean mHasContactsMetadata; - private boolean mHasEditSchema; - - public ExternalAccountType(Context context, String resPackageName, boolean isExtension) { - this(context, resPackageName, isExtension, null); - } - - /** - * Constructor used for testing to initialize with any arbitrary XML. - * - * @param injectedMetadata If non-null, it'll be used to initialize the type. Only set by - * tests. If null, the metadata is loaded from the specified package. - */ - ExternalAccountType(Context context, String packageName, boolean isExtension, - XmlResourceParser injectedMetadata) { - this.mIsExtension = isExtension; - this.resourcePackageName = packageName; - this.syncAdapterPackageName = packageName; - - final PackageManager pm = context.getPackageManager(); - final XmlResourceParser parser; - if (injectedMetadata == null) { - try { - parser = loadContactsXml(context, packageName); - } catch (NameNotFoundException e1) { - // If the package name is not found, we can't initialize this account type. - return; - } - } else { - parser = injectedMetadata; - } - boolean needLineNumberInErrorLog = true; - try { - if (parser != null) { - inflate(context, parser); - } - - // Done parsing; line number no longer needed in error log. - needLineNumberInErrorLog = false; - if (mHasEditSchema) { - checkKindExists(StructuredName.CONTENT_ITEM_TYPE); - checkKindExists(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME); - checkKindExists(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME); - checkKindExists(Photo.CONTENT_ITEM_TYPE); - } else { - // Bring in name and photo from fallback source, which are non-optional - addDataKindStructuredName(context); - addDataKindDisplayName(context); - addDataKindPhoneticName(context); - addDataKindPhoto(context); - } - } catch (DefinitionException e) { - final StringBuilder error = new StringBuilder(); - error.append("Problem reading XML"); - if (needLineNumberInErrorLog && (parser != null)) { - error.append(" in line "); - error.append(parser.getLineNumber()); - } - error.append(" for external package "); - error.append(packageName); - - Log.e(TAG, error.toString(), e); - return; - } finally { - if (parser != null) { - parser.close(); - } - } - - mExtensionPackageNames = new ArrayList<String>(); - mInviteActionLabelResId = resolveExternalResId(context, mInviteActionLabelAttribute, - syncAdapterPackageName, ATTR_INVITE_CONTACT_ACTION_LABEL); - mViewGroupLabelResId = resolveExternalResId(context, mViewGroupLabelAttribute, - syncAdapterPackageName, ATTR_VIEW_GROUP_ACTION_LABEL); - titleRes = resolveExternalResId(context, mAccountTypeLabelAttribute, - syncAdapterPackageName, ATTR_ACCOUNT_LABEL); - iconRes = resolveExternalResId(context, mAccountTypeIconAttribute, - syncAdapterPackageName, ATTR_ACCOUNT_ICON); - - // If we reach this point, the account type has been successfully initialized. - mIsInitialized = true; - } - - /** - * Returns the CONTACTS_STRUCTURE metadata (aka "contacts.xml") in the given apk package. - * - * Unfortunately, there's no public way to determine which service defines a sync service for - * which account type, so this method looks through all services in the package, and just - * returns the first CONTACTS_STRUCTURE metadata defined in any of them. - * - * Returns {@code null} if the package has no CONTACTS_STRUCTURE metadata. In this case - * the account type *will* be initialized with minimal configuration. - * - * On the other hand, if the package is not found, it throws a {@link NameNotFoundException}, - * in which case the account type will *not* be initialized. - */ - private XmlResourceParser loadContactsXml(Context context, String resPackageName) - throws NameNotFoundException { - final PackageManager pm = context.getPackageManager(); - PackageInfo packageInfo = pm.getPackageInfo(resPackageName, - PackageManager.GET_SERVICES|PackageManager.GET_META_DATA); - for (ServiceInfo serviceInfo : packageInfo.services) { - final XmlResourceParser parser = serviceInfo.loadXmlMetaData(pm, - METADATA_CONTACTS); - if (parser != null) { - return parser; - } - } - // Package was found, but that doesn't contain the CONTACTS_STRUCTURE metadata. - return null; - } - - private void checkKindExists(String mimeType) throws DefinitionException { - if (getKindForMimetype(mimeType) == null) { - throw new DefinitionException(mimeType + " must be supported"); - } - } - - @Override - public boolean isEmbedded() { - return false; - } - - @Override - public boolean isExtension() { - return mIsExtension; - } - - @Override - public boolean areContactsWritable() { - return mHasEditSchema; - } - - /** - * Whether this account type has the android.provider.CONTACTS_STRUCTURE metadata xml. - */ - public boolean hasContactsMetadata() { - return mHasContactsMetadata; - } - - @Override - public String getEditContactActivityClassName() { - return mEditContactActivityClassName; - } - - @Override - public String getCreateContactActivityClassName() { - return mCreateContactActivityClassName; - } - - @Override - public String getInviteContactActivityClassName() { - return mInviteContactActivity; - } - - @Override - protected int getInviteContactActionResId() { - return mInviteActionLabelResId; - } - - @Override - public String getViewContactNotifyServiceClassName() { - return mViewContactNotifyService; - } - - @Override - public String getViewGroupActivity() { - return mViewGroupActivity; - } - - @Override - protected int getViewGroupLabelResId() { - return mViewGroupLabelResId; - } - - @Override - public String getViewStreamItemActivity() { - return mViewStreamItemActivity; - } - - @Override - public String getViewStreamItemPhotoActivity() { - return mViewStreamItemPhotoActivity; - } - - @Override - public List<String> getExtensionPackageNames() { - return mExtensionPackageNames; - } - - /** - * Inflate this {@link AccountType} from the given parser. This may only - * load details matching the publicly-defined schema. - */ - protected void inflate(Context context, XmlPullParser parser) throws DefinitionException { - final AttributeSet attrs = Xml.asAttributeSet(parser); - - try { - int type; - while ((type = parser.next()) != XmlPullParser.START_TAG - && type != XmlPullParser.END_DOCUMENT) { - // Drain comments and whitespace - } - - if (type != XmlPullParser.START_TAG) { - throw new IllegalStateException("No start tag found"); - } - - String rootTag = parser.getName(); - if (!TAG_CONTACTS_ACCOUNT_TYPE.equals(rootTag) && - !TAG_CONTACTS_SOURCE_LEGACY.equals(rootTag)) { - throw new IllegalStateException("Top level element must be " - + TAG_CONTACTS_ACCOUNT_TYPE + ", not " + rootTag); - } - - mHasContactsMetadata = true; - - int attributeCount = parser.getAttributeCount(); - for (int i = 0; i < attributeCount; i++) { - String attr = parser.getAttributeName(i); - String value = parser.getAttributeValue(i); - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, attr + "=" + value); - } - if (ATTR_EDIT_CONTACT_ACTIVITY.equals(attr)) { - mEditContactActivityClassName = value; - } else if (ATTR_CREATE_CONTACT_ACTIVITY.equals(attr)) { - mCreateContactActivityClassName = value; - } else if (ATTR_INVITE_CONTACT_ACTIVITY.equals(attr)) { - mInviteContactActivity = value; - } else if (ATTR_INVITE_CONTACT_ACTION_LABEL.equals(attr)) { - mInviteActionLabelAttribute = value; - } else if (ATTR_VIEW_CONTACT_NOTIFY_SERVICE.equals(attr)) { - mViewContactNotifyService = value; - } else if (ATTR_VIEW_GROUP_ACTIVITY.equals(attr)) { - mViewGroupActivity = value; - } else if (ATTR_VIEW_GROUP_ACTION_LABEL.equals(attr)) { - mViewGroupLabelAttribute = value; - } else if (ATTR_VIEW_STREAM_ITEM_ACTIVITY.equals(attr)) { - mViewStreamItemActivity = value; - } else if (ATTR_VIEW_STREAM_ITEM_PHOTO_ACTIVITY.equals(attr)) { - mViewStreamItemPhotoActivity = value; - } else if (ATTR_DATA_SET.equals(attr)) { - dataSet = value; - } else if (ATTR_EXTENSION_PACKAGE_NAMES.equals(attr)) { - mExtensionPackageNames.add(value); - } else if (ATTR_ACCOUNT_TYPE.equals(attr)) { - accountType = value; - } else if (ATTR_ACCOUNT_LABEL.equals(attr)) { - mAccountTypeLabelAttribute = value; - } else if (ATTR_ACCOUNT_ICON.equals(attr)) { - mAccountTypeIconAttribute = value; - } else { - Log.e(TAG, "Unsupported attribute " + attr); - } - } - - // Parse all children kinds - final int startDepth = parser.getDepth(); - while (((type = parser.next()) != XmlPullParser.END_TAG - || parser.getDepth() > startDepth) - && type != XmlPullParser.END_DOCUMENT) { - - if (type != XmlPullParser.START_TAG || parser.getDepth() != startDepth + 1) { - continue; // Not a direct child tag - } - - String tag = parser.getName(); - if (TAG_EDIT_SCHEMA.equals(tag)) { - mHasEditSchema = true; - parseEditSchema(context, parser, attrs); - } else if (TAG_CONTACTS_DATA_KIND.equals(tag)) { - final TypedArray a = context.obtainStyledAttributes(attrs, - android.R.styleable.ContactsDataKind); - final DataKind kind = new DataKind(); - - kind.mimeType = a - .getString(com.android.internal.R.styleable.ContactsDataKind_mimeType); - - final String summaryColumn = a.getString( - com.android.internal.R.styleable.ContactsDataKind_summaryColumn); - if (summaryColumn != null) { - // Inflate a specific column as summary when requested - kind.actionHeader = new SimpleInflater(summaryColumn); - } - - final String detailColumn = a.getString( - com.android.internal.R.styleable.ContactsDataKind_detailColumn); - final boolean detailSocialSummary = a.getBoolean( - com.android.internal.R.styleable.ContactsDataKind_detailSocialSummary, - false); - - if (detailSocialSummary) { - // Inflate social summary when requested - kind.actionBodySocial = true; - } - - if (detailColumn != null) { - // Inflate specific column as summary - kind.actionBody = new SimpleInflater(detailColumn); - } - - a.recycle(); - - addKind(kind); - } - } - } catch (XmlPullParserException e) { - throw new DefinitionException("Problem reading XML", e); - } catch (IOException e) { - throw new DefinitionException("Problem reading XML", e); - } - } - - /** - * Takes a string in the "@xxx/yyy" format and return the resource ID for the resource in - * the resource package. - * - * If the argument is in the invalid format or isn't a resource name, it returns -1. - * - * @param context context - * @param resourceName Resource name in the "@xxx/yyy" format, e.g. "@string/invite_lavbel" - * @param packageName name of the package containing the resource. - * @param xmlAttributeName attribute name which the resource came from. Used for logging. - */ - @VisibleForTesting - static int resolveExternalResId(Context context, String resourceName, - String packageName, String xmlAttributeName) { - if (TextUtils.isEmpty(resourceName)) { - return -1; // Empty text is okay. - } - if (resourceName.charAt(0) != '@') { - Log.e(TAG, xmlAttributeName + " must be a resource name beginnig with '@'"); - return -1; - } - final String name = resourceName.substring(1); - final Resources res; - try { - res = context.getPackageManager().getResourcesForApplication(packageName); - } catch (NameNotFoundException e) { - Log.e(TAG, "Unable to load package " + packageName); - return -1; - } - final int resId = res.getIdentifier(name, null, packageName); - if (resId == 0) { - Log.e(TAG, "Unable to load " + resourceName + " from package " + packageName); - return -1; - } - return resId; - } -} diff --git a/src/com/android/contacts/model/account/FallbackAccountType.java b/src/com/android/contacts/model/account/FallbackAccountType.java deleted file mode 100644 index dae288da8..000000000 --- a/src/com/android/contacts/model/account/FallbackAccountType.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.contacts.model.account; - -import android.content.Context; -import android.util.Log; - -import com.android.contacts.R; -import com.android.contacts.model.dataitem.DataKind; -import com.android.contacts.test.NeededForTesting; - -public class FallbackAccountType extends BaseAccountType { - private static final String TAG = "FallbackAccountType"; - - private FallbackAccountType(Context context, String resPackageName) { - this.accountType = null; - this.dataSet = null; - this.titleRes = R.string.account_phone; - this.iconRes = R.mipmap.ic_launcher_contacts; - - // Note those are only set for unit tests. - this.resourcePackageName = resPackageName; - this.syncAdapterPackageName = resPackageName; - - try { - addDataKindStructuredName(context); - addDataKindDisplayName(context); - addDataKindPhoneticName(context); - addDataKindNickname(context); - addDataKindPhone(context); - addDataKindEmail(context); - addDataKindStructuredPostal(context); - addDataKindIm(context); - addDataKindOrganization(context); - addDataKindPhoto(context); - addDataKindNote(context); - addDataKindWebsite(context); - addDataKindSipAddress(context); - - mIsInitialized = true; - } catch (DefinitionException e) { - Log.e(TAG, "Problem building account type", e); - } - } - - public FallbackAccountType(Context context) { - this(context, null); - } - - /** - * Used to compare with an {@link ExternalAccountType} built from a test contacts.xml. - * In order to build {@link DataKind}s with the same resource package name, - * {@code resPackageName} is injectable. - */ - @NeededForTesting - static AccountType createWithPackageNameForTest(Context context, String resPackageName) { - return new FallbackAccountType(context, resPackageName); - } - - @Override - public boolean areContactsWritable() { - return true; - } -} diff --git a/src/com/android/contacts/model/account/GoogleAccountType.java b/src/com/android/contacts/model/account/GoogleAccountType.java deleted file mode 100644 index 192c3d0e5..000000000 --- a/src/com/android/contacts/model/account/GoogleAccountType.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.contacts.model.account; - -import android.content.ContentValues; -import android.content.Context; -import android.provider.ContactsContract.CommonDataKinds.Email; -import android.provider.ContactsContract.CommonDataKinds.Event; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.CommonDataKinds.Relation; -import android.util.Log; - -import com.android.contacts.R; -import com.android.contacts.model.dataitem.DataKind; -import com.android.contacts.util.DateUtils; -import com.google.common.collect.Lists; - -import java.util.List; - -public class GoogleAccountType extends BaseAccountType { - private static final String TAG = "GoogleAccountType"; - - public static final String ACCOUNT_TYPE = "com.google"; - - private static final List<String> mExtensionPackages = - Lists.newArrayList("com.google.android.apps.plus"); - - public GoogleAccountType(Context context, String authenticatorPackageName) { - this.accountType = ACCOUNT_TYPE; - this.resourcePackageName = null; - this.syncAdapterPackageName = authenticatorPackageName; - - try { - addDataKindStructuredName(context); - addDataKindDisplayName(context); - addDataKindPhoneticName(context); - addDataKindNickname(context); - addDataKindPhone(context); - addDataKindEmail(context); - addDataKindStructuredPostal(context); - addDataKindIm(context); - addDataKindOrganization(context); - addDataKindPhoto(context); - addDataKindNote(context); - addDataKindWebsite(context); - addDataKindSipAddress(context); - addDataKindGroupMembership(context); - addDataKindRelation(context); - addDataKindEvent(context); - - mIsInitialized = true; - } catch (DefinitionException e) { - Log.e(TAG, "Problem building account type", e); - } - } - - @Override - public List<String> getExtensionPackageNames() { - return mExtensionPackages; - } - - @Override - protected DataKind addDataKindPhone(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindPhone(context); - - kind.typeColumn = Phone.TYPE; - kind.typeList = Lists.newArrayList(); - kind.typeList.add(buildPhoneType(Phone.TYPE_MOBILE)); - kind.typeList.add(buildPhoneType(Phone.TYPE_WORK)); - kind.typeList.add(buildPhoneType(Phone.TYPE_HOME)); - kind.typeList.add(buildPhoneType(Phone.TYPE_MAIN)); - kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_WORK).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_HOME).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_PAGER).setSecondary(true)); - kind.typeList.add(buildPhoneType(Phone.TYPE_OTHER)); - kind.typeList.add(buildPhoneType(Phone.TYPE_CUSTOM).setSecondary(true) - .setCustomColumn(Phone.LABEL)); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Phone.NUMBER, R.string.phoneLabelsGroup, FLAGS_PHONE)); - - return kind; - } - - @Override - protected DataKind addDataKindEmail(Context context) throws DefinitionException { - final DataKind kind = super.addDataKindEmail(context); - - kind.typeColumn = Email.TYPE; - kind.typeList = Lists.newArrayList(); - kind.typeList.add(buildEmailType(Email.TYPE_HOME)); - kind.typeList.add(buildEmailType(Email.TYPE_WORK)); - kind.typeList.add(buildEmailType(Email.TYPE_OTHER)); - kind.typeList.add(buildEmailType(Email.TYPE_CUSTOM).setSecondary(true).setCustomColumn( - Email.LABEL)); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Email.DATA, R.string.emailLabelsGroup, FLAGS_EMAIL)); - - return kind; - } - - private DataKind addDataKindRelation(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(Relation.CONTENT_ITEM_TYPE, - R.string.relationLabelsGroup, 160, true, R.layout.text_fields_editor_view)); - kind.actionHeader = new RelationActionInflater(); - kind.actionBody = new SimpleInflater(Relation.NAME); - - kind.typeColumn = Relation.TYPE; - kind.typeList = Lists.newArrayList(); - kind.typeList.add(buildRelationType(Relation.TYPE_ASSISTANT)); - kind.typeList.add(buildRelationType(Relation.TYPE_BROTHER)); - kind.typeList.add(buildRelationType(Relation.TYPE_CHILD)); - kind.typeList.add(buildRelationType(Relation.TYPE_DOMESTIC_PARTNER)); - kind.typeList.add(buildRelationType(Relation.TYPE_FATHER)); - kind.typeList.add(buildRelationType(Relation.TYPE_FRIEND)); - kind.typeList.add(buildRelationType(Relation.TYPE_MANAGER)); - kind.typeList.add(buildRelationType(Relation.TYPE_MOTHER)); - kind.typeList.add(buildRelationType(Relation.TYPE_PARENT)); - kind.typeList.add(buildRelationType(Relation.TYPE_PARTNER)); - kind.typeList.add(buildRelationType(Relation.TYPE_REFERRED_BY)); - kind.typeList.add(buildRelationType(Relation.TYPE_RELATIVE)); - kind.typeList.add(buildRelationType(Relation.TYPE_SISTER)); - kind.typeList.add(buildRelationType(Relation.TYPE_SPOUSE)); - kind.typeList.add(buildRelationType(Relation.TYPE_CUSTOM).setSecondary(true) - .setCustomColumn(Relation.LABEL)); - - kind.defaultValues = new ContentValues(); - kind.defaultValues.put(Relation.TYPE, Relation.TYPE_SPOUSE); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Relation.DATA, R.string.relationLabelsGroup, - FLAGS_RELATION)); - - return kind; - } - - private DataKind addDataKindEvent(Context context) throws DefinitionException { - DataKind kind = addKind(new DataKind(Event.CONTENT_ITEM_TYPE, - R.string.eventLabelsGroup, 150, true, R.layout.event_field_editor_view)); - kind.actionHeader = new EventActionInflater(); - kind.actionBody = new SimpleInflater(Event.START_DATE); - - kind.typeColumn = Event.TYPE; - kind.typeList = Lists.newArrayList(); - kind.dateFormatWithoutYear = DateUtils.NO_YEAR_DATE_FORMAT; - kind.dateFormatWithYear = DateUtils.FULL_DATE_FORMAT; - kind.typeList.add(buildEventType(Event.TYPE_BIRTHDAY, true).setSpecificMax(1)); - kind.typeList.add(buildEventType(Event.TYPE_ANNIVERSARY, false)); - kind.typeList.add(buildEventType(Event.TYPE_OTHER, false)); - kind.typeList.add(buildEventType(Event.TYPE_CUSTOM, false).setSecondary(true) - .setCustomColumn(Event.LABEL)); - - kind.defaultValues = new ContentValues(); - kind.defaultValues.put(Event.TYPE, Event.TYPE_BIRTHDAY); - - kind.fieldList = Lists.newArrayList(); - kind.fieldList.add(new EditField(Event.DATA, R.string.eventLabelsGroup, FLAGS_EVENT)); - - return kind; - } - - @Override - public boolean isGroupMembershipEditable() { - return true; - } - - @Override - public boolean areContactsWritable() { - return true; - } - - @Override - public String getViewContactNotifyServiceClassName() { - return "com.google.android.syncadapters.contacts." + - "SyncHighResPhotoIntentService"; - } - - @Override - public String getViewContactNotifyServicePackageName() { - return "com.google.android.syncadapters.contacts"; - } -} diff --git a/src/com/android/contacts/model/dataitem/DataItem.java b/src/com/android/contacts/model/dataitem/DataItem.java index 9c618de7a..38d0c0339 100644 --- a/src/com/android/contacts/model/dataitem/DataItem.java +++ b/src/com/android/contacts/model/dataitem/DataItem.java @@ -35,6 +35,8 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.provider.ContactsContract.CommonDataKinds.Website; import android.provider.ContactsContract.Contacts.Data; +import com.android.contacts.common.model.dataitem.DataKind; + /** * This is the base class for data items, which represents a row from the Data table. */ diff --git a/src/com/android/contacts/model/dataitem/DataKind.java b/src/com/android/contacts/model/dataitem/DataKind.java deleted file mode 100644 index 204b784f4..000000000 --- a/src/com/android/contacts/model/dataitem/DataKind.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.contacts.model.dataitem; - -import android.content.ContentValues; -import android.content.Context; -import android.provider.ContactsContract.Data; - -import com.android.contacts.R; -import com.android.contacts.model.account.AccountType.EditField; -import com.android.contacts.model.account.AccountType.EditType; -import com.android.contacts.model.account.AccountType.StringInflater; -import com.google.common.collect.Iterators; - -import java.text.SimpleDateFormat; -import java.util.List; - -/** - * Description of a specific data type, usually marked by a unique - * {@link Data#MIMETYPE}. Includes details about how to view and edit - * {@link Data} rows of this kind, including the possible {@link EditType} - * labels and editable {@link EditField}. - */ -public final class DataKind { - - public static final String PSEUDO_MIME_TYPE_DISPLAY_NAME = "#displayName"; - public static final String PSEUDO_MIME_TYPE_PHONETIC_NAME = "#phoneticName"; - public static final String PSEUDO_COLUMN_PHONETIC_NAME = "#phoneticName"; - - public String resourcePackageName; - public String mimeType; - public int titleRes; - public int iconAltRes; - public int iconAltDescriptionRes; - public int weight; - public boolean editable; - - public StringInflater actionHeader; - public StringInflater actionAltHeader; - public StringInflater actionBody; - - public boolean actionBodySocial = false; - - public String typeColumn; - - /** - * Maximum number of values allowed in the list. -1 represents infinity. - */ - public int typeOverallMax; - - public List<EditType> typeList; - public List<EditField> fieldList; - - public ContentValues defaultValues; - - /** Layout resource id for an editor view to edit this {@link DataKind}. */ - public final int editorLayoutResourceId; - - /** - * If this is a date field, this specifies the format of the date when saving. The - * date includes year, month and day. If this is not a date field or the date field is not - * editable, this value should be ignored. - */ - public SimpleDateFormat dateFormatWithoutYear; - - /** - * If this is a date field, this specifies the format of the date when saving. The - * date includes month and day. If this is not a date field, the field is not editable or - * dates without year are not supported, this value should be ignored. - */ - public SimpleDateFormat dateFormatWithYear; - - /** - * The number of lines available for displaying this kind of data in a - * {@link ContactDetailFragment} (and possibly elsewhere) - * Defaults to 1. - */ - public int maxLinesForDisplay; - - public DataKind() { - editorLayoutResourceId = R.layout.text_fields_editor_view; - maxLinesForDisplay = 1; - } - - public DataKind(String mimeType, int titleRes, int weight, boolean editable, - int editorLayoutResourceId) { - this.mimeType = mimeType; - this.titleRes = titleRes; - this.weight = weight; - this.editable = editable; - this.typeOverallMax = -1; - this.editorLayoutResourceId = editorLayoutResourceId; - maxLinesForDisplay = 1; - } - - public String getKindString(Context context) { - return (titleRes == -1 || titleRes == 0) ? "" : context.getString(titleRes); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("DataKind:"); - sb.append(" resPackageName=").append(resourcePackageName); - sb.append(" mimeType=").append(mimeType); - sb.append(" titleRes=").append(titleRes); - sb.append(" iconAltRes=").append(iconAltRes); - sb.append(" iconAltDescriptionRes=").append(iconAltDescriptionRes); - sb.append(" weight=").append(weight); - sb.append(" editable=").append(editable); - sb.append(" actionHeader=").append(actionHeader); - sb.append(" actionAltHeader=").append(actionAltHeader); - sb.append(" actionBody=").append(actionBody); - sb.append(" actionBodySocial=").append(actionBodySocial); - sb.append(" typeColumn=").append(typeColumn); - sb.append(" typeOverallMax=").append(typeOverallMax); - sb.append(" typeList=").append(toString(typeList)); - sb.append(" fieldList=").append(toString(fieldList)); - sb.append(" defaultValues=").append(defaultValues); - sb.append(" editorLayoutResourceId=").append(editorLayoutResourceId); - sb.append(" dateFormatWithoutYear=").append(toString(dateFormatWithoutYear)); - sb.append(" dateFormatWithYear=").append(toString(dateFormatWithYear)); - - return sb.toString(); - } - - public static String toString(SimpleDateFormat format) { - return format == null ? "(null)" : format.toPattern(); - } - - public static String toString(Iterable<?> list) { - if (list == null) { - return "(null)"; - } else { - return Iterators.toString(list.iterator()); - } - } -} diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java index 3cf3adf1f..90a97de27 100644 --- a/src/com/android/contacts/quickcontact/DataAction.java +++ b/src/com/android/contacts/quickcontact/DataAction.java @@ -32,9 +32,9 @@ import com.android.contacts.common.CallUtil; import com.android.contacts.ContactsUtils; import com.android.contacts.R; import com.android.contacts.common.MoreContactUtils; -import com.android.contacts.model.account.AccountType.EditType; +import com.android.contacts.common.model.account.AccountType.EditType; import com.android.contacts.model.dataitem.DataItem; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.model.dataitem.EmailDataItem; import com.android.contacts.model.dataitem.ImDataItem; import com.android.contacts.model.dataitem.PhoneDataItem; diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java index 36d29ecf4..9044e325f 100644 --- a/src/com/android/contacts/quickcontact/QuickContactActivity.java +++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java @@ -62,9 +62,9 @@ import com.android.contacts.model.AccountTypeManager; import com.android.contacts.model.Contact; import com.android.contacts.model.ContactLoader; import com.android.contacts.model.RawContact; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import com.android.contacts.model.dataitem.DataItem; -import com.android.contacts.model.dataitem.DataKind; +import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.model.dataitem.EmailDataItem; import com.android.contacts.model.dataitem.ImDataItem; import com.android.contacts.util.Constants; diff --git a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java index 259f38db7..5c584b4c8 100644 --- a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java +++ b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java @@ -41,7 +41,7 @@ import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; import com.android.contacts.model.Contact; import com.android.contacts.model.ContactLoader; -import com.android.contacts.model.account.AccountType; +import com.android.contacts.common.model.account.AccountType; import com.android.contacts.quickcontact.QuickContactBroadcastReceiver; import com.android.contacts.util.ContactBadgeUtil; import com.android.contacts.util.HtmlUtils; diff --git a/src/com/android/contacts/test/NeededForTesting.java b/src/com/android/contacts/test/NeededForTesting.java deleted file mode 100644 index f40fe2c00..000000000 --- a/src/com/android/contacts/test/NeededForTesting.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.contacts.test; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Denotes that the class, constructor, method or field is used by tests and therefore cannot be - * removed by tools like ProGuard. - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD}) -public @interface NeededForTesting {} diff --git a/src/com/android/contacts/util/AccountPromptUtils.java b/src/com/android/contacts/util/AccountPromptUtils.java index cdefda0b7..979176b1b 100644 --- a/src/com/android/contacts/util/AccountPromptUtils.java +++ b/src/com/android/contacts/util/AccountPromptUtils.java @@ -30,7 +30,7 @@ import android.preference.PreferenceManager; import android.util.Log; import com.android.contacts.R; -import com.android.contacts.model.account.GoogleAccountType; +import com.android.contacts.common.model.account.GoogleAccountType; import java.io.IOException; diff --git a/src/com/android/contacts/util/AccountSelectionUtil.java b/src/com/android/contacts/util/AccountSelectionUtil.java index d83cb410c..d3c9d14e1 100644 --- a/src/com/android/contacts/util/AccountSelectionUtil.java +++ b/src/com/android/contacts/util/AccountSelectionUtil.java @@ -32,8 +32,8 @@ import android.widget.TextView; import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; import java.util.List; diff --git a/src/com/android/contacts/util/AccountsListAdapter.java b/src/com/android/contacts/util/AccountsListAdapter.java index 4355cba6f..274004935 100644 --- a/src/com/android/contacts/util/AccountsListAdapter.java +++ b/src/com/android/contacts/util/AccountsListAdapter.java @@ -27,8 +27,8 @@ import android.widget.TextView; import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountType; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/contacts/util/DateUtils.java b/src/com/android/contacts/util/DateUtils.java index 89127c93a..56fcead89 100644 --- a/src/com/android/contacts/util/DateUtils.java +++ b/src/com/android/contacts/util/DateUtils.java @@ -19,6 +19,8 @@ package com.android.contacts.util; import android.content.Context; import android.text.format.DateFormat; +import com.android.contacts.common.util.CommonDateUtils; + import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -32,26 +34,17 @@ import java.util.TimeZone; public class DateUtils { public static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("UTC"); - // All the SimpleDateFormats in this class use the UTC timezone - public static final SimpleDateFormat NO_YEAR_DATE_FORMAT = - new SimpleDateFormat("--MM-dd", Locale.US); /** * When parsing a date without a year, the system assumes 1970, which wasn't a leap-year. * Let's add a one-off hack for that day of the year */ public static final String NO_YEAR_DATE_FEB29TH = "--02-29"; - public static final SimpleDateFormat FULL_DATE_FORMAT = - new SimpleDateFormat("yyyy-MM-dd", Locale.US); - public static final SimpleDateFormat DATE_AND_TIME_FORMAT = - new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); - public static final SimpleDateFormat NO_YEAR_DATE_AND_TIME_FORMAT = - new SimpleDateFormat("--MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); // Variations of ISO 8601 date format. Do not change the order - it does affect the // result in ambiguous cases. private static final SimpleDateFormat[] DATE_FORMATS = { - FULL_DATE_FORMAT, - DATE_AND_TIME_FORMAT, + CommonDateUtils.FULL_DATE_FORMAT, + CommonDateUtils.DATE_AND_TIME_FORMAT, new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US), new SimpleDateFormat("yyyyMMdd", Locale.US), new SimpleDateFormat("yyyyMMdd'T'HHmmssSSS'Z'", Locale.US), @@ -70,7 +63,7 @@ public class DateUtils { format.setLenient(true); format.setTimeZone(UTC_TIMEZONE); } - NO_YEAR_DATE_FORMAT.setTimeZone(UTC_TIMEZONE); + CommonDateUtils.NO_YEAR_DATE_FORMAT.setTimeZone(UTC_TIMEZONE); FORMAT_WITHOUT_YEAR_MONTH_FIRST.setTimeZone(UTC_TIMEZONE); FORMAT_WITHOUT_YEAR_DAY_FIRST.setTimeZone(UTC_TIMEZONE); } @@ -127,8 +120,8 @@ public class DateUtils { date = getUtcDate(0, Calendar.FEBRUARY, 29); noYearParsed = true; } else { - synchronized (NO_YEAR_DATE_FORMAT) { - date = NO_YEAR_DATE_FORMAT.parse(string, parsePosition); + synchronized (CommonDateUtils.NO_YEAR_DATE_FORMAT) { + date = CommonDateUtils.NO_YEAR_DATE_FORMAT.parse(string, parsePosition); } noYearParsed = parsePosition.getIndex() == string.length(); } diff --git a/src/com/android/contacts/util/StreamItemEntry.java b/src/com/android/contacts/util/StreamItemEntry.java index b15bae918..2332c0e91 100644 --- a/src/com/android/contacts/util/StreamItemEntry.java +++ b/src/com/android/contacts/util/StreamItemEntry.java @@ -22,7 +22,7 @@ import android.provider.ContactsContract.StreamItems; import android.text.Html; import com.android.contacts.detail.ContactDetailDisplayUtils; -import com.android.contacts.test.NeededForTesting; +import com.android.contacts.common.test.NeededForTesting; import java.util.ArrayList; import java.util.Collections; diff --git a/src/com/android/contacts/vcard/ImportVCardActivity.java b/src/com/android/contacts/vcard/ImportVCardActivity.java index 9af2d527c..a741ba32c 100644 --- a/src/com/android/contacts/vcard/ImportVCardActivity.java +++ b/src/com/android/contacts/vcard/ImportVCardActivity.java @@ -49,7 +49,7 @@ import android.widget.Toast; import com.android.contacts.ContactsActivity; import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.util.AccountSelectionUtil; import com.android.vcard.VCardEntryCounter; import com.android.vcard.VCardParser; diff --git a/src/com/android/contacts/vcard/NfcImportVCardActivity.java b/src/com/android/contacts/vcard/NfcImportVCardActivity.java index 035be607a..c181dfa82 100644 --- a/src/com/android/contacts/vcard/NfcImportVCardActivity.java +++ b/src/com/android/contacts/vcard/NfcImportVCardActivity.java @@ -33,7 +33,7 @@ import android.util.Log; import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.vcard.VCardEntry; import com.android.vcard.VCardEntryCounter; import com.android.vcard.VCardParser; diff --git a/src/com/android/contacts/vcard/SelectAccountActivity.java b/src/com/android/contacts/vcard/SelectAccountActivity.java index 0e9c5a851..918524476 100644 --- a/src/com/android/contacts/vcard/SelectAccountActivity.java +++ b/src/com/android/contacts/vcard/SelectAccountActivity.java @@ -24,7 +24,7 @@ import android.util.Log; import com.android.contacts.ContactsActivity; import com.android.contacts.R; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.util.AccountSelectionUtil; import java.util.List; diff --git a/src/com/android/contacts/widget/CompositeListAdapter.java b/src/com/android/contacts/widget/CompositeListAdapter.java index 34c8fa036..d83246aa2 100644 --- a/src/com/android/contacts/widget/CompositeListAdapter.java +++ b/src/com/android/contacts/widget/CompositeListAdapter.java @@ -21,7 +21,7 @@ import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListAdapter; -import com.android.contacts.test.NeededForTesting; +import com.android.contacts.common.test.NeededForTesting; import com.google.common.annotations.VisibleForTesting; /** |