UIProvider.java revision 9912eee82731d0cbf2c6cf35e62c8388c2a9ee79
1/*******************************************************************************
2 *      Copyright (C) 2011 Google Inc.
3 *      Licensed to The Android Open Source Project.
4 *
5 *      Licensed under the Apache License, Version 2.0 (the "License");
6 *      you may not use this file except in compliance with the License.
7 *      You may obtain a copy of the License at
8 *
9 *           http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *      Unless required by applicable law or agreed to in writing, software
12 *      distributed under the License is distributed on an "AS IS" BASIS,
13 *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *      See the License for the specific language governing permissions and
15 *      limitations under the License.
16 *******************************************************************************/
17
18package com.android.mail.providers;
19
20import android.content.Context;
21import android.provider.BaseColumns;
22import android.text.TextUtils;
23
24import com.android.common.contacts.DataUsageStatUpdater;
25
26import java.util.ArrayList;
27
28
29public class UIProvider {
30    public static final String EMAIL_SEPARATOR = "\n";
31    public static final long INVALID_CONVERSATION_ID = -1;
32    public static final long INVALID_MESSAGE_ID = -1;
33
34    /**
35     * Values for the current state of a Folder/Account; note that it's possible that more than one
36     * sync is in progress
37     */
38    public static final class SyncStatus {
39        // No sync in progress
40        public static final int NO_SYNC = 1<<0;
41        // A user-requested sync/refresh is in progress
42        public static final int USER_REFRESH = 1<<1;
43        // A user-requested query is in progress
44        public static final int USER_QUERY = 1<<2;
45        // A user request for additional results is in progress
46        public static final int USER_MORE_RESULTS = 1<<3;
47        // A background sync is in progress
48        public static final int BACKGROUND_SYNC = 1<<4;
49    }
50
51    /**
52     * Values for the result of the last attempted sync of a Folder/Account
53     */
54    public static final class LastSyncResult {
55        // The sync completed successfully
56        public static final int SUCCESS = 0;
57        // The sync wasn't completed due to a connection error
58        public static final int CONNECTION_ERROR = 1;
59        // The sync wasn't completed due to an authentication error
60        public static final int AUTH_ERROR = 2;
61        // The sync wasn't completed due to a security error
62        public static final int SECURITY_ERROR = 3;
63        // The sync wasn't completed due to a low memory condition
64        public static final int STORAGE_ERROR = 4;
65        // The sync wasn't completed due to an internal error/exception
66        public static final int INTERNAL_ERROR = 5;
67    }
68
69    // The actual content provider should define its own authority
70    public static final String AUTHORITY = "com.android.mail.providers";
71
72    public static final String ACCOUNT_LIST_TYPE =
73            "vnd.android.cursor.dir/vnd.com.android.mail.account";
74    public static final String ACCOUNT_TYPE =
75            "vnd.android.cursor.item/vnd.com.android.mail.account";
76
77    public static final String[] ACCOUNTS_PROJECTION = {
78            BaseColumns._ID,
79            AccountColumns.NAME,
80            AccountColumns.PROVIDER_VERSION,
81            AccountColumns.URI,
82            AccountColumns.CAPABILITIES,
83            AccountColumns.FOLDER_LIST_URI,
84            AccountColumns.SEARCH_URI,
85            AccountColumns.ACCOUNT_FROM_ADDRESSES_URI,
86            AccountColumns.SAVE_DRAFT_URI,
87            AccountColumns.SEND_MAIL_URI,
88            AccountColumns.EXPUNGE_MESSAGE_URI,
89            AccountColumns.UNDO_URI,
90            AccountColumns.SETTINGS_INTENT_URI,
91            AccountColumns.SYNC_STATUS
92    };
93
94    public static final int ACCOUNT_ID_COLUMN = 0;
95    public static final int ACCOUNT_NAME_COLUMN = 1;
96    public static final int ACCOUNT_PROVIDER_VERISON_COLUMN = 2;
97    public static final int ACCOUNT_URI_COLUMN = 3;
98    public static final int ACCOUNT_CAPABILITIES_COLUMN = 4;
99    public static final int ACCOUNT_FOLDER_LIST_URI_COLUMN = 5;
100    public static final int ACCOUNT_SEARCH_URI_COLUMN = 6;
101    public static final int ACCOUNT_FROM_ADDRESSES_URI_COLUMN = 7;
102    public static final int ACCOUNT_SAVE_DRAFT_URI_COLUMN = 8;
103    public static final int ACCOUNT_SEND_MESSAGE_URI_COLUMN = 9;
104    public static final int ACCOUNT_EXPUNGE_MESSAGE_URI_COLUMN = 10;
105    public static final int ACCOUNT_UNDO_URI_COLUMN = 11;
106    public static final int ACCOUNT_SETTINGS_INTENT_URI_COLUMN = 12;
107    public static final int ACCOUNT_SYNC_STATUS_COLUMN = 13;
108
109    public static final class AccountCapabilities {
110        /**
111         * Whether folders can be synchronized back to the server.
112         */
113        public static final int SYNCABLE_FOLDERS = 0x0001;
114        /**
115         * Whether the server allows reporting spam back.
116         */
117        public static final int REPORT_SPAM = 0x0002;
118        /**
119         * Whether the server supports a concept of Archive: removing mail from the Inbox but
120         * keeping it around.
121         */
122        public static final int ARCHIVE = 0x0004;
123        /**
124         * Whether the server will stop notifying on updates to this thread? This requires
125         * THREADED_CONVERSATIONS to be true, otherwise it should be ignored.
126         */
127        public static final int MUTE = 0x0008;
128        /**
129         * Whether the server supports searching over all messages. This requires SYNCABLE_FOLDERS
130         * to be true, otherwise it should be ignored.
131         */
132        public static final int SERVER_SEARCH = 0x0010;
133        /**
134         * Whether the server supports constraining search to a single folder. Requires
135         * SYNCABLE_FOLDERS, otherwise it should be ignored.
136         */
137        public static final int FOLDER_SERVER_SEARCH = 0x0020;
138        /**
139         * Whether the server sends us sanitized HTML (guaranteed to not contain malicious HTML).
140         */
141        public static final int SANITIZED_HTML = 0x0040;
142        /**
143         * Whether the server allows synchronization of draft messages. This does NOT require
144         * SYNCABLE_FOLDERS to be set.
145         */
146        public static final int DRAFT_SYNCHRONIZATION = 0x0080;
147        /**
148         * Does the server allow the user to compose mails (and reply) using addresses other than
149         * their account name? For instance, GMail allows users to set FROM addresses that are
150         * different from account@gmail.com address. For instance, user@gmail.com could have another
151         * FROM: address like user@android.com. If the user has enabled multiple FROM address, he
152         * can compose (and reply) using either address.
153         */
154        public static final int MULTIPLE_FROM_ADDRESSES = 0x0100;
155        /**
156         * Whether the server allows the original message to be included in the reply by setting a
157         * flag on the reply. If we can avoid including the entire previous message, we save on
158         * bandwidth (replies are shorter).
159         */
160        public static final int SMART_REPLY = 0x0200;
161        /**
162         * Does this account support searching locally, on the device? This requires the backend
163         * storage to support a mechanism for searching.
164         */
165        public static final int LOCAL_SEARCH = 0x0400;
166        /**
167         * Whether the server supports a notion of threaded conversations: where replies to messages
168         * are tagged to keep conversations grouped. This could be full threading (each message
169         * lists its parent) or conversation-level threading (each message lists one conversation
170         * which it belongs to)
171         */
172        public static final int THREADED_CONVERSATIONS = 0x0800;
173        /**
174         * Whether the server supports allowing a conversation to be in multiple folders. (Or allows
175         * multiple labels on a single conversation, since labels and folders are interchangeable
176         * in this application.)
177         */
178        public static final int MULTIPLE_FOLDERS_PER_CONV = 0x1000;
179        /**
180         * Whether the provider supports undoing operations. If it doesn't, never show the undo bar.
181         */
182        public static final int UNDO = 0x2000;
183    }
184
185    public static final class AccountColumns {
186        /**
187         * This string column contains the human visible name for the account.
188         */
189        public static final String NAME = "name";
190
191        /**
192         * This integer column returns the version of the UI provider schema from which this
193         * account provider will return results.
194         */
195        public static final String PROVIDER_VERSION = "providerVersion";
196
197        /**
198         * This string column contains the uri to directly access the information for this account.
199         */
200        public static final String URI = "accountUri";
201
202        /**
203         * This integer column contains a bit field of the possible cabibilities that this account
204         * supports.
205         */
206        public static final String CAPABILITIES = "capabilities";
207
208        /**
209         * This string column contains the content provider uri to return the
210         * list of top level folders for this account.
211         */
212        public static final String FOLDER_LIST_URI = "folderListUri";
213
214        /**
215         * This string column contains the content provider uri that can be queried for search
216         * results.
217         */
218        public static final String SEARCH_URI = "searchUri";
219
220        /**
221         * This string column contains the content provider uri that can be queried to access the
222         * from addresses for this account.
223         */
224        public static final String ACCOUNT_FROM_ADDRESSES_URI = "accountFromAddressesUri";
225
226        /**
227         * This string column contains the content provider uri that can be used to save (insert)
228         * new draft messages for this account. NOTE: This might be better to
229         * be an update operation on the messageUri.
230         */
231        public static final String SAVE_DRAFT_URI = "saveDraftUri";
232
233        /**
234         * This string column contains the content provider uri that can be used to send
235         * a message for this account.
236         * NOTE: This might be better to be an update operation on the messageUri.
237         */
238        public static final String SEND_MAIL_URI = "sendMailUri";
239
240        /**
241         * This string column contains the content provider uri that can be used
242         * to expunge a message from this account. NOTE: This might be better to
243         * be an update operation on the messageUri.
244         */
245        public static final String EXPUNGE_MESSAGE_URI = "expungeMessageUri";
246
247        /**
248         * This string column contains the content provider uri that can be used
249         * to undo the last committed action.
250         */
251        public static final String UNDO_URI = "undoUri";
252
253        /**
254         * Uri for EDIT intent that will cause the settings screens for this account type to be
255         * shown.
256         * TODO: When we want to support a heterogeneous set of account types, this value may need
257         * to be moved to a global content provider.
258         */
259        public static String SETTINGS_INTENT_URI = "accountSettingsIntentUri";
260
261        /**
262         * This int column contains the current sync status of the account (the logical AND of the
263         * sync status of folders in this account)
264         */
265        public static final String SYNC_STATUS = "syncStatus";
266    }
267
268    // We define a "folder" as anything that contains a list of conversations.
269    public static final String FOLDER_LIST_TYPE =
270            "vnd.android.cursor.dir/vnd.com.android.mail.folder";
271    public static final String FOLDER_TYPE =
272            "vnd.android.cursor.item/vnd.com.android.mail.folder";
273
274    public static final String[] FOLDERS_PROJECTION = {
275        BaseColumns._ID,
276        FolderColumns.URI,
277        FolderColumns.NAME,
278        FolderColumns.HAS_CHILDREN,
279        FolderColumns.CAPABILITIES,
280        FolderColumns.SYNC_FREQUENCY,
281        FolderColumns.SYNC_WINDOW,
282        FolderColumns.CONVERSATION_LIST_URI,
283        FolderColumns.CHILD_FOLDERS_LIST_URI,
284        FolderColumns.UNREAD_COUNT,
285        FolderColumns.TOTAL_COUNT,
286        FolderColumns.REFRESH_URI,
287        FolderColumns.SYNC_STATUS,
288        FolderColumns.LAST_SYNC_RESULT
289    };
290
291    public static final int FOLDER_ID_COLUMN = 0;
292    public static final int FOLDER_URI_COLUMN = 1;
293    public static final int FOLDER_NAME_COLUMN = 2;
294    public static final int FOLDER_HAS_CHILDREN_COLUMN = 3;
295    public static final int FOLDER_CAPABILITIES_COLUMN = 4;
296    public static final int FOLDER_SYNC_FREQUENCY_COLUMN = 5;
297    public static final int FOLDER_SYNC_WINDOW_COLUMN = 6;
298    public static final int FOLDER_CONVERSATION_LIST_URI_COLUMN = 7;
299    public static final int FOLDER_CHILD_FOLDERS_LIST_COLUMN = 8;
300    public static final int FOLDER_UNREAD_COUNT_COLUMN = 9;
301    public static final int FOLDER_TOTAL_COUNT_COLUMN = 10;
302    public static final int FOLDER_REFRESH_URI_COLUMN = 11;
303    public static final int FOLDER_SYNC_STATUS_COLUMN = 12;
304    public static final int FOLDER_LAST_SYNC_RESULT_COLUMN = 13;
305
306    public static final class FolderCapabilities {
307        public static final int SYNCABLE = 0x0001;
308        public static final int PARENT = 0x0002;
309        public static final int CAN_HOLD_MAIL = 0x0004;
310        public static final int CAN_ACCEPT_MOVED_MESSAGES = 0x0008;
311    }
312
313    public static final class FolderColumns {
314        public static final String URI = "folderUri";
315        /**
316         * This string column contains the human visible name for the folder.
317         */
318        public static final String NAME = "name";
319        /**
320         * This int column represents the capabilities of the folder specified by
321         * FolderCapabilities flags.
322         */
323        public static String CAPABILITIES = "capabilities";
324        /**
325         * This int column represents whether or not this folder has any
326         * child folders.
327         */
328        public static String HAS_CHILDREN = "hasChildren";
329        /**
330         * This int column represents how often the folder should be synchronized with the server.
331         */
332        public static String SYNC_FREQUENCY = "syncFrequency";
333        /**
334         * This int column represents how large the sync window is.
335         */
336        public static String SYNC_WINDOW = "syncWindow";
337        /**
338         * This string column contains the content provider uri to return the
339         * list of conversations for this folder.
340         */
341        public static final String CONVERSATION_LIST_URI = "conversationListUri";
342        /**
343         * This string column contains the content provider uri to return the
344         * list of child folders of this folder.
345         */
346        public static final String CHILD_FOLDERS_LIST_URI = "childFoldersListUri";
347
348        public static final String UNREAD_COUNT = "unreadCount";
349
350        public static final String TOTAL_COUNT = "totalCount";
351        /**
352         * This string column contains the content provider uri to force a
353         * refresh of this folder.
354         */
355        public static final  String REFRESH_URI = "refreshUri";
356        /**
357         * This int column contains current sync status of the folder; some combination of the
358         * SyncStatus bits defined above
359         */
360        public static final String SYNC_STATUS  = "syncStatus";
361        /**
362         * This int column contains the sync status of the last sync attempt; one of the
363         * LastSyncStatus values defined above
364         */
365        public static final String LAST_SYNC_RESULT  = "lastSyncResult";
366
367        public FolderColumns() {}
368    }
369
370    // We define a "folder" as anything that contains a list of conversations.
371    public static final String CONVERSATION_LIST_TYPE =
372            "vnd.android.cursor.dir/vnd.com.android.mail.conversation";
373    public static final String CONVERSATION_TYPE =
374            "vnd.android.cursor.item/vnd.com.android.mail.conversation";
375
376
377    public static final String[] CONVERSATION_PROJECTION = {
378        BaseColumns._ID,
379        ConversationColumns.URI,
380        ConversationColumns.MESSAGE_LIST_URI,
381        ConversationColumns.SUBJECT,
382        ConversationColumns.SNIPPET,
383        ConversationColumns.SENDER_INFO,
384        ConversationColumns.DATE_RECEIVED_MS,
385        ConversationColumns.HAS_ATTACHMENTS,
386        ConversationColumns.NUM_MESSAGES,
387        ConversationColumns.NUM_DRAFTS,
388        ConversationColumns.SENDING_STATE,
389        ConversationColumns.PRIORITY,
390        ConversationColumns.READ,
391        ConversationColumns.STARRED,
392        ConversationColumns.FOLDER_LIST
393    };
394
395    // These column indexes only work when the caller uses the
396    // default CONVERSATION_PROJECTION defined above.
397    public static final int CONVERSATION_ID_COLUMN = 0;
398    public static final int CONVERSATION_URI_COLUMN = 1;
399    public static final int CONVERSATION_MESSAGE_LIST_URI_COLUMN = 2;
400    public static final int CONVERSATION_SUBJECT_COLUMN = 3;
401    public static final int CONVERSATION_SNIPPET_COLUMN = 4;
402    public static final int CONVERSATION_SENDER_INFO_COLUMN = 5;
403    public static final int CONVERSATION_DATE_RECEIVED_MS_COLUMN = 6;
404    public static final int CONVERSATION_HAS_ATTACHMENTS_COLUMN = 7;
405    public static final int CONVERSATION_NUM_MESSAGES_COLUMN = 8;
406    public static final int CONVERSATION_NUM_DRAFTS_COLUMN = 9;
407    public static final int CONVERSATION_SENDING_STATE_COLUMN = 10;
408    public static final int CONVERSATION_PRIORITY_COLUMN = 11;
409    public static final int CONVERSATION_READ_COLUMN = 12;
410    public static final int CONVERSATION_STARRED_COLUMN = 13;
411    public static final int CONVERSATION_FOLDER_LIST_COLUMN = 14;
412
413    public static final class ConversationSendingState {
414        public static final int OTHER = 0;
415        public static final int SENDING = 1;
416        public static final int SENT = 2;
417        public static final int SEND_ERROR = -1;
418    }
419
420    public static final class ConversationPriority {
421        public static final int LOW = 0;
422        public static final int HIGH = 1;
423    }
424
425    public static final class ConversationFlags {
426        public static final int READ = 1<<0;
427        public static final int STARRED = 1<<1;
428        public static final int REPLIED = 1<<2;
429        public static final int FORWARDED = 1<<3;
430    }
431
432    public static final class ConversationColumns {
433        public static final String URI = "conversationUri";
434        /**
435         * This string column contains the content provider uri to return the
436         * list of messages for this conversation.
437         */
438        public static final String MESSAGE_LIST_URI = "messageListUri";
439        /**
440         * This string column contains the subject string for a conversation.
441         */
442        public static final String SUBJECT = "subject";
443        /**
444         * This string column contains the snippet string for a conversation.
445         */
446        public static final String SNIPPET = "snippet";
447        /**
448         * This string column contains the sender info string for a
449         * conversation.
450         */
451        public static final String SENDER_INFO = "senderInfo";
452        /**
453         * This long column contains the time in ms of the latest update to a
454         * conversation.
455         */
456        public static final String DATE_RECEIVED_MS = "dateReceivedMs";
457
458        /**
459         * This boolean column contains whether any messages in this conversation
460         * have attachments.
461         */
462        public static final String HAS_ATTACHMENTS = "hasAttachments";
463
464        /**
465         * This int column contains the number of messages in this conversation.
466         * For unthreaded, this will always be 1.
467         */
468        public static String NUM_MESSAGES = "numMessages";
469
470        /**
471         * This int column contains the number of drafts associated with this
472         * conversation.
473         */
474        public static String NUM_DRAFTS = "numDrafts";
475
476        /**
477         * This int column contains the state of drafts and replies associated
478         * with this conversation. Use ConversationSendingState to interpret
479         * this field.
480         */
481        public static String SENDING_STATE = "sendingState";
482
483        /**
484         * This int column contains the priority of this conversation. Use
485         * ConversationPriority to interpret this field.
486         */
487        public static String PRIORITY = "priority";
488
489        /**
490         * This boolean column indicates whether the conversation has been read
491         */
492        public static String READ = "read";
493
494        /**
495         * This boolean column indicates whether the conversation has been read
496         */
497        public static String STARRED = "starred";
498
499        /**
500         * This string column contains a csv of all folders associated with this
501         * conversation
502         */
503        public static final String FOLDER_LIST = "folderList";
504
505        public ConversationColumns() {
506        }
507    }
508
509    /**
510     * Returns a uri that, when queried, will return a cursor with a list of information for the
511     * list of configured accounts.
512     * @return
513     */
514    // TODO: create a static registry for the starting point for the UI provider.
515//    public static Uri getAccountsUri() {
516//        return Uri.parse(BASE_URI_STRING + "/");
517//    }
518
519    public static final class DraftType {
520        public static final int NOT_A_DRAFT = 0;
521        public static final int COMPOSE = 1;
522        public static final int REPLY = 2;
523        public static final int REPLY_ALL = 3;
524        public static final int FORWARD = 4;
525
526        private DraftType() {}
527    }
528
529    public static final String[] MESSAGE_PROJECTION = {
530        BaseColumns._ID,
531        MessageColumns.SERVER_ID,
532        MessageColumns.URI,
533        MessageColumns.CONVERSATION_ID,
534        MessageColumns.SUBJECT,
535        MessageColumns.SNIPPET,
536        MessageColumns.FROM,
537        MessageColumns.TO,
538        MessageColumns.CC,
539        MessageColumns.BCC,
540        MessageColumns.REPLY_TO,
541        MessageColumns.DATE_RECEIVED_MS,
542        MessageColumns.BODY_HTML,
543        MessageColumns.BODY_TEXT,
544        MessageColumns.EMBEDS_EXTERNAL_RESOURCES,
545        MessageColumns.REF_MESSAGE_ID,
546        MessageColumns.DRAFT_TYPE,
547        MessageColumns.APPEND_REF_MESSAGE_CONTENT,
548        MessageColumns.HAS_ATTACHMENTS,
549        MessageColumns.ATTACHMENT_LIST_URI,
550        MessageColumns.MESSAGE_FLAGS,
551        MessageColumns.JOINED_ATTACHMENT_INFOS,
552        MessageColumns.SAVE_MESSAGE_URI,
553        MessageColumns.SEND_MESSAGE_URI
554    };
555
556    /** Separates attachment info parts in strings in a message. */
557    public static final String MESSAGE_ATTACHMENT_INFO_SEPARATOR = "\n";
558    public static final String MESSAGE_LIST_TYPE =
559            "vnd.android.cursor.dir/vnd.com.android.mail.message";
560    public static final String MESSAGE_TYPE =
561            "vnd.android.cursor.item/vnd.com.android.mail.message";
562
563    public static final int MESSAGE_ID_COLUMN = 0;
564    public static final int MESSAGE_SERVER_ID_COLUMN = 1;
565    public static final int MESSAGE_URI_COLUMN = 2;
566    public static final int MESSAGE_CONVERSATION_ID_COLUMN = 3;
567    public static final int MESSAGE_SUBJECT_COLUMN = 4;
568    public static final int MESSAGE_SNIPPET_COLUMN = 5;
569    public static final int MESSAGE_FROM_COLUMN = 6;
570    public static final int MESSAGE_TO_COLUMN = 7;
571    public static final int MESSAGE_CC_COLUMN = 8;
572    public static final int MESSAGE_BCC_COLUMN = 9;
573    public static final int MESSAGE_REPLY_TO_COLUMN = 10;
574    public static final int MESSAGE_DATE_RECEIVED_MS_COLUMN = 11;
575    public static final int MESSAGE_BODY_HTML_COLUMN = 12;
576    public static final int MESSAGE_BODY_TEXT_COLUMN = 13;
577    public static final int MESSAGE_EMBEDS_EXTERNAL_RESOURCES_COLUMN = 14;
578    public static final int MESSAGE_REF_MESSAGE_ID_COLUMN = 15;
579    public static final int MESSAGE_DRAFT_TYPE_COLUMN = 16;
580    public static final int MESSAGE_APPEND_REF_MESSAGE_CONTENT_COLUMN = 17;
581    public static final int MESSAGE_HAS_ATTACHMENTS_COLUMN = 18;
582    public static final int MESSAGE_ATTACHMENT_LIST_URI_COLUMN = 19;
583    public static final int MESSAGE_FLAGS_COLUMN = 20;
584    public static final int MESSAGE_JOINED_ATTACHMENT_INFOS_COLUMN = 21;
585    public static final int MESSAGE_SAVE_URI_COLUMN = 22;
586    public static final int MESSAGE_SEND_URI_COLUMN = 23;
587
588    public static final class MessageFlags {
589        public static final int STARRED =       1 << 0;
590        public static final int UNREAD =        1 << 1;
591        public static final int REPLIED =       1 << 2;
592        public static final int FORWARDED =     1 << 3;
593    }
594
595    public static final class MessageColumns {
596        /**
597         * This string column contains a content provider URI that points to this single message.
598         */
599        public static final String URI = "messageUri";
600        /**
601         * This string column contains a server-assigned ID for this message.
602         */
603        public static final String SERVER_ID = "serverMessageId";
604        public static final String CONVERSATION_ID = "conversationId";
605        /**
606         * This string column contains the subject of a message.
607         */
608        public static final String SUBJECT = "subject";
609        /**
610         * This string column contains a snippet of the message body.
611         */
612        public static final String SNIPPET = "snippet";
613        /**
614         * This string column contains the single email address (and optionally name) of the sender.
615         */
616        public static final String FROM = "fromAddress";
617        /**
618         * This string column contains a comma-delimited list of "To:" recipient email addresses.
619         */
620        public static final String TO = "toAddresses";
621        /**
622         * This string column contains a comma-delimited list of "CC:" recipient email addresses.
623         */
624        public static final String CC = "ccAddresses";
625        /**
626         * This string column contains a comma-delimited list of "BCC:" recipient email addresses.
627         * This value will be null for incoming messages.
628         */
629        public static final String BCC = "bccAddresses";
630        /**
631         * This string column contains the single email address (and optionally name) of the
632         * sender's reply-to address.
633         */
634        public static final String REPLY_TO = "replyToAddress";
635        /**
636         * This long column contains the timestamp (in millis) of receipt of the message.
637         */
638        public static final String DATE_RECEIVED_MS = "dateReceivedMs";
639        /**
640         * This string column contains the HTML form of the message body, if available. If not,
641         * a provider must populate BODY_TEXT.
642         */
643        public static final String BODY_HTML = "bodyHtml";
644        /**
645         * This string column contains the plaintext form of the message body, if HTML is not
646         * otherwise available. If HTML is available, this value should be left empty (null).
647         */
648        public static final String BODY_TEXT = "bodyText";
649        public static final String EMBEDS_EXTERNAL_RESOURCES = "bodyEmbedsExternalResources";
650        /**
651         * This string column contains an opaque string used by the sendMessage api.
652         */
653        public static final String REF_MESSAGE_ID = "refMessageId";
654        /**
655         * This integer column contains the type of this draft, or zero (0) if this message is not a
656         * draft. See {@link DraftType} for possible values.
657         */
658        public static final String DRAFT_TYPE = "draftType";
659        /**
660         * This boolean column indicates whether an outgoing message should trigger special quoted
661         * text processing upon send. The value should default to zero (0) for protocols that do
662         * not support or require this flag, and for all incoming messages.
663         */
664        public static final String APPEND_REF_MESSAGE_CONTENT = "appendRefMessageContent";
665        /**
666         * This boolean column indicates whether a message has attachments. The list of attachments
667         * can be retrieved using the URI in {@link MessageColumns#ATTACHMENT_LIST_URI}.
668         */
669        public static final String HAS_ATTACHMENTS = "hasAttachments";
670        /**
671         * This string column contains the content provider URI for the list of
672         * attachments associated with this message.
673         */
674        public static final String ATTACHMENT_LIST_URI = "attachmentListUri";
675        /**
676         * This long column is a bit field of flags defined in {@link MessageFlags}.
677         */
678        public static final String MESSAGE_FLAGS = "messageFlags";
679        /**
680         * This string column contains a specially formatted string representing all
681         * attachments that we added to a message that is being sent or saved.
682         */
683        public static final String JOINED_ATTACHMENT_INFOS = "joinedAttachmentInfos";
684        /**
685         * This string column contains the content provider URI for saving this
686         * message.
687         */
688        public static final String SAVE_MESSAGE_URI = "saveMessageUri";
689        /**
690         * This string column contains content provider URI for sending this
691         * message.
692         */
693        public static final String SEND_MESSAGE_URI = "sendMessageUri";
694
695        private MessageColumns() {}
696    }
697
698    // We define a "folder" as anything that contains a list of conversations.
699    public static final String ATTACHMENT_LIST_TYPE =
700            "vnd.android.cursor.dir/vnd.com.android.mail.attachment";
701    public static final String ATTACHMENT_TYPE =
702            "vnd.android.cursor.item/vnd.com.android.mail.attachment";
703
704    public static final String[] ATTACHMENT_PROJECTION = {
705        BaseColumns._ID,
706        AttachmentColumns.NAME,
707        AttachmentColumns.SIZE,
708        AttachmentColumns.URI,
709        AttachmentColumns.ORIGIN_EXTRAS,
710        AttachmentColumns.CONTENT_TYPE,
711        AttachmentColumns.SYNCED
712    };
713    private static final String EMAIL_SEPARATOR_PATTERN = "\n";
714    public static final int ATTACHMENT_ID_COLUMN = 0;
715    public static final int ATTACHMENT_NAME_COLUMN = 1;
716    public static final int ATTACHMENT_SIZE_COLUMN = 2;
717    public static final int ATTACHMENT_URI_COLUMN = 3;
718    public static final int ATTACHMENT_ORIGIN_EXTRAS_COLUMN = 4;
719    public static final int ATTACHMENT_CONTENT_TYPE_COLUMN = 5;
720    public static final int ATTACHMENT_SYNCED_COLUMN = 6;
721
722    public static final class AttachmentColumns {
723        public static final String NAME = "name";
724        public static final String SIZE = "size";
725        public static final String URI = "uri";
726        public static final String ORIGIN_EXTRAS = "originExtras";
727        public static final String CONTENT_TYPE = "contentType";
728        public static final String SYNCED = "synced";
729    }
730
731    public static int getMailMaxAttachmentSize(String account) {
732        // TODO: query the account to see what the max attachment size is?
733        return 5 * 1024 * 1024;
734    }
735
736    public static String getAttachmentTypeSetting() {
737        // TODO: query the account to see what kinds of attachments it supports?
738        return "com.google.android.gm.allowAddAnyAttachment";
739    }
740
741    public static void incrementRecipientsTimesContacted(Context context, String addressString) {
742        DataUsageStatUpdater statsUpdater = new DataUsageStatUpdater(context);
743        ArrayList<String> recipients = new ArrayList<String>();
744        String[] addresses = TextUtils.split(addressString, EMAIL_SEPARATOR_PATTERN);
745        for (String address : addresses) {
746            recipients.add(address);
747        }
748        statsUpdater.updateWithAddress(recipients);
749    }
750
751    public static final String[] UNDO_PROJECTION = {
752        ConversationColumns.MESSAGE_LIST_URI
753    };
754    public static final int UNDO_MESSAGE_LIST_COLUMN = 0;
755
756    // Parameter used to indicate the sequence number for an undoable operation
757    public static final String SEQUENCE_QUERY_PARAMETER = "seq";
758}
759