blob: 37e60f20b21c4b70f770b26f9554fd78482c9a45 [file] [log] [blame]
Mindy Pereira3ce64e72012-01-13 14:29:45 -08001/**
2 * Copyright (c) 2012, Google Inc.
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
17package com.android.mail.providers;
18
Andy Huang3233bff2012-03-20 19:38:45 -070019import android.content.AsyncQueryHandler;
20import android.content.ContentValues;
Mindy Pereira3ce64e72012-01-13 14:29:45 -080021import android.database.Cursor;
Mindy Pereiracfb7f332012-02-28 10:23:43 -080022import android.net.Uri;
Mindy Pereira3ce64e72012-01-13 14:29:45 -080023import android.os.Parcel;
24import android.os.Parcelable;
Andy Huange623a0f2012-07-12 15:01:23 -070025import android.provider.BaseColumns;
Andy Huang014ea4c2012-09-25 14:50:54 -070026import android.text.Html;
27import android.text.SpannedString;
Mindy Pereiracfb7f332012-02-28 10:23:43 -080028import android.text.TextUtils;
mindyp5ed63112012-09-17 17:31:45 -070029import android.text.util.Rfc822Token;
30import android.text.util.Rfc822Tokenizer;
Mindy Pereira3ce64e72012-01-13 14:29:45 -080031
Marc Blank26846d82012-03-22 18:12:54 -070032import com.android.mail.providers.UIProvider.MessageColumns;
33import com.android.mail.utils.Utils;
Andy Huangcd5c5ee2012-08-12 19:03:51 -070034import com.google.common.base.Objects;
Marc Blank26846d82012-03-22 18:12:54 -070035
Andy Huang9ab47b12012-03-27 19:39:43 -070036import java.util.Collections;
Andy Huang5a929072012-03-23 20:17:10 -070037import java.util.List;
Paul Westbrook41dca182012-08-07 10:43:42 -070038import java.util.regex.Pattern;
Andy Huang5a929072012-03-23 20:17:10 -070039
Mindy Pereira3ce64e72012-01-13 14:29:45 -080040
41public class Message implements Parcelable {
Andy Huange623a0f2012-07-12 15:01:23 -070042 /**
Paul Westbrook41dca182012-08-07 10:43:42 -070043 * Regex pattern used to look for any inline images in message bodies, including Gmail-hosted
44 * relative-URL images, Gmail emoticons, and any external inline images (although we usually
45 * count on the server to detect external images).
46 */
47 private static Pattern INLINE_IMAGE_PATTERN = Pattern.compile("<img\\s+[^>]*src=",
48 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
49
50 /**
Andy Huange623a0f2012-07-12 15:01:23 -070051 * @see BaseColumns#_ID
52 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -080053 public long id;
Andy Huange623a0f2012-07-12 15:01:23 -070054 /**
55 * @see UIProvider.MessageColumns#SERVER_ID
56 */
Andy Huangd47877e2012-08-09 19:31:24 -070057 public String serverId;
Andy Huange623a0f2012-07-12 15:01:23 -070058 /**
59 * @see UIProvider.MessageColumns#URI
60 */
Mindy Pereiracfb7f332012-02-28 10:23:43 -080061 public Uri uri;
Andy Huange623a0f2012-07-12 15:01:23 -070062 /**
63 * @see UIProvider.MessageColumns#CONVERSATION_ID
64 */
Andy Huangdaa06ab2012-07-24 10:46:44 -070065 public Uri conversationUri;
Andy Huange623a0f2012-07-12 15:01:23 -070066 /**
67 * @see UIProvider.MessageColumns#SUBJECT
68 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -080069 public String subject;
Andy Huange623a0f2012-07-12 15:01:23 -070070 /**
71 * @see UIProvider.MessageColumns#SNIPPET
72 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -080073 public String snippet;
Andy Huange623a0f2012-07-12 15:01:23 -070074 /**
75 * @see UIProvider.MessageColumns#FROM
76 */
Scott Kennedy8960f0a2012-11-07 15:35:50 -080077 private String mFrom;
Andy Huange623a0f2012-07-12 15:01:23 -070078 /**
79 * @see UIProvider.MessageColumns#TO
80 */
Scott Kennedy8960f0a2012-11-07 15:35:50 -080081 private String mTo;
Andy Huange623a0f2012-07-12 15:01:23 -070082 /**
83 * @see UIProvider.MessageColumns#CC
84 */
Scott Kennedy8960f0a2012-11-07 15:35:50 -080085 private String mCc;
Andy Huange623a0f2012-07-12 15:01:23 -070086 /**
87 * @see UIProvider.MessageColumns#BCC
88 */
Scott Kennedy8960f0a2012-11-07 15:35:50 -080089 private String mBcc;
Andy Huange623a0f2012-07-12 15:01:23 -070090 /**
91 * @see UIProvider.MessageColumns#REPLY_TO
92 */
Scott Kennedy8960f0a2012-11-07 15:35:50 -080093 private String mReplyTo;
Andy Huange623a0f2012-07-12 15:01:23 -070094 /**
95 * @see UIProvider.MessageColumns#DATE_RECEIVED_MS
96 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -080097 public long dateReceivedMs;
Andy Huange623a0f2012-07-12 15:01:23 -070098 /**
99 * @see UIProvider.MessageColumns#BODY_HTML
100 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800101 public String bodyHtml;
Andy Huange623a0f2012-07-12 15:01:23 -0700102 /**
103 * @see UIProvider.MessageColumns#BODY_TEXT
104 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800105 public String bodyText;
Andy Huange623a0f2012-07-12 15:01:23 -0700106 /**
107 * @see UIProvider.MessageColumns#EMBEDS_EXTERNAL_RESOURCES
108 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800109 public boolean embedsExternalResources;
Andy Huange623a0f2012-07-12 15:01:23 -0700110 /**
111 * @see UIProvider.MessageColumns#REF_MESSAGE_ID
112 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800113 public String refMessageId;
Andy Huange623a0f2012-07-12 15:01:23 -0700114 /**
115 * @see UIProvider.MessageColumns#DRAFT_TYPE
116 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800117 public int draftType;
Andy Huange623a0f2012-07-12 15:01:23 -0700118 /**
119 * @see UIProvider.MessageColumns#APPEND_REF_MESSAGE_CONTENT
120 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800121 public boolean appendRefMessageContent;
Andy Huange623a0f2012-07-12 15:01:23 -0700122 /**
123 * @see UIProvider.MessageColumns#HAS_ATTACHMENTS
124 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800125 public boolean hasAttachments;
Andy Huange623a0f2012-07-12 15:01:23 -0700126 /**
127 * @see UIProvider.MessageColumns#ATTACHMENT_LIST_URI
128 */
Mindy Pereiracfb7f332012-02-28 10:23:43 -0800129 public Uri attachmentListUri;
Andy Huange623a0f2012-07-12 15:01:23 -0700130 /**
131 * @see UIProvider.MessageColumns#MESSAGE_FLAGS
132 */
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800133 public long messageFlags;
Andy Huange623a0f2012-07-12 15:01:23 -0700134 /**
135 * @see UIProvider.MessageColumns#SAVE_MESSAGE_URI
136 */
Paul Westbrook72e2ea82012-10-22 16:25:22 -0700137 @Deprecated
Mindy Pereira7ed1c112012-01-18 10:59:25 -0800138 public String saveUri;
Andy Huange623a0f2012-07-12 15:01:23 -0700139 /**
140 * @see UIProvider.MessageColumns#SEND_MESSAGE_URI
141 */
Paul Westbrook72e2ea82012-10-22 16:25:22 -0700142 @Deprecated
Mindy Pereira7ed1c112012-01-18 10:59:25 -0800143 public String sendUri;
Andy Huange623a0f2012-07-12 15:01:23 -0700144 /**
145 * @see UIProvider.MessageColumns#ALWAYS_SHOW_IMAGES
146 */
Paul Westbrook104f7292012-02-28 16:07:07 -0800147 public boolean alwaysShowImages;
Andy Huange623a0f2012-07-12 15:01:23 -0700148 /**
149 * @see UIProvider.MessageColumns#READ
150 */
Andy Huangd8e249e2012-03-21 17:01:37 -0700151 public boolean read;
Andy Huange623a0f2012-07-12 15:01:23 -0700152 /**
153 * @see UIProvider.MessageColumns#STARRED
154 */
Andy Huangd8e249e2012-03-21 17:01:37 -0700155 public boolean starred;
Andy Huange623a0f2012-07-12 15:01:23 -0700156 /**
157 * @see UIProvider.MessageColumns#QUOTE_START_POS
158 */
Mindy Pereira4dbbf9f2012-03-20 15:48:26 -0700159 public int quotedTextOffset;
Andy Huange623a0f2012-07-12 15:01:23 -0700160 /**
161 * @see UIProvider.MessageColumns#ATTACHMENTS
Andy Huang6766b6e2012-09-28 12:43:52 -0700162 *<p>
163 * N.B. this value is NOT immutable and may change during conversation view render.
Andy Huange623a0f2012-07-12 15:01:23 -0700164 */
Andy Huang5a929072012-03-23 20:17:10 -0700165 public String attachmentsJson;
Andy Huange623a0f2012-07-12 15:01:23 -0700166 /**
167 * @see UIProvider.MessageColumns#MESSAGE_ACCOUNT_URI
168 */
Mindy Pereira62de1b12012-04-06 12:17:56 -0700169 public Uri accountUri;
Andy Huange623a0f2012-07-12 15:01:23 -0700170 /**
171 * @see UIProvider.MessageColumns#EVENT_INTENT_URI
172 */
Marc Blank3842af92012-04-27 09:06:09 -0700173 public Uri eventIntentUri;
Andrew Sappersteind5b369b2012-07-13 12:38:46 -0700174 /**
175 * @see UIProvider.MessageColumns#SPAM_WARNING_STRING
176 */
Andrew Sapperstein3b08c512012-07-11 16:51:07 -0700177 public String spamWarningString;
Andrew Sappersteind5b369b2012-07-13 12:38:46 -0700178 /**
179 * @see UIProvider.MessageColumns#SPAM_WARNING_LEVEL
180 */
Andrew Sapperstein3b08c512012-07-11 16:51:07 -0700181 public int spamWarningLevel;
Andrew Sappersteind5b369b2012-07-13 12:38:46 -0700182 /**
183 * @see UIProvider.MessageColumns#SPAM_WARNING_LINK_TYPE
184 */
Andrew Sapperstein3b08c512012-07-11 16:51:07 -0700185 public int spamLinkType;
Andrew Sappersteind5b369b2012-07-13 12:38:46 -0700186 /**
187 * @see UIProvider.MessageColumns#VIA_DOMAIN
188 */
189 public String viaDomain;
Andy Huang47aa9c92012-07-31 15:37:21 -0700190 /**
191 * @see UIProvider.MessageColumns#IS_SENDING
192 */
193 public boolean isSending;
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800194
Andrew Sappersteind5b369b2012-07-13 12:38:46 -0700195 private transient String[] mFromAddresses = null;
Andy Huang5a929072012-03-23 20:17:10 -0700196 private transient String[] mToAddresses = null;
197 private transient String[] mCcAddresses = null;
198 private transient String[] mBccAddresses = null;
199 private transient String[] mReplyToAddresses = null;
200
201 private transient List<Attachment> mAttachments = null;
mindyp845f87e2012-09-24 15:14:49 -0700202
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800203 @Override
204 public int describeContents() {
205 return 0;
206 }
207
208 @Override
Andy Huang3233bff2012-03-20 19:38:45 -0700209 public boolean equals(Object o) {
Andy Huangcd5c5ee2012-08-12 19:03:51 -0700210 return this == o || (o != null && o instanceof Message
211 && Objects.equal(uri, ((Message) o).uri));
Andy Huang3233bff2012-03-20 19:38:45 -0700212 }
213
214 @Override
215 public int hashCode() {
216 return uri == null ? 0 : uri.hashCode();
217 }
218
219 @Override
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800220 public void writeToParcel(Parcel dest, int flags) {
221 dest.writeLong(id);
Andy Huangd47877e2012-08-09 19:31:24 -0700222 dest.writeString(serverId);
Mindy Pereiracfb7f332012-02-28 10:23:43 -0800223 dest.writeParcelable(uri, 0);
Andy Huangdaa06ab2012-07-24 10:46:44 -0700224 dest.writeParcelable(conversationUri, 0);
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800225 dest.writeString(subject);
226 dest.writeString(snippet);
Scott Kennedy8960f0a2012-11-07 15:35:50 -0800227 dest.writeString(mFrom);
228 dest.writeString(mTo);
229 dest.writeString(mCc);
230 dest.writeString(mBcc);
231 dest.writeString(mReplyTo);
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800232 dest.writeLong(dateReceivedMs);
233 dest.writeString(bodyHtml);
234 dest.writeString(bodyText);
235 dest.writeInt(embedsExternalResources ? 1 : 0);
236 dest.writeString(refMessageId);
237 dest.writeInt(draftType);
238 dest.writeInt(appendRefMessageContent ? 1 : 0);
239 dest.writeInt(hasAttachments ? 1 : 0);
Mindy Pereiracfb7f332012-02-28 10:23:43 -0800240 dest.writeParcelable(attachmentListUri, 0);
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800241 dest.writeLong(messageFlags);
Mindy Pereira7ed1c112012-01-18 10:59:25 -0800242 dest.writeString(saveUri);
243 dest.writeString(sendUri);
Paul Westbrook104f7292012-02-28 16:07:07 -0800244 dest.writeInt(alwaysShowImages ? 1 : 0);
Mindy Pereira4dbbf9f2012-03-20 15:48:26 -0700245 dest.writeInt(quotedTextOffset);
Mindy Pereira2421dc82012-03-27 13:32:31 -0700246 dest.writeString(attachmentsJson);
Mindy Pereira62de1b12012-04-06 12:17:56 -0700247 dest.writeParcelable(accountUri, 0);
Marc Blank3842af92012-04-27 09:06:09 -0700248 dest.writeParcelable(eventIntentUri, 0);
Andrew Sapperstein3b08c512012-07-11 16:51:07 -0700249 dest.writeString(spamWarningString);
250 dest.writeInt(spamWarningLevel);
251 dest.writeInt(spamLinkType);
Andrew Sappersteind5b369b2012-07-13 12:38:46 -0700252 dest.writeString(viaDomain);
Andy Huang47aa9c92012-07-31 15:37:21 -0700253 dest.writeInt(isSending ? 1 : 0);
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800254 }
255
256 private Message(Parcel in) {
257 id = in.readLong();
Andy Huangd47877e2012-08-09 19:31:24 -0700258 serverId = in.readString();
Mindy Pereiracfb7f332012-02-28 10:23:43 -0800259 uri = in.readParcelable(null);
Andy Huangdaa06ab2012-07-24 10:46:44 -0700260 conversationUri = in.readParcelable(null);
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800261 subject = in.readString();
262 snippet = in.readString();
Scott Kennedy8960f0a2012-11-07 15:35:50 -0800263 mFrom = in.readString();
264 mTo = in.readString();
265 mCc = in.readString();
266 mBcc = in.readString();
267 mReplyTo = in.readString();
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800268 dateReceivedMs = in.readLong();
269 bodyHtml = in.readString();
270 bodyText = in.readString();
271 embedsExternalResources = in.readInt() != 0;
272 refMessageId = in.readString();
273 draftType = in.readInt();
274 appendRefMessageContent = in.readInt() != 0;
275 hasAttachments = in.readInt() != 0;
Mindy Pereiracfb7f332012-02-28 10:23:43 -0800276 attachmentListUri = in.readParcelable(null);
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800277 messageFlags = in.readLong();
Mindy Pereira7ed1c112012-01-18 10:59:25 -0800278 saveUri = in.readString();
279 sendUri = in.readString();
Paul Westbrook104f7292012-02-28 16:07:07 -0800280 alwaysShowImages = in.readInt() != 0;
Mindy Pereira4dbbf9f2012-03-20 15:48:26 -0700281 quotedTextOffset = in.readInt();
Mindy Pereira2421dc82012-03-27 13:32:31 -0700282 attachmentsJson = in.readString();
Mindy Pereira62de1b12012-04-06 12:17:56 -0700283 accountUri = in.readParcelable(null);
Marc Blank3842af92012-04-27 09:06:09 -0700284 eventIntentUri = in.readParcelable(null);
Andrew Sapperstein3b08c512012-07-11 16:51:07 -0700285 spamWarningString = in.readString();
286 spamWarningLevel = in.readInt();
287 spamLinkType = in.readInt();
Andrew Sappersteind5b369b2012-07-13 12:38:46 -0700288 viaDomain = in.readString();
Andy Huang47aa9c92012-07-31 15:37:21 -0700289 isSending = in.readInt() != 0;
Paul Westbrook104f7292012-02-28 16:07:07 -0800290 }
291
292 public Message() {
293
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800294 }
295
296 @Override
297 public String toString() {
298 return "[message id=" + id + "]";
299 }
300
301 public static final Creator<Message> CREATOR = new Creator<Message>() {
302
303 @Override
304 public Message createFromParcel(Parcel source) {
305 return new Message(source);
306 }
307
308 @Override
309 public Message[] newArray(int size) {
310 return new Message[size];
311 }
312
313 };
314
Mindy Pereiraa831b2f2012-02-23 19:24:40 -0800315 public Message(Cursor cursor) {
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800316 if (cursor != null) {
317 id = cursor.getLong(UIProvider.MESSAGE_ID_COLUMN);
Andy Huangd47877e2012-08-09 19:31:24 -0700318 serverId = cursor.getString(UIProvider.MESSAGE_SERVER_ID_COLUMN);
Andy Huangdaa06ab2012-07-24 10:46:44 -0700319 final String messageUriStr = cursor.getString(UIProvider.MESSAGE_URI_COLUMN);
320 uri = !TextUtils.isEmpty(messageUriStr) ? Uri.parse(messageUriStr) : null;
321 final String convUriStr = cursor.getString(UIProvider.MESSAGE_CONVERSATION_URI_COLUMN);
322 conversationUri = !TextUtils.isEmpty(convUriStr) ? Uri.parse(convUriStr) : null;
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800323 subject = cursor.getString(UIProvider.MESSAGE_SUBJECT_COLUMN);
324 snippet = cursor.getString(UIProvider.MESSAGE_SNIPPET_COLUMN);
Scott Kennedy8960f0a2012-11-07 15:35:50 -0800325 mFrom = cursor.getString(UIProvider.MESSAGE_FROM_COLUMN);
326 mTo = cursor.getString(UIProvider.MESSAGE_TO_COLUMN);
327 mCc = cursor.getString(UIProvider.MESSAGE_CC_COLUMN);
328 mBcc = cursor.getString(UIProvider.MESSAGE_BCC_COLUMN);
329 mReplyTo = cursor.getString(UIProvider.MESSAGE_REPLY_TO_COLUMN);
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800330 dateReceivedMs = cursor.getLong(UIProvider.MESSAGE_DATE_RECEIVED_MS_COLUMN);
331 bodyHtml = cursor.getString(UIProvider.MESSAGE_BODY_HTML_COLUMN);
332 bodyText = cursor.getString(UIProvider.MESSAGE_BODY_TEXT_COLUMN);
333 embedsExternalResources = cursor
334 .getInt(UIProvider.MESSAGE_EMBEDS_EXTERNAL_RESOURCES_COLUMN) != 0;
335 refMessageId = cursor.getString(UIProvider.MESSAGE_REF_MESSAGE_ID_COLUMN);
336 draftType = cursor.getInt(UIProvider.MESSAGE_DRAFT_TYPE_COLUMN);
337 appendRefMessageContent = cursor
338 .getInt(UIProvider.MESSAGE_APPEND_REF_MESSAGE_CONTENT_COLUMN) != 0;
339 hasAttachments = cursor.getInt(UIProvider.MESSAGE_HAS_ATTACHMENTS_COLUMN) != 0;
Mindy Pereira7bb27252012-03-07 10:17:09 -0800340 final String attachmentsUri = cursor
341 .getString(UIProvider.MESSAGE_ATTACHMENT_LIST_URI_COLUMN);
342 attachmentListUri = hasAttachments && !TextUtils.isEmpty(attachmentsUri) ? Uri
343 .parse(attachmentsUri) : null;
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800344 messageFlags = cursor.getLong(UIProvider.MESSAGE_FLAGS_COLUMN);
Mindy Pereira7ed1c112012-01-18 10:59:25 -0800345 saveUri = cursor
346 .getString(UIProvider.MESSAGE_SAVE_URI_COLUMN);
347 sendUri = cursor
348 .getString(UIProvider.MESSAGE_SEND_URI_COLUMN);
Andy Huangd8e249e2012-03-21 17:01:37 -0700349 alwaysShowImages = cursor.getInt(UIProvider.MESSAGE_ALWAYS_SHOW_IMAGES_COLUMN) != 0;
350 read = cursor.getInt(UIProvider.MESSAGE_READ_COLUMN) != 0;
351 starred = cursor.getInt(UIProvider.MESSAGE_STARRED_COLUMN) != 0;
Mindy Pereira4dbbf9f2012-03-20 15:48:26 -0700352 quotedTextOffset = cursor.getInt(UIProvider.QUOTED_TEXT_OFFSET_COLUMN);
Andy Huang5a929072012-03-23 20:17:10 -0700353 attachmentsJson = cursor.getString(UIProvider.MESSAGE_ATTACHMENTS_COLUMN);
Mindy Pereira62de1b12012-04-06 12:17:56 -0700354 String accountUriString = cursor.getString(UIProvider.MESSAGE_ACCOUNT_URI_COLUMN);
355 accountUri = !TextUtils.isEmpty(accountUriString) ? Uri.parse(accountUriString) : null;
Marc Blank3842af92012-04-27 09:06:09 -0700356 eventIntentUri =
357 Utils.getValidUri(cursor.getString(UIProvider.MESSAGE_EVENT_INTENT_COLUMN));
Andrew Sapperstein3b08c512012-07-11 16:51:07 -0700358 spamWarningString =
359 cursor.getString(UIProvider.MESSAGE_SPAM_WARNING_STRING_ID_COLUMN);
360 spamWarningLevel = cursor.getInt(UIProvider.MESSAGE_SPAM_WARNING_LEVEL_COLUMN);
361 spamLinkType = cursor.getInt(UIProvider.MESSAGE_SPAM_WARNING_LINK_TYPE_COLUMN);
Andrew Sappersteind5b369b2012-07-13 12:38:46 -0700362 viaDomain = cursor.getString(UIProvider.MESSAGE_VIA_DOMAIN_COLUMN);
Andy Huang47aa9c92012-07-31 15:37:21 -0700363 isSending = cursor.getInt(UIProvider.MESSAGE_IS_SENDING_COLUMN) != 0;
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800364 }
365 }
Andy Huang0a220472012-03-14 17:36:55 -0700366
Andy Huanga71f1f32012-04-24 20:17:22 -0700367 public boolean isFlaggedReplied() {
368 return (messageFlags & UIProvider.MessageFlags.REPLIED) ==
369 UIProvider.MessageFlags.REPLIED;
370 }
371
372 public boolean isFlaggedForwarded() {
373 return (messageFlags & UIProvider.MessageFlags.FORWARDED) ==
374 UIProvider.MessageFlags.FORWARDED;
375 }
376
377 public boolean isFlaggedCalendarInvite() {
378 return (messageFlags & UIProvider.MessageFlags.CALENDAR_INVITE) ==
379 UIProvider.MessageFlags.CALENDAR_INVITE;
380 }
381
Scott Kennedy8960f0a2012-11-07 15:35:50 -0800382 public String getFrom() {
383 return mFrom;
384 }
385
386 public synchronized void setFrom(final String from) {
387 mFrom = from;
388 mFromAddresses = null;
389 }
390
391 public String getTo() {
392 return mTo;
393 }
394
395 public synchronized void setTo(final String to) {
396 mTo = to;
397 mToAddresses = null;
398 }
399
400 public String getCc() {
401 return mCc;
402 }
403
404 public synchronized void setCc(final String cc) {
405 mCc = cc;
406 mCcAddresses = null;
407 }
408
409 public String getBcc() {
410 return mBcc;
411 }
412
413 public synchronized void setBcc(final String bcc) {
414 mBcc = bcc;
415 mBccAddresses = null;
416 }
417
418 public String getReplyTo() {
419 return mReplyTo;
420 }
421
422 public synchronized void setReplyTo(final String replyTo) {
423 mReplyTo = replyTo;
424 mReplyToAddresses = null;
425 }
426
Andrew Sappersteind5b369b2012-07-13 12:38:46 -0700427 public synchronized String[] getFromAddresses() {
428 if (mFromAddresses == null) {
Scott Kennedy8960f0a2012-11-07 15:35:50 -0800429 mFromAddresses = tokenizeAddresses(mFrom);
Andrew Sappersteind5b369b2012-07-13 12:38:46 -0700430 }
431 return mFromAddresses;
432 }
433
Paul Westbrookbb87b7f2012-03-20 16:20:07 -0700434 public synchronized String[] getToAddresses() {
435 if (mToAddresses == null) {
Scott Kennedy8960f0a2012-11-07 15:35:50 -0800436 mToAddresses = tokenizeAddresses(mTo);
Paul Westbrookbb87b7f2012-03-20 16:20:07 -0700437 }
438 return mToAddresses;
439 }
440
441 public synchronized String[] getCcAddresses() {
442 if (mCcAddresses == null) {
Scott Kennedy8960f0a2012-11-07 15:35:50 -0800443 mCcAddresses = tokenizeAddresses(mCc);
Paul Westbrookbb87b7f2012-03-20 16:20:07 -0700444 }
445 return mCcAddresses;
446 }
447
448 public synchronized String[] getBccAddresses() {
449 if (mBccAddresses == null) {
Scott Kennedy8960f0a2012-11-07 15:35:50 -0800450 mBccAddresses = tokenizeAddresses(mBcc);
Paul Westbrookbb87b7f2012-03-20 16:20:07 -0700451 }
452 return mBccAddresses;
453 }
454
455 public synchronized String[] getReplyToAddresses() {
456 if (mReplyToAddresses == null) {
Scott Kennedy8960f0a2012-11-07 15:35:50 -0800457 mReplyToAddresses = tokenizeAddresses(mReplyTo);
Paul Westbrookbb87b7f2012-03-20 16:20:07 -0700458 }
459 return mReplyToAddresses;
460 }
Andy Huang3233bff2012-03-20 19:38:45 -0700461
Paul Westbrook233f5622012-09-27 16:18:11 -0700462 public static String[] tokenizeAddresses(String addresses) {
mindyp5ed63112012-09-17 17:31:45 -0700463 if (TextUtils.isEmpty(addresses)) {
464 return new String[0];
465 }
mindyp845f87e2012-09-24 15:14:49 -0700466 Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(addresses);
mindyp5ed63112012-09-17 17:31:45 -0700467 String[] strings = new String[tokens.length];
468 for (int i = 0; i < tokens.length;i++) {
469 strings[i] = tokens[i].toString();
470 }
471 return strings;
472 }
Andy Huang6766b6e2012-09-28 12:43:52 -0700473
474 public List<Attachment> getAttachments() {
Andy Huang9ab47b12012-03-27 19:39:43 -0700475 if (mAttachments == null) {
476 if (attachmentsJson != null) {
477 mAttachments = Attachment.fromJSONArray(attachmentsJson);
478 } else {
479 mAttachments = Collections.emptyList();
480 }
Andy Huang5a929072012-03-23 20:17:10 -0700481 }
482 return mAttachments;
483 }
484
Andy Huang3233bff2012-03-20 19:38:45 -0700485 /**
486 * Returns whether a "Show Pictures" button should initially appear for this message. If the
487 * button is shown, the message must also block all non-local images in the body. Inversely, if
488 * the button is not shown, the message must show all images within (or else the user would be
489 * stuck with no images and no way to reveal them).
490 *
491 * @return true if a "Show Pictures" button should appear.
492 */
493 public boolean shouldShowImagePrompt() {
Paul Westbrook41dca182012-08-07 10:43:42 -0700494 return !alwaysShowImages && embedsExternalResources();
495 }
496
497 private boolean embedsExternalResources() {
498 return embedsExternalResources ||
499 (!TextUtils.isEmpty(bodyHtml) && INLINE_IMAGE_PATTERN.matcher(bodyHtml).find());
Andy Huang3233bff2012-03-20 19:38:45 -0700500 }
501
502 /**
503 * Helper method to command a provider to mark all messages from this sender with the
504 * {@link MessageColumns#ALWAYS_SHOW_IMAGES} flag set.
505 *
506 * @param handler a caller-provided handler to run the query on
507 * @param token (optional) token to identify the command to the handler
508 * @param cookie (optional) cookie to pass to the handler
509 */
510 public void markAlwaysShowImages(AsyncQueryHandler handler, int token, Object cookie) {
Andy Huang839ada22012-07-20 15:48:40 -0700511 alwaysShowImages = true;
512
Andy Huang3233bff2012-03-20 19:38:45 -0700513 final ContentValues values = new ContentValues(1);
514 values.put(UIProvider.MessageColumns.ALWAYS_SHOW_IMAGES, 1);
515
516 handler.startUpdate(token, cookie, uri, values, null, null);
517 }
518
Andy Huang014ea4c2012-09-25 14:50:54 -0700519 public String getBodyAsHtml() {
520 String body = "";
521 if (!TextUtils.isEmpty(bodyHtml)) {
522 body = bodyHtml;
523 } else if (!TextUtils.isEmpty(bodyText)) {
524 body = Html.toHtml(new SpannedString(bodyText));
525 }
526 return body;
527 }
528
Mindy Pereira3ce64e72012-01-13 14:29:45 -0800529}