UIProvider.java revision 48a4aed2e943debf725564808944e7c9e46dce5d
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.ContentProvider;
21import android.content.ContentValues;
22import android.content.Context;
23import android.content.Intent;
24import android.net.Uri;
25import android.provider.BaseColumns;
26import android.text.TextUtils;
27
28import com.android.common.contacts.DataUsageStatUpdater;
29
30import java.util.ArrayList;
31
32public class UIProvider {
33    public static final String EMAIL_SEPARATOR = "\n";
34    public static final long INVALID_CONVERSATION_ID = -1;
35    public static final long INVALID_MESSAGE_ID = -1;
36
37    /**
38     * Values for the current state of a Folder/Account; note that it's possible that more than one
39     * sync is in progress
40     */
41    public static final class SyncStatus {
42        // No sync in progress
43        public static final int NO_SYNC = 0;
44        // A user-requested sync/refresh is in progress
45        public static final int USER_REFRESH = 1<<0;
46        // A user-requested query is in progress
47        public static final int USER_QUERY = 1<<1;
48        // A user request for additional results is in progress
49        public static final int USER_MORE_RESULTS = 1<<2;
50        // A background sync is in progress
51        public static final int BACKGROUND_SYNC = 1<<3;
52    }
53
54    /**
55     * Values for the result of the last attempted sync of a Folder/Account
56     */
57    public static final class LastSyncResult {
58        // The sync completed successfully
59        public static final int SUCCESS = 0;
60        // The sync wasn't completed due to a connection error
61        public static final int CONNECTION_ERROR = 1;
62        // The sync wasn't completed due to an authentication error
63        public static final int AUTH_ERROR = 2;
64        // The sync wasn't completed due to a security error
65        public static final int SECURITY_ERROR = 3;
66        // The sync wasn't completed due to a low memory condition
67        public static final int STORAGE_ERROR = 4;
68        // The sync wasn't completed due to an internal error/exception
69        public static final int INTERNAL_ERROR = 5;
70    }
71
72    // The actual content provider should define its own authority
73    public static final String AUTHORITY = "com.android.mail.providers";
74
75    public static final String ACCOUNT_LIST_TYPE =
76            "vnd.android.cursor.dir/vnd.com.android.mail.account";
77    public static final String ACCOUNT_TYPE =
78            "vnd.android.cursor.item/vnd.com.android.mail.account";
79
80    public static final String[] ACCOUNTS_PROJECTION = {
81            BaseColumns._ID,
82            AccountColumns.NAME,
83            AccountColumns.PROVIDER_VERSION,
84            AccountColumns.URI,
85            AccountColumns.CAPABILITIES,
86            AccountColumns.FOLDER_LIST_URI,
87            AccountColumns.SEARCH_URI,
88            AccountColumns.ACCOUNT_FROM_ADDRESSES_URI,
89            AccountColumns.SAVE_DRAFT_URI,
90            AccountColumns.SEND_MAIL_URI,
91            AccountColumns.EXPUNGE_MESSAGE_URI,
92            AccountColumns.UNDO_URI,
93            AccountColumns.SETTINGS_INTENT_URI,
94            AccountColumns.SETTINGS_QUERY_URI,
95            AccountColumns.SYNC_STATUS,
96            AccountColumns.HELP_INTENT_URI,
97            AccountColumns.COMPOSE_URI,
98            AccountColumns.MIME_TYPE,
99            AccountColumns.RECENT_FOLDER_LIST_URI
100    };
101
102    public static final int ACCOUNT_ID_COLUMN = 0;
103    public static final int ACCOUNT_NAME_COLUMN = 1;
104    public static final int ACCOUNT_PROVIDER_VERISON_COLUMN = 2;
105    public static final int ACCOUNT_URI_COLUMN = 3;
106    public static final int ACCOUNT_CAPABILITIES_COLUMN = 4;
107    public static final int ACCOUNT_FOLDER_LIST_URI_COLUMN = 5;
108    public static final int ACCOUNT_SEARCH_URI_COLUMN = 6;
109    public static final int ACCOUNT_FROM_ADDRESSES_URI_COLUMN = 7;
110    public static final int ACCOUNT_SAVE_DRAFT_URI_COLUMN = 8;
111    public static final int ACCOUNT_SEND_MESSAGE_URI_COLUMN = 9;
112    public static final int ACCOUNT_EXPUNGE_MESSAGE_URI_COLUMN = 10;
113    public static final int ACCOUNT_UNDO_URI_COLUMN = 11;
114    public static final int ACCOUNT_SETTINGS_INTENT_URI_COLUMN = 12;
115    public static final int ACCOUNT_SETTINGS_QUERY_URI_COLUMN = 13;
116    public static final int ACCOUNT_SYNC_STATUS_COLUMN = 14;
117    public static final int ACCOUNT_HELP_INTENT_URI_COLUMN = 15;
118    public static final int ACCOUNT_COMPOSE_INTENT_URI_COLUMN = 16;
119    public static final int ACCOUNT_MIME_TYPE_COLUMN = 17;
120    public static final int ACCOUNT_RECENT_FOLDER_LIST_URI_COLUMN = 18;
121
122    public static final class AccountCapabilities {
123        /**
124         * Whether folders can be synchronized back to the server.
125         */
126        public static final int SYNCABLE_FOLDERS = 0x0001;
127        /**
128         * Whether the server allows reporting spam back.
129         */
130        public static final int REPORT_SPAM = 0x0002;
131        /**
132         * Whether the server supports a concept of Archive: removing mail from the Inbox but
133         * keeping it around.
134         */
135        public static final int ARCHIVE = 0x0004;
136        /**
137         * Whether the server will stop notifying on updates to this thread? This requires
138         * THREADED_CONVERSATIONS to be true, otherwise it should be ignored.
139         */
140        public static final int MUTE = 0x0008;
141        /**
142         * Whether the server supports searching over all messages. This requires SYNCABLE_FOLDERS
143         * to be true, otherwise it should be ignored.
144         */
145        public static final int SERVER_SEARCH = 0x0010;
146        /**
147         * Whether the server supports constraining search to a single folder. Requires
148         * SYNCABLE_FOLDERS, otherwise it should be ignored.
149         */
150        public static final int FOLDER_SERVER_SEARCH = 0x0020;
151        /**
152         * Whether the server sends us sanitized HTML (guaranteed to not contain malicious HTML).
153         */
154        public static final int SANITIZED_HTML = 0x0040;
155        /**
156         * Whether the server allows synchronization of draft messages. This does NOT require
157         * SYNCABLE_FOLDERS to be set.
158         */
159        public static final int DRAFT_SYNCHRONIZATION = 0x0080;
160        /**
161         * Does the server allow the user to compose mails (and reply) using addresses other than
162         * their account name? For instance, GMail allows users to set FROM addresses that are
163         * different from account@gmail.com address. For instance, user@gmail.com could have another
164         * FROM: address like user@android.com. If the user has enabled multiple FROM address, he
165         * can compose (and reply) using either address.
166         */
167        public static final int MULTIPLE_FROM_ADDRESSES = 0x0100;
168        /**
169         * Whether the server allows the original message to be included in the reply by setting a
170         * flag on the reply. If we can avoid including the entire previous message, we save on
171         * bandwidth (replies are shorter).
172         */
173        public static final int SMART_REPLY = 0x0200;
174        /**
175         * Does this account support searching locally, on the device? This requires the backend
176         * storage to support a mechanism for searching.
177         */
178        public static final int LOCAL_SEARCH = 0x0400;
179        /**
180         * Whether the server supports a notion of threaded conversations: where replies to messages
181         * are tagged to keep conversations grouped. This could be full threading (each message
182         * lists its parent) or conversation-level threading (each message lists one conversation
183         * which it belongs to)
184         */
185        public static final int THREADED_CONVERSATIONS = 0x0800;
186        /**
187         * Whether the server supports allowing a conversation to be in multiple folders. (Or allows
188         * multiple folders on a single conversation)
189         */
190        public static final int MULTIPLE_FOLDERS_PER_CONV = 0x1000;
191        /**
192         * Whether the provider supports undoing operations. If it doesn't, never show the undo bar.
193         */
194        public static final int UNDO = 0x2000;
195        /**
196         * Whether the account provides help content.
197         */
198        public static final int HELP_CONTENT = 0x4000;
199        /**
200         * Whether the account provides a mechanism for marking conversations as important.
201         */
202        public static final int MARK_IMPORTANT = 0x8000;
203    }
204
205    public static final class AccountColumns {
206        /**
207         * This string column contains the human visible name for the account.
208         */
209        public static final String NAME = "name";
210
211        /**
212         * This integer column returns the version of the UI provider schema from which this
213         * account provider will return results.
214         */
215        public static final String PROVIDER_VERSION = "providerVersion";
216
217        /**
218         * This string column contains the uri to directly access the information for this account.
219         */
220        public static final String URI = "accountUri";
221
222        /**
223         * This integer column contains a bit field of the possible capabilities that this account
224         * supports.
225         */
226        public static final String CAPABILITIES = "capabilities";
227
228        /**
229         * This string column contains the content provider uri to return the
230         * list of top level folders for this account.
231         */
232        public static final String FOLDER_LIST_URI = "folderListUri";
233
234        /**
235         * This string column contains the content provider uri that can be queried for search
236         * results.
237         * The supported query parameters are limited to those listed
238         * in {@link #SearchQueryParameters}
239         * The cursor returned from this query is expected have one row, where the columnm are a
240         * subset of the columns specified in {@link #FolderColumns}
241         */
242        public static final String SEARCH_URI = "searchUri";
243
244        /**
245         * This string column contains the content provider uri that can be queried to access the
246         * from addresses for this account.
247         */
248        public static final String ACCOUNT_FROM_ADDRESSES_URI = "accountFromAddressesUri";
249
250        /**
251         * This string column contains the content provider uri that can be used to save (insert)
252         * new draft messages for this account. NOTE: This might be better to
253         * be an update operation on the messageUri.
254         */
255        public static final String SAVE_DRAFT_URI = "saveDraftUri";
256
257        /**
258         * This string column contains the content provider uri that can be used to send
259         * a message for this account.
260         * NOTE: This might be better to be an update operation on the messageUri.
261         */
262        public static final String SEND_MAIL_URI = "sendMailUri";
263
264        /**
265         * This string column contains the content provider uri that can be used
266         * to expunge a message from this account. NOTE: This might be better to
267         * be an update operation on the messageUri.
268         */
269        public static final String EXPUNGE_MESSAGE_URI = "expungeMessageUri";
270
271        /**
272         * This string column contains the content provider uri that can be used
273         * to undo the last committed action.
274         */
275        public static final String UNDO_URI = "undoUri";
276
277        /**
278         * Uri for EDIT intent that will cause the settings screens for this account type to be
279         * shown.
280         * TODO: When we want to support a heterogeneous set of account types, this value may need
281         * to be moved to a global content provider.
282         */
283        public static String SETTINGS_INTENT_URI = "accountSettingsIntentUri";
284
285        /**
286         * This string column contains the content provider uri that can be used to query user
287         * settings/preferences.
288         *
289         * The cursor returned by this query support columns declared in {@link #SettingsColumns}
290         */
291        public static final String SETTINGS_QUERY_URI = "accountSettingsQueryUri";
292
293        /**
294         * Uri for VIEW intent that will cause the help screens for this account type to be
295         * shown.
296         * TODO: When we want to support a heterogeneous set of account types, this value may need
297         * to be moved to a global content provider.
298         */
299        public static String HELP_INTENT_URI = "helpIntentUri";
300
301        /**
302         * This int column contains the current sync status of the account (the logical AND of the
303         * sync status of folders in this account)
304         */
305        public static final String SYNC_STATUS = "syncStatus";
306        /**
307         * Uri for VIEW intent that will cause the compose screens for this type
308         * of account to be shown.
309         */
310        public static final String COMPOSE_URI = "composeUri";
311        /**
312         * Mime-type defining this account.
313         */
314        public static final String MIME_TYPE = "mimeType";
315        /**
316         * URI for location of recent folders viewed on this account.
317         */
318        public static final String RECENT_FOLDER_LIST_URI = "recentFolderListUri";
319    }
320
321    public static final class SearchQueryParameters {
322        /**
323         * Parameter used to specify the search query.
324         */
325        public static final String QUERY = "query";
326
327        /**
328         * If specified, the query results will be limited to this folder.
329         */
330        public static final String FOLDER = "folder";
331
332        private SearchQueryParameters() {}
333    }
334
335    // We define a "folder" as anything that contains a list of conversations.
336    public static final String FOLDER_LIST_TYPE =
337            "vnd.android.cursor.dir/vnd.com.android.mail.folder";
338    public static final String FOLDER_TYPE =
339            "vnd.android.cursor.item/vnd.com.android.mail.folder";
340
341    public static final String[] FOLDERS_PROJECTION = {
342        BaseColumns._ID,
343        FolderColumns.URI,
344        FolderColumns.NAME,
345        FolderColumns.HAS_CHILDREN,
346        FolderColumns.CAPABILITIES,
347        FolderColumns.SYNC_WINDOW,
348        FolderColumns.CONVERSATION_LIST_URI,
349        FolderColumns.CHILD_FOLDERS_LIST_URI,
350        FolderColumns.UNREAD_COUNT,
351        FolderColumns.TOTAL_COUNT,
352        FolderColumns.REFRESH_URI,
353        FolderColumns.SYNC_STATUS,
354        FolderColumns.LAST_SYNC_RESULT,
355        FolderColumns.TYPE,
356        FolderColumns.ICON_RES_ID,
357        FolderColumns.BG_COLOR,
358        FolderColumns.FG_COLOR,
359        FolderColumns.LOAD_MORE_URI
360    };
361
362    public static final int FOLDER_ID_COLUMN = 0;
363    public static final int FOLDER_URI_COLUMN = 1;
364    public static final int FOLDER_NAME_COLUMN = 2;
365    public static final int FOLDER_HAS_CHILDREN_COLUMN = 3;
366    public static final int FOLDER_CAPABILITIES_COLUMN = 4;
367    public static final int FOLDER_SYNC_WINDOW_COLUMN = 5;
368    public static final int FOLDER_CONVERSATION_LIST_URI_COLUMN = 6;
369    public static final int FOLDER_CHILD_FOLDERS_LIST_COLUMN = 7;
370    public static final int FOLDER_UNREAD_COUNT_COLUMN = 8;
371    public static final int FOLDER_TOTAL_COUNT_COLUMN = 9;
372    public static final int FOLDER_REFRESH_URI_COLUMN = 10;
373    public static final int FOLDER_SYNC_STATUS_COLUMN = 11;
374    public static final int FOLDER_LAST_SYNC_RESULT_COLUMN = 12;
375    public static final int FOLDER_TYPE_COLUMN = 13;
376    public static final int FOLDER_ICON_RES_ID_COLUMN = 14;
377    public static final int FOLDER_BG_COLOR_COLUMN = 15;
378    public static final int FOLDER_FG_COLOR_COLUMN = 16;
379    public static final int FOLDER_LOAD_MORE_URI_COLUMN = 17;
380
381    public static final class FolderType {
382        public static final int DEFAULT = 0;
383        public static final int INBOX = 1;
384        public static final int DRAFT = 2;
385        public static final int OUTBOX = 3;
386        public static final int SENT = 4;
387        public static final int TRASH = 5;
388        public static final int SPAM = 6;
389    }
390
391    public static final class FolderCapabilities {
392        public static final int SYNCABLE = 0x0001;
393        public static final int PARENT = 0x0002;
394        public static final int CAN_HOLD_MAIL = 0x0004;
395        public static final int CAN_ACCEPT_MOVED_MESSAGES = 0x0008;
396        /**
397         * For accounts that support archive, this will indicate that this folder supports
398         * the archive functionality.
399         */
400        public static final int ARCHIVE = 0x0010;
401
402        /**
403         * For accounts that support report spam, this will indicate that this folder supports
404         * the report spam functionality.
405         */
406        public static final int REPORT_SPAM = 0x0020;
407
408        /**
409         * For accounts that support mute, this will indicate if a mute is performed from within
410         * this folder, the action is destructive.
411         */
412        public static final int DESTRUCTIVE_MUTE = 0x0040;
413    }
414
415    public static final class FolderColumns {
416        public static final String URI = "folderUri";
417        /**
418         * This string column contains the human visible name for the folder.
419         */
420        public static final String NAME = "name";
421        /**
422         * This int column represents the capabilities of the folder specified by
423         * FolderCapabilities flags.
424         */
425        public static String CAPABILITIES = "capabilities";
426        /**
427         * This int column represents whether or not this folder has any
428         * child folders.
429         */
430        public static String HAS_CHILDREN = "hasChildren";
431        /**
432         * This int column represents how large the sync window is.
433         */
434        public static String SYNC_WINDOW = "syncWindow";
435        /**
436         * This string column contains the content provider uri to return the
437         * list of conversations for this folder.
438         */
439        public static final String CONVERSATION_LIST_URI = "conversationListUri";
440        /**
441         * This string column contains the content provider uri to return the
442         * list of child folders of this folder.
443         */
444        public static final String CHILD_FOLDERS_LIST_URI = "childFoldersListUri";
445
446        public static final String UNREAD_COUNT = "unreadCount";
447
448        public static final String TOTAL_COUNT = "totalCount";
449        /**
450         * This string column contains the content provider uri to force a
451         * refresh of this folder.
452         */
453        public static final  String REFRESH_URI = "refreshUri";
454        /**
455         * This int column contains current sync status of the folder; some combination of the
456         * SyncStatus bits defined above
457         */
458        public static final String SYNC_STATUS  = "syncStatus";
459        /**
460         * This int column contains the sync status of the last sync attempt; one of the
461         * LastSyncStatus values defined above
462         */
463        public static final String LAST_SYNC_RESULT  = "lastSyncResult";
464        /**
465         * This long column contains the icon res id for this folder, or 0 if there is none.
466         */
467        public static final String ICON_RES_ID = "iconResId";
468        /**
469         * This int column contains the type of the folder. Zero is default.
470         */
471        public static final String TYPE = "type";
472        /**
473         * String representing the integer background color associated with this
474         * folder, or null.
475         */
476        public static final String BG_COLOR = "bgColor";
477        /**
478         * String representing the integer of the foreground color associated
479         * with this folder, or null.
480         */
481        public static final String FG_COLOR = "fgColor";
482        /**
483         * String with the content provider Uri used to request more items in the folder, or null.
484         */
485        public static final String LOAD_MORE_URI = "loadMoreUri";
486        public FolderColumns() {}
487    }
488
489    // We define a "folder" as anything that contains a list of conversations.
490    public static final String CONVERSATION_LIST_TYPE =
491            "vnd.android.cursor.dir/vnd.com.android.mail.conversation";
492    public static final String CONVERSATION_TYPE =
493            "vnd.android.cursor.item/vnd.com.android.mail.conversation";
494
495
496    public static final String[] CONVERSATION_PROJECTION = {
497        BaseColumns._ID,
498        ConversationColumns.URI,
499        ConversationColumns.MESSAGE_LIST_URI,
500        ConversationColumns.SUBJECT,
501        ConversationColumns.SNIPPET,
502        ConversationColumns.SENDER_INFO,
503        ConversationColumns.DATE_RECEIVED_MS,
504        ConversationColumns.HAS_ATTACHMENTS,
505        ConversationColumns.NUM_MESSAGES,
506        ConversationColumns.NUM_DRAFTS,
507        ConversationColumns.SENDING_STATE,
508        ConversationColumns.PRIORITY,
509        ConversationColumns.READ,
510        ConversationColumns.STARRED,
511        ConversationColumns.FOLDER_LIST
512    };
513
514    // These column indexes only work when the caller uses the
515    // default CONVERSATION_PROJECTION defined above.
516    public static final int CONVERSATION_ID_COLUMN = 0;
517    public static final int CONVERSATION_URI_COLUMN = 1;
518    public static final int CONVERSATION_MESSAGE_LIST_URI_COLUMN = 2;
519    public static final int CONVERSATION_SUBJECT_COLUMN = 3;
520    public static final int CONVERSATION_SNIPPET_COLUMN = 4;
521    public static final int CONVERSATION_SENDER_INFO_COLUMN = 5;
522    public static final int CONVERSATION_DATE_RECEIVED_MS_COLUMN = 6;
523    public static final int CONVERSATION_HAS_ATTACHMENTS_COLUMN = 7;
524    public static final int CONVERSATION_NUM_MESSAGES_COLUMN = 8;
525    public static final int CONVERSATION_NUM_DRAFTS_COLUMN = 9;
526    public static final int CONVERSATION_SENDING_STATE_COLUMN = 10;
527    public static final int CONVERSATION_PRIORITY_COLUMN = 11;
528    public static final int CONVERSATION_READ_COLUMN = 12;
529    public static final int CONVERSATION_STARRED_COLUMN = 13;
530    public static final int CONVERSATION_FOLDER_LIST_COLUMN = 14;
531
532    public static final class ConversationSendingState {
533        public static final int OTHER = 0;
534        public static final int SENDING = 1;
535        public static final int SENT = 2;
536        public static final int SEND_ERROR = -1;
537    }
538
539    public static final class ConversationPriority {
540        public static final int LOW = 0;
541        public static final int HIGH = 1;
542    }
543
544    public static final class ConversationFlags {
545        public static final int READ = 1<<0;
546        public static final int STARRED = 1<<1;
547        public static final int REPLIED = 1<<2;
548        public static final int FORWARDED = 1<<3;
549    }
550
551    public static final class ConversationColumns {
552        public static final String URI = "conversationUri";
553        /**
554         * This string column contains the content provider uri to return the
555         * list of messages for this conversation.
556         */
557        public static final String MESSAGE_LIST_URI = "messageListUri";
558        /**
559         * This string column contains the subject string for a conversation.
560         */
561        public static final String SUBJECT = "subject";
562        /**
563         * This string column contains the snippet string for a conversation.
564         */
565        public static final String SNIPPET = "snippet";
566        /**
567         * This string column contains the sender info string for a
568         * conversation.
569         */
570        public static final String SENDER_INFO = "senderInfo";
571        /**
572         * This long column contains the time in ms of the latest update to a
573         * conversation.
574         */
575        public static final String DATE_RECEIVED_MS = "dateReceivedMs";
576
577        /**
578         * This boolean column contains whether any messages in this conversation
579         * have attachments.
580         */
581        public static final String HAS_ATTACHMENTS = "hasAttachments";
582
583        /**
584         * This int column contains the number of messages in this conversation.
585         * For unthreaded, this will always be 1.
586         */
587        public static String NUM_MESSAGES = "numMessages";
588
589        /**
590         * This int column contains the number of drafts associated with this
591         * conversation.
592         */
593        public static String NUM_DRAFTS = "numDrafts";
594
595        /**
596         * This int column contains the state of drafts and replies associated
597         * with this conversation. Use ConversationSendingState to interpret
598         * this field.
599         */
600        public static String SENDING_STATE = "sendingState";
601
602        /**
603         * This int column contains the priority of this conversation. Use
604         * ConversationPriority to interpret this field.
605         */
606        public static String PRIORITY = "priority";
607
608        /**
609         * This boolean column indicates whether the conversation has been read
610         */
611        public static String READ = "read";
612
613        /**
614         * This boolean column indicates whether the conversation has been read
615         */
616        public static String STARRED = "starred";
617
618        /**
619         * This string column contains a csv of all folders associated with this
620         * conversation
621         */
622        public static final String FOLDER_LIST = "folderList";
623
624        private ConversationColumns() {
625        }
626    }
627
628    /**
629     * List of operations that can can be performed on a conversation. These operations are applied
630     * with {@link ContentProvider#update(Uri, ContentValues, String, String[])}
631     * where the conversation uri is specified, and the ContentValues specifies the operation to
632     * be performed.
633     * <p/>
634     * The operation to be performed is specified in the ContentValues by
635     * the {@link ConversationOperations#OPERATION_KEY}
636     * <p/>
637     * Note not all UI providers will support these operations.  {@link AccountCapabilities} can
638     * be used to determine which operations are supported.
639     */
640    public static final class ConversationOperations {
641        /**
642         * ContentValues key used to specify the operation to be performed
643         */
644        public static final String OPERATION_KEY = "operation";
645
646        /**
647         * Archive operation
648         */
649        public static final String ARCHIVE = "archive";
650
651        /**
652         * Mute operation
653         */
654        public static final String MUTE = "mute";
655
656        /**
657         * Report spam operation
658         */
659        public static final String REPORT_SPAM = "report_spam";
660
661        private ConversationOperations() {
662        }
663    }
664
665    public static final class DraftType {
666        public static final int NOT_A_DRAFT = 0;
667        public static final int COMPOSE = 1;
668        public static final int REPLY = 2;
669        public static final int REPLY_ALL = 3;
670        public static final int FORWARD = 4;
671
672        private DraftType() {}
673    }
674
675    public static final String[] MESSAGE_PROJECTION = {
676        BaseColumns._ID,
677        MessageColumns.SERVER_ID,
678        MessageColumns.URI,
679        MessageColumns.CONVERSATION_ID,
680        MessageColumns.SUBJECT,
681        MessageColumns.SNIPPET,
682        MessageColumns.FROM,
683        MessageColumns.TO,
684        MessageColumns.CC,
685        MessageColumns.BCC,
686        MessageColumns.REPLY_TO,
687        MessageColumns.DATE_RECEIVED_MS,
688        MessageColumns.BODY_HTML,
689        MessageColumns.BODY_TEXT,
690        MessageColumns.EMBEDS_EXTERNAL_RESOURCES,
691        MessageColumns.REF_MESSAGE_ID,
692        MessageColumns.DRAFT_TYPE,
693        MessageColumns.APPEND_REF_MESSAGE_CONTENT,
694        MessageColumns.HAS_ATTACHMENTS,
695        MessageColumns.ATTACHMENT_LIST_URI,
696        MessageColumns.MESSAGE_FLAGS,
697        MessageColumns.JOINED_ATTACHMENT_INFOS,
698        MessageColumns.SAVE_MESSAGE_URI,
699        MessageColumns.SEND_MESSAGE_URI,
700        MessageColumns.ALWAYS_SHOW_IMAGES
701    };
702
703    /** Separates attachment info parts in strings in a message. */
704    public static final String MESSAGE_ATTACHMENT_INFO_SEPARATOR = "\n";
705    public static final String MESSAGE_LIST_TYPE =
706            "vnd.android.cursor.dir/vnd.com.android.mail.message";
707    public static final String MESSAGE_TYPE =
708            "vnd.android.cursor.item/vnd.com.android.mail.message";
709
710    public static final int MESSAGE_ID_COLUMN = 0;
711    public static final int MESSAGE_SERVER_ID_COLUMN = 1;
712    public static final int MESSAGE_URI_COLUMN = 2;
713    public static final int MESSAGE_CONVERSATION_ID_COLUMN = 3;
714    public static final int MESSAGE_SUBJECT_COLUMN = 4;
715    public static final int MESSAGE_SNIPPET_COLUMN = 5;
716    public static final int MESSAGE_FROM_COLUMN = 6;
717    public static final int MESSAGE_TO_COLUMN = 7;
718    public static final int MESSAGE_CC_COLUMN = 8;
719    public static final int MESSAGE_BCC_COLUMN = 9;
720    public static final int MESSAGE_REPLY_TO_COLUMN = 10;
721    public static final int MESSAGE_DATE_RECEIVED_MS_COLUMN = 11;
722    public static final int MESSAGE_BODY_HTML_COLUMN = 12;
723    public static final int MESSAGE_BODY_TEXT_COLUMN = 13;
724    public static final int MESSAGE_EMBEDS_EXTERNAL_RESOURCES_COLUMN = 14;
725    public static final int MESSAGE_REF_MESSAGE_ID_COLUMN = 15;
726    public static final int MESSAGE_DRAFT_TYPE_COLUMN = 16;
727    public static final int MESSAGE_APPEND_REF_MESSAGE_CONTENT_COLUMN = 17;
728    public static final int MESSAGE_HAS_ATTACHMENTS_COLUMN = 18;
729    public static final int MESSAGE_ATTACHMENT_LIST_URI_COLUMN = 19;
730    public static final int MESSAGE_FLAGS_COLUMN = 20;
731    public static final int MESSAGE_JOINED_ATTACHMENT_INFOS_COLUMN = 21;
732    public static final int MESSAGE_SAVE_URI_COLUMN = 22;
733    public static final int MESSAGE_SEND_URI_COLUMN = 23;
734    public static final int ALWAYS_SHOW_IMAGES_COLUMN = 24;
735
736    public static final class MessageFlags {
737        public static final int STARRED =       1 << 0;
738        public static final int UNREAD =        1 << 1;
739        public static final int REPLIED =       1 << 2;
740        public static final int FORWARDED =     1 << 3;
741    }
742
743    public static final class MessageColumns {
744        /**
745         * This string column contains a content provider URI that points to this single message.
746         */
747        public static final String URI = "messageUri";
748        /**
749         * This string column contains a server-assigned ID for this message.
750         */
751        public static final String SERVER_ID = "serverMessageId";
752        public static final String CONVERSATION_ID = "conversationId";
753        /**
754         * This string column contains the subject of a message.
755         */
756        public static final String SUBJECT = "subject";
757        /**
758         * This string column contains a snippet of the message body.
759         */
760        public static final String SNIPPET = "snippet";
761        /**
762         * This string column contains the single email address (and optionally name) of the sender.
763         */
764        public static final String FROM = "fromAddress";
765        /**
766         * This string column contains a comma-delimited list of "To:" recipient email addresses.
767         */
768        public static final String TO = "toAddresses";
769        /**
770         * This string column contains a comma-delimited list of "CC:" recipient email addresses.
771         */
772        public static final String CC = "ccAddresses";
773        /**
774         * This string column contains a comma-delimited list of "BCC:" recipient email addresses.
775         * This value will be null for incoming messages.
776         */
777        public static final String BCC = "bccAddresses";
778        /**
779         * This string column contains the single email address (and optionally name) of the
780         * sender's reply-to address.
781         */
782        public static final String REPLY_TO = "replyToAddress";
783        /**
784         * This long column contains the timestamp (in millis) of receipt of the message.
785         */
786        public static final String DATE_RECEIVED_MS = "dateReceivedMs";
787        /**
788         * This string column contains the HTML form of the message body, if available. If not,
789         * a provider must populate BODY_TEXT.
790         */
791        public static final String BODY_HTML = "bodyHtml";
792        /**
793         * This string column contains the plaintext form of the message body, if HTML is not
794         * otherwise available. If HTML is available, this value should be left empty (null).
795         */
796        public static final String BODY_TEXT = "bodyText";
797        public static final String EMBEDS_EXTERNAL_RESOURCES = "bodyEmbedsExternalResources";
798        /**
799         * This string column contains an opaque string used by the sendMessage api.
800         */
801        public static final String REF_MESSAGE_ID = "refMessageId";
802        /**
803         * This integer column contains the type of this draft, or zero (0) if this message is not a
804         * draft. See {@link DraftType} for possible values.
805         */
806        public static final String DRAFT_TYPE = "draftType";
807        /**
808         * This boolean column indicates whether an outgoing message should trigger special quoted
809         * text processing upon send. The value should default to zero (0) for protocols that do
810         * not support or require this flag, and for all incoming messages.
811         */
812        public static final String APPEND_REF_MESSAGE_CONTENT = "appendRefMessageContent";
813        /**
814         * This boolean column indicates whether a message has attachments. The list of attachments
815         * can be retrieved using the URI in {@link MessageColumns#ATTACHMENT_LIST_URI}.
816         */
817        public static final String HAS_ATTACHMENTS = "hasAttachments";
818        /**
819         * This string column contains the content provider URI for the list of
820         * attachments associated with this message.
821         */
822        public static final String ATTACHMENT_LIST_URI = "attachmentListUri";
823        /**
824         * This long column is a bit field of flags defined in {@link MessageFlags}.
825         */
826        public static final String MESSAGE_FLAGS = "messageFlags";
827        /**
828         * This string column contains a specially formatted string representing all
829         * attachments that we added to a message that is being sent or saved.
830         */
831        public static final String JOINED_ATTACHMENT_INFOS = "joinedAttachmentInfos";
832        /**
833         * This string column contains the content provider URI for saving this
834         * message.
835         */
836        public static final String SAVE_MESSAGE_URI = "saveMessageUri";
837        /**
838         * This string column contains content provider URI for sending this
839         * message.
840         */
841        public static final String SEND_MESSAGE_URI = "sendMessageUri";
842
843        /**
844         * This integer column represents whether the user has specified that images should always
845         * be shown.  The value of "1" indicates that the user has specified that images should be
846         * shown, while the value of "0" indicates that the user should be prompted before loading
847         * any external images.
848         */
849        public static final String ALWAYS_SHOW_IMAGES = "alwaysShowImages";
850
851        private MessageColumns() {}
852    }
853
854    public static final String ATTACHMENT_LIST_TYPE =
855            "vnd.android.cursor.dir/vnd.com.android.mail.attachment";
856    public static final String ATTACHMENT_TYPE =
857            "vnd.android.cursor.item/vnd.com.android.mail.attachment";
858
859    public static final String[] ATTACHMENT_PROJECTION = {
860        AttachmentColumns.NAME,
861        AttachmentColumns.SIZE,
862        AttachmentColumns.URI,
863        AttachmentColumns.CONTENT_TYPE,
864        AttachmentColumns.STATE,
865        AttachmentColumns.DESTINATION,
866        AttachmentColumns.DOWNLOADED_SIZE,
867        AttachmentColumns.CONTENT_URI,
868        AttachmentColumns.THUMBNAIL_URI,
869        AttachmentColumns.PREVIEW_INTENT
870    };
871    private static final String EMAIL_SEPARATOR_PATTERN = "\n";
872    public static final int ATTACHMENT_NAME_COLUMN = 0;
873    public static final int ATTACHMENT_SIZE_COLUMN = 1;
874    public static final int ATTACHMENT_URI_COLUMN = 2;
875    public static final int ATTACHMENT_CONTENT_TYPE_COLUMN = 3;
876    public static final int ATTACHMENT_STATE_COLUMN = 4;
877    public static final int ATTACHMENT_DESTINATION_COLUMN = 5;
878    public static final int ATTACHMENT_DOWNLOADED_SIZE_COLUMN = 6;
879    public static final int ATTACHMENT_CONTENT_URI_COLUMN = 7;
880    public static final int ATTACHMENT_THUMBNAIL_URI_COLUMN = 8;
881    public static final int ATTACHMENT_PREVIEW_INTENT_COLUMN = 9;
882
883    /**
884     * Valid states for the {@link AttachmentColumns#STATE} column.
885     *
886     */
887    public static final class AttachmentState {
888        /**
889         * The full attachment is not present on device. When used as a command,
890         * setting this state will tell the provider to cancel a download in
891         * progress.
892         * <p>
893         * Valid next states: {@link #DOWNLOADING}
894         */
895        public static final int NOT_SAVED = 0;
896        /**
897         * The most recent attachment download attempt failed. The current UI
898         * design does not require providers to persist this state, but
899         * providers must return this state at least once after a download
900         * failure occurs. This state may not be used as a command.
901         * <p>
902         * Valid next states: {@link #DOWNLOADING}
903         */
904        public static final int FAILED = 1;
905        /**
906         * The attachment is currently being downloaded by the provider.
907         * {@link AttachmentColumns#DOWNLOADED_SIZE} should reflect the current
908         * download progress while in this state. When used as a command,
909         * setting this state will tell the provider to initiate a download to
910         * the accompanying destination in {@link AttachmentColumns#DESTINATION}
911         * .
912         * <p>
913         * Valid next states: {@link #NOT_SAVED}, {@link #FAILED},
914         * {@link #SAVED}
915         */
916        public static final int DOWNLOADING = 2;
917        /**
918         * The attachment was successfully downloaded to the destination in
919         * {@link AttachmentColumns#DESTINATION}. If a provider later detects
920         * that a download is missing, it should reset the state to
921         * {@link #NOT_SAVED}. This state may not be used as a command on its
922         * own. To move a file from cache to external, update
923         * {@link AttachmentColumns#DESTINATION}.
924         * <p>
925         * Valid next states: {@link #NOT_SAVED}
926         */
927        public static final int SAVED = 3;
928
929        private AttachmentState() {}
930    }
931
932    public static final class AttachmentDestination {
933
934        /**
935         * The attachment will be or is already saved to the app-private cache partition.
936         */
937        public static final int CACHE = 0;
938        /**
939         * The attachment will be or is already saved to external shared device storage.
940         */
941        public static final int EXTERNAL = 1;
942
943        private AttachmentDestination() {}
944    }
945
946    public static final class AttachmentColumns {
947        /**
948         * This string column is the attachment's file name, intended for display in UI. It is not
949         * the full path of the file.
950         */
951        public static final String NAME = "name";
952        /**
953         * This integer column is the file size of the attachment, in bytes.
954         */
955        public static final String SIZE = "size";
956        /**
957         * This column is a {@link Uri} that can be queried to monitor download state and progress
958         * for this individual attachment (resulting cursor has one single row for this attachment).
959         */
960        public static final String URI = "uri";
961        /**
962         * This string column is the MIME type of the attachment.
963         */
964        public static final String CONTENT_TYPE = "contentType";
965        /**
966         * This integer column is the current downloading state of the
967         * attachment as defined in {@link AttachmentState}.
968         * <p>
969         * Providers must accept updates to {@link URI} with new values of
970         * this column to initiate or cancel downloads.
971         */
972        public static final String STATE = "state";
973        /**
974         * This integer column is the file destination for the current download
975         * in progress (when {@link #STATE} is
976         * {@link AttachmentState#DOWNLOADING}) or the resulting downloaded file
977         * ( when {@link #STATE} is {@link AttachmentState#SAVED}), as defined
978         * in {@link AttachmentDestination}. This value is undefined in any
979         * other state.
980         * <p>
981         * Providers must accept updates to {@link URI} with new values of
982         * this column to move an existing downloaded file.
983         */
984        public static final String DESTINATION = "destination";
985        /**
986         * This integer column is the current number of bytes downloaded when
987         * {@link #STATE} is {@link AttachmentState#DOWNLOADING}. This value is
988         * undefined in any other state.
989         */
990        public static final String DOWNLOADED_SIZE = "downloadedSize";
991        /**
992         * This column is a {@link Uri} that points to the downloaded local file
993         * when {@link #STATE} is {@link AttachmentState#SAVED}. This value is
994         * undefined in any other state.
995         */
996        public static final String CONTENT_URI = "contentUri";
997        /**
998         * This column is a {@link Uri} that points to a local thumbnail file
999         * for the attachment. Providers that do not support downloading
1000         * attachment thumbnails may leave this null.
1001         */
1002        public static final String THUMBNAIL_URI = "thumbnailUri";
1003        /**
1004         * This column is an {@link Intent} to launch a preview activity that
1005         * allows the user to efficiently view an attachment without having to
1006         * first download the entire file. Providers that do not support
1007         * previewing attachments may leave this null. The intent is represented
1008         * as a byte-array blob generated by writing an Intent to a parcel and
1009         * then marshaling that parcel.
1010         */
1011        public static final String PREVIEW_INTENT = "previewIntent";
1012
1013        private AttachmentColumns() {}
1014    }
1015
1016    public static int getMailMaxAttachmentSize(String account) {
1017        // TODO: query the account to see what the max attachment size is?
1018        return 5 * 1024 * 1024;
1019    }
1020
1021    public static String getAttachmentTypeSetting() {
1022        // TODO: query the account to see what kinds of attachments it supports?
1023        return "com.google.android.gm.allowAddAnyAttachment";
1024    }
1025
1026    public static void incrementRecipientsTimesContacted(Context context, String addressString) {
1027        DataUsageStatUpdater statsUpdater = new DataUsageStatUpdater(context);
1028        ArrayList<String> recipients = new ArrayList<String>();
1029        String[] addresses = TextUtils.split(addressString, EMAIL_SEPARATOR_PATTERN);
1030        for (String address : addresses) {
1031            recipients.add(address);
1032        }
1033        statsUpdater.updateWithAddress(recipients);
1034    }
1035
1036    public static final String[] UNDO_PROJECTION = {
1037        ConversationColumns.MESSAGE_LIST_URI
1038    };
1039    public static final int UNDO_MESSAGE_LIST_COLUMN = 0;
1040
1041    // Parameter used to indicate the sequence number for an undoable operation
1042    public static final String SEQUENCE_QUERY_PARAMETER = "seq";
1043
1044
1045    public static final String[] SETTINGS_PROJECTION = {
1046            SettingsColumns.SIGNATURE,
1047            SettingsColumns.AUTO_ADVANCE,
1048            SettingsColumns.MESSAGE_TEXT_SIZE,
1049            SettingsColumns.SNAP_HEADERS,
1050            SettingsColumns.REPLY_BEHAVIOR,
1051            SettingsColumns.HIDE_CHECKBOXES,
1052            SettingsColumns.CONFIRM_DELETE,
1053            SettingsColumns.CONFIRM_ARCHIVE,
1054            SettingsColumns.CONFIRM_SEND,
1055            SettingsColumns.DEFAULT_INBOX
1056    };
1057
1058    public static final int SETTINGS_SIGNATURE_COLUMN = 0;
1059    public static final int SETTINGS_AUTO_ADVANCE_COLUMN = 1;
1060    public static final int SETTINGS_MESSAGE_TEXT_SIZE_COLUMN = 2;
1061    public static final int SETTINGS_SNAP_HEADERS_COLUMN = 3;
1062    public static final int SETTINGS_REPLY_BEHAVIOR_COLUMN = 4;
1063    public static final int SETTINGS_HIDE_CHECKBOXES_COLUMN = 5;
1064    public static final int SETTINGS_CONFIRM_DELETE_COLUMN = 6;
1065    public static final int SETTINGS_CONFIRM_ARCHIVE_COLUMN = 7;
1066    public static final int SETTINGS_CONFIRM_SEND_COLUMN = 8;
1067    public static final int SETTINGS_DEFAULT_INBOX_COLUMN = 9;
1068
1069    public static final class AutoAdvance {
1070        public static final int UNSET = 0;
1071        public static final int OLDER = 1;
1072        public static final int NEWER = 2;
1073        public static final int LIST = 3;
1074    }
1075
1076    public static final class SnapHeaderValue {
1077        public static final int ALWAYS = 0;
1078        public static final int PORTRAIT_ONLY = 1;
1079        public static final int NEVER = 2;
1080    }
1081
1082    public static final class MessageTextSize {
1083        public static final int TINY = -2;
1084        public static final int SMALL = -1;
1085        public static final int NORMAL = 0;
1086        public static final int LARGE = 1;
1087        public static final int HUGE = 2;
1088    }
1089
1090    public static final class DefaultReplyBehavior {
1091        public static final int REPLY = 0;
1092        public static final int REPLY_ALL = 1;
1093    }
1094
1095    public static final class SettingsColumns {
1096        /**
1097         * String column containing the contents of the signature for this account.  If no
1098         * signature has been specified, the value will be null.
1099         */
1100        public static final String SIGNATURE = "signature";
1101
1102        /**
1103         * Integer column containing the user's specified auto-advance policy.  This value will be
1104         * one of the values in {@link UIProvider.AutoAdvance}
1105         */
1106        public static final String AUTO_ADVANCE = "auto_advance";
1107
1108        /**
1109         * Integer column containing the user's specified message text size preference.  This value
1110         * will be one of the values in {@link UIProvider.MessageTextSize}
1111         */
1112        public static final String MESSAGE_TEXT_SIZE = "message_text_size";
1113
1114        /**
1115         * Integer column contaning the user's specified snap header preference.  This value
1116         * will be one of the values in {@link UIProvider.SnapHeaderValue}
1117         */
1118        public static final String SNAP_HEADERS = "snap_headers";
1119
1120        /**
1121         * Integer column containing the user's specified default reply behavior.  This value will
1122         * be one of the values in {@link UIProvider.DefaultReplyBehavior}
1123         */
1124        public static final String REPLY_BEHAVIOR = "reply_behavior";
1125
1126        /**
1127         * Integer column containing the user's specified checkbox preference. A
1128         * non zero value means to hide checkboxes.
1129         */
1130        public static final String HIDE_CHECKBOXES = "hide_checkboxes";
1131
1132        /**
1133         * Integer column containing the user's specified confirm delete preference value.
1134         * A non zero value indicates that the user has indicated that a confirmation should
1135         * be shown when a delete action is performed.
1136         */
1137        public static final String CONFIRM_DELETE = "confirm_delete";
1138
1139        /**
1140         * Integer column containing the user's specified confirm archive preference value.
1141         * A non zero value indicates that the user has indicated that a confirmation should
1142         * be shown when an archive action is performed.
1143         */
1144        public static final String CONFIRM_ARCHIVE = "confirm_archive";
1145
1146        /**
1147         * Integer column containing the user's specified confirm send preference value.
1148         * A non zero value indicates that the user has indicated that a confirmation should
1149         * be shown when a send action is performed.
1150         */
1151        public static final String CONFIRM_SEND = "confirm_send";
1152        /**
1153         * String folder containing the serialized default inbox folder for an account.
1154         */
1155        public static final String DEFAULT_INBOX = "default_inbox";
1156    }
1157}
1158