blob: 81450bc2e8b6d6ab2c2f2ef13ef9637beaa54661 [file] [log] [blame]
Yorke Lee2644d942013-10-28 11:05:43 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Gary Mai69c182a2016-12-05 13:07:03 -080017package com.android.contacts.model.dataitem;
Yorke Lee2644d942013-10-28 11:05:43 -070018
19import android.content.ContentValues;
20import android.content.Context;
21import android.provider.ContactsContract.CommonDataKinds.Email;
22import android.provider.ContactsContract.CommonDataKinds.Event;
23import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
24import android.provider.ContactsContract.CommonDataKinds.Identity;
25import android.provider.ContactsContract.CommonDataKinds.Im;
26import android.provider.ContactsContract.CommonDataKinds.Nickname;
27import android.provider.ContactsContract.CommonDataKinds.Note;
28import android.provider.ContactsContract.CommonDataKinds.Organization;
29import android.provider.ContactsContract.CommonDataKinds.Phone;
30import android.provider.ContactsContract.CommonDataKinds.Photo;
31import android.provider.ContactsContract.CommonDataKinds.Relation;
32import android.provider.ContactsContract.CommonDataKinds.SipAddress;
33import android.provider.ContactsContract.CommonDataKinds.StructuredName;
34import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
35import android.provider.ContactsContract.CommonDataKinds.Website;
36import android.provider.ContactsContract.Contacts.Data;
Paul Soulos8684f742014-06-23 11:24:17 -070037import android.provider.ContactsContract.Contacts.Entity;
Yorke Lee2644d942013-10-28 11:05:43 -070038
Gary Mai0a49afa2016-12-05 15:53:58 -080039import com.android.contacts.Collapser;
40import com.android.contacts.MoreContactUtils;
Gary Mai69c182a2016-12-05 13:07:03 -080041import com.android.contacts.model.RawContactModifier;
Yorke Lee2644d942013-10-28 11:05:43 -070042
43/**
44 * This is the base class for data items, which represents a row from the Data table.
45 */
Paul Soulos9e795d32014-06-30 14:32:53 +000046public class DataItem implements Collapser.Collapsible<DataItem> {
Yorke Lee2644d942013-10-28 11:05:43 -070047
48 private final ContentValues mContentValues;
Paul Soulosa69518c2014-07-28 14:12:23 -070049 protected DataKind mKind;
Yorke Lee2644d942013-10-28 11:05:43 -070050
51 protected DataItem(ContentValues values) {
52 mContentValues = values;
53 }
54
55 /**
56 * Factory for creating subclasses of DataItem objects based on the mimetype in the
57 * content values. Raw contact is the raw contact that this data item is associated with.
58 */
59 public static DataItem createFrom(ContentValues values) {
60 final String mimeType = values.getAsString(Data.MIMETYPE);
61 if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
62 return new GroupMembershipDataItem(values);
63 } else if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
64 return new StructuredNameDataItem(values);
65 } else if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
66 return new PhoneDataItem(values);
67 } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
68 return new EmailDataItem(values);
69 } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType)) {
70 return new StructuredPostalDataItem(values);
71 } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType)) {
72 return new ImDataItem(values);
73 } else if (Organization.CONTENT_ITEM_TYPE.equals(mimeType)) {
74 return new OrganizationDataItem(values);
75 } else if (Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) {
76 return new NicknameDataItem(values);
77 } else if (Note.CONTENT_ITEM_TYPE.equals(mimeType)) {
78 return new NoteDataItem(values);
79 } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType)) {
80 return new WebsiteDataItem(values);
81 } else if (SipAddress.CONTENT_ITEM_TYPE.equals(mimeType)) {
82 return new SipAddressDataItem(values);
83 } else if (Event.CONTENT_ITEM_TYPE.equals(mimeType)) {
84 return new EventDataItem(values);
85 } else if (Relation.CONTENT_ITEM_TYPE.equals(mimeType)) {
86 return new RelationDataItem(values);
87 } else if (Identity.CONTENT_ITEM_TYPE.equals(mimeType)) {
88 return new IdentityDataItem(values);
89 } else if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
90 return new PhotoDataItem(values);
yaolu1bd88262016-08-18 10:29:12 -070091 } else if (CustomDataItem.MIMETYPE_CUSTOM_FIELD.equals(mimeType)) {
92 return new CustomDataItem(values);
Yorke Lee2644d942013-10-28 11:05:43 -070093 }
94
95 // generic
96 return new DataItem(values);
97 }
98
99 public ContentValues getContentValues() {
100 return mContentValues;
101 }
102
103 public void setRawContactId(long rawContactId) {
104 mContentValues.put(Data.RAW_CONTACT_ID, rawContactId);
105 }
106
Paul Soulos6e06dd12014-06-25 14:14:20 -0700107 public Long getRawContactId() {
108 return mContentValues.getAsLong(Data.RAW_CONTACT_ID);
109 }
110
Yorke Lee2644d942013-10-28 11:05:43 -0700111 /**
112 * Returns the data id.
113 */
114 public long getId() {
115 return mContentValues.getAsLong(Data._ID);
116 }
117
118 /**
119 * Returns the mimetype of the data.
120 */
121 public String getMimeType() {
122 return mContentValues.getAsString(Data.MIMETYPE);
123 }
124
125 public void setMimeType(String mimeType) {
126 mContentValues.put(Data.MIMETYPE, mimeType);
127 }
128
129 public boolean isPrimary() {
130 Integer primary = mContentValues.getAsInteger(Data.IS_PRIMARY);
131 return primary != null && primary != 0;
132 }
133
134 public boolean isSuperPrimary() {
135 Integer superPrimary = mContentValues.getAsInteger(Data.IS_SUPER_PRIMARY);
136 return superPrimary != null && superPrimary != 0;
137 }
138
139 public boolean hasKindTypeColumn(DataKind kind) {
140 final String key = kind.typeColumn;
141 return key != null && mContentValues.containsKey(key) &&
142 mContentValues.getAsInteger(key) != null;
143 }
144
145 public int getKindTypeColumn(DataKind kind) {
146 final String key = kind.typeColumn;
147 return mContentValues.getAsInteger(key);
148 }
149
150 /**
Tyler Gunn001d9742015-12-18 13:57:02 -0800151 * Indicates the carrier presence value for the current {@link DataItem}.
152 *
153 * @return {@link Data#CARRIER_PRESENCE_VT_CAPABLE} if the {@link DataItem} supports carrier
154 * video calling, {@code 0} otherwise.
155 */
156 public int getCarrierPresence() {
Tyler Gunn166962a2016-04-25 08:54:29 -0700157 final Integer value = mContentValues.getAsInteger(Data.CARRIER_PRESENCE);
158 return value != null ? value.intValue() : 0;
Tyler Gunn001d9742015-12-18 13:57:02 -0800159 }
160
161 /**
Yorke Lee2644d942013-10-28 11:05:43 -0700162 * This builds the data string depending on the type of data item by using the generic
163 * DataKind object underneath.
164 */
165 public String buildDataString(Context context, DataKind kind) {
166 if (kind.actionBody == null) {
167 return null;
168 }
169 CharSequence actionBody = kind.actionBody.inflateUsing(context, mContentValues);
170 return actionBody == null ? null : actionBody.toString();
171 }
172
173 /**
174 * This builds the data string(intended for display) depending on the type of data item. It
175 * returns the same value as {@link #buildDataString} by default, but certain data items can
176 * override it to provide their version of formatted data strings.
177 *
178 * @return Data string representing the data item, possibly formatted for display
179 */
180 public String buildDataStringForDisplay(Context context, DataKind kind) {
181 return buildDataString(context, kind);
182 }
Paul Soulos8684f742014-06-23 11:24:17 -0700183
Paul Soulos9e795d32014-06-30 14:32:53 +0000184 public void setDataKind(DataKind kind) {
185 mKind = kind;
186 }
187
188 public DataKind getDataKind() {
189 return mKind;
190 }
191
Paul Soulos82d23912014-06-24 11:32:35 -0700192 public Integer getTimesUsed() {
193 return mContentValues.getAsInteger(Entity.TIMES_USED);
Paul Soulos8684f742014-06-23 11:24:17 -0700194 }
195
Paul Soulos82d23912014-06-24 11:32:35 -0700196 public Long getLastTimeUsed() {
197 return mContentValues.getAsLong(Entity.LAST_TIME_USED);
Paul Soulos8684f742014-06-23 11:24:17 -0700198 }
Paul Soulos9e795d32014-06-30 14:32:53 +0000199
200 @Override
201 public void collapseWith(DataItem that) {
202 DataKind thisKind = getDataKind();
203 DataKind thatKind = that.getDataKind();
Paul Soulosa69518c2014-07-28 14:12:23 -0700204 // If this does not have a type and that does, or if that's type is higher precedence,
205 // use that's type
Paul Soulos9e795d32014-06-30 14:32:53 +0000206 if ((!hasKindTypeColumn(thisKind) && that.hasKindTypeColumn(thatKind)) ||
Paul Soulos91740d82014-07-02 14:55:17 -0400207 that.hasKindTypeColumn(thatKind) &&
Paul Soulos9e795d32014-06-30 14:32:53 +0000208 RawContactModifier.getTypePrecedence(thisKind, getKindTypeColumn(thisKind))
209 >
210 RawContactModifier.getTypePrecedence(thatKind, that.getKindTypeColumn(thatKind))) {
211 mContentValues.put(thatKind.typeColumn, that.getKindTypeColumn(thatKind));
212 mKind = thatKind;
213 }
214
215 // Choose the max of the maxLines and maxLabelLines values.
216 mKind.maxLinesForDisplay = Math.max(thisKind.maxLinesForDisplay,
217 thatKind.maxLinesForDisplay);
218
219 // If any of the collapsed entries are super primary make the whole thing super primary.
220 if (isSuperPrimary() || that.isSuperPrimary()) {
Paul Soulos856820d2014-07-18 14:41:34 -0700221 mContentValues.put(Data.IS_SUPER_PRIMARY, 1);
222 mContentValues.put(Data.IS_PRIMARY, 1);
Paul Soulos9e795d32014-06-30 14:32:53 +0000223 }
224
225 // If any of the collapsed entries are primary make the whole thing primary.
226 if (isPrimary() || that.isPrimary()) {
Paul Soulos856820d2014-07-18 14:41:34 -0700227 mContentValues.put(Data.IS_PRIMARY, 1);
Paul Soulos9e795d32014-06-30 14:32:53 +0000228 }
229
230 // Add up the times used
231 mContentValues.put(Entity.TIMES_USED, (getTimesUsed() == null ? 0 : getTimesUsed()) +
232 (that.getTimesUsed() == null ? 0 : that.getTimesUsed()));
233
234 // Use the most recent time
235 mContentValues.put(Entity.LAST_TIME_USED,
236 Math.max(getLastTimeUsed() == null ? 0 : getLastTimeUsed(),
237 that.getLastTimeUsed() == null ? 0 : that.getLastTimeUsed()));
238 }
239
240 @Override
241 public boolean shouldCollapseWith(DataItem t, Context context) {
242 if (mKind == null || t.getDataKind() == null) {
243 return false;
244 }
245 return MoreContactUtils.shouldCollapse(getMimeType(), buildDataString(context, mKind),
246 t.getMimeType(), t.buildDataString(context, t.getDataKind()));
247 }
Yorke Lee2644d942013-10-28 11:05:43 -0700248}