UIProvider.java revision a9a05d566650f31f09191eda0ba61af843bd4cd8
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 com.google.common.collect.ImmutableMap;
21
22import android.content.ContentProvider;
23import android.content.ContentValues;
24import android.content.Context;
25import android.content.Intent;
26import android.net.Uri;
27import android.provider.BaseColumns;
28import android.provider.OpenableColumns;
29import android.text.TextUtils;
30import android.text.util.Rfc822Token;
31import android.text.util.Rfc822Tokenizer;
32
33import com.android.common.contacts.DataUsageStatUpdater;
34
35import java.util.ArrayList;
36import java.util.HashMap;
37
38public class UIProvider {
39    public static final String EMAIL_SEPARATOR = ",";
40    public static final long INVALID_CONVERSATION_ID = -1;
41    public static final long INVALID_MESSAGE_ID = -1;
42
43    /**
44     * Values for the current state of a Folder/Account; note that it's possible that more than one
45     * sync is in progress
46     */
47    public static final class SyncStatus {
48        /**
49         * No sync in progress
50         */
51        public static final int NO_SYNC = 0;
52        /**
53         * A user-requested sync/refresh is in progress. This occurs when the user taps on the
54         * refresh icon in the action bar.
55         */
56        public static final int USER_REFRESH = 1<<0;
57        /**
58         * A user-requested live query is in progress. This occurs when the user goes past the end
59         * of the fetched results in the conversation list.
60         */
61        public static final int LIVE_QUERY = 1<<1;
62        /** Please use the constant {@link #LIVE_QUERY} instead. */
63        @Deprecated
64        public static final int USER_QUERY = 1<<1;
65        /**
66         * A background sync is in progress. This happens on <b>no</b> user interaction.
67         */
68        public static final int BACKGROUND_SYNC = 1<<2;
69        /**
70         * An initial sync is needed for this Account/Folder to be used. This is account-wide, when
71         * the user has added an account, and the first sync has not completed successfully.
72         */
73        public static final int INITIAL_SYNC_NEEDED = 1<<3;
74        /**
75         * Manual sync is required. This is account-wide, when the user has disabled sync on the
76         * Gmail account.
77         */
78        public static final int MANUAL_SYNC_REQUIRED = 1<<4;
79        /**
80         * Account initialization is required.
81         */
82        public static final int ACCOUNT_INITIALIZATION_REQUIRED = 1<<5;
83
84        public static boolean isSyncInProgress(int syncStatus) {
85            return 0 != (syncStatus & (BACKGROUND_SYNC |
86                    USER_REFRESH |
87                    LIVE_QUERY |
88                    USER_MORE_RESULTS));
89        }
90        /**
91         * Unused currently, is not used by any provider.
92         * TODO(viki): Remove.
93         */
94        public static final int USER_MORE_RESULTS = 1<<5;
95    }
96
97    /**
98     * Values for the result of the last attempted sync of a Folder/Account
99     */
100    public static final class LastSyncResult {
101        /** The sync completed successfully */
102        public static final int SUCCESS = 0;
103        /** The sync wasn't completed due to a connection error */
104        public static final int CONNECTION_ERROR = 1;
105        /** The sync wasn't completed due to an authentication error */
106        public static final int AUTH_ERROR = 2;
107        /** The sync wasn't completed due to a security error */
108        public static final int SECURITY_ERROR = 3;
109        /** The sync wasn't completed due to a low memory condition */
110        public static final int STORAGE_ERROR = 4;
111        /** The sync wasn't completed due to an internal error/exception */
112        public static final int INTERNAL_ERROR = 5;
113    }
114
115    // The actual content provider should define its own authority
116    public static final String AUTHORITY = "com.android.mail.providers";
117
118    public static final String ACCOUNT_LIST_TYPE =
119            "vnd.android.cursor.dir/vnd.com.android.mail.account";
120    public static final String ACCOUNT_TYPE =
121            "vnd.android.cursor.item/vnd.com.android.mail.account";
122
123    /**
124     * Query parameter key that can be used to control the behavior of list queries.  The value
125     * must be a serialized {@link ListParams} object.  UIProvider implementations are not
126     * required to respect this query parameter
127     */
128    public static final String LIST_PARAMS_QUERY_PARAMETER = "listParams";
129
130    public static final String[] ACCOUNTS_PROJECTION = {
131            BaseColumns._ID,
132            AccountColumns.NAME,
133            AccountColumns.PROVIDER_VERSION,
134            AccountColumns.URI,
135            AccountColumns.CAPABILITIES,
136            AccountColumns.FOLDER_LIST_URI,
137            AccountColumns.FULL_FOLDER_LIST_URI,
138            AccountColumns.SEARCH_URI,
139            AccountColumns.ACCOUNT_FROM_ADDRESSES,
140            AccountColumns.SAVE_DRAFT_URI,
141            AccountColumns.SEND_MAIL_URI,
142            AccountColumns.EXPUNGE_MESSAGE_URI,
143            AccountColumns.UNDO_URI,
144            AccountColumns.SETTINGS_INTENT_URI,
145            AccountColumns.SYNC_STATUS,
146            AccountColumns.HELP_INTENT_URI,
147            AccountColumns.SEND_FEEDBACK_INTENT_URI,
148            AccountColumns.REAUTHENTICATION_INTENT_URI,
149            AccountColumns.COMPOSE_URI,
150            AccountColumns.MIME_TYPE,
151            AccountColumns.RECENT_FOLDER_LIST_URI,
152            AccountColumns.COLOR,
153            AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI,
154            AccountColumns.MANUAL_SYNC_URI,
155            AccountColumns.VIEW_INTENT_PROXY_URI,
156            AccountColumns.ACCOUNT_COOKIE_QUERY_URI,
157            AccountColumns.SettingsColumns.SIGNATURE,
158            AccountColumns.SettingsColumns.AUTO_ADVANCE,
159            AccountColumns.SettingsColumns.MESSAGE_TEXT_SIZE,
160            AccountColumns.SettingsColumns.SNAP_HEADERS,
161            AccountColumns.SettingsColumns.REPLY_BEHAVIOR,
162            AccountColumns.SettingsColumns.HIDE_CHECKBOXES,
163            AccountColumns.SettingsColumns.CONFIRM_DELETE,
164            AccountColumns.SettingsColumns.CONFIRM_ARCHIVE,
165            AccountColumns.SettingsColumns.CONFIRM_SEND,
166            AccountColumns.SettingsColumns.DEFAULT_INBOX,
167            AccountColumns.SettingsColumns.DEFAULT_INBOX_NAME,
168            AccountColumns.SettingsColumns.FORCE_REPLY_FROM_DEFAULT,
169            AccountColumns.SettingsColumns.MAX_ATTACHMENT_SIZE,
170            AccountColumns.SettingsColumns.SWIPE,
171            AccountColumns.SettingsColumns.PRIORITY_ARROWS_ENABLED,
172            AccountColumns.SettingsColumns.SETUP_INTENT_URI,
173            AccountColumns.SettingsColumns.CONVERSATION_VIEW_MODE
174    };
175
176    public static final int ACCOUNT_ID_COLUMN = 0;
177    public static final int ACCOUNT_NAME_COLUMN = 1;
178    public static final int ACCOUNT_PROVIDER_VERISON_COLUMN = 2;
179    public static final int ACCOUNT_URI_COLUMN = 3;
180    public static final int ACCOUNT_CAPABILITIES_COLUMN = 4;
181    public static final int ACCOUNT_FOLDER_LIST_URI_COLUMN = 5;
182    public static final int ACCOUNT_FULL_FOLDER_LIST_URI_COLUMN = 6;
183    public static final int ACCOUNT_SEARCH_URI_COLUMN = 7;
184    public static final int ACCOUNT_FROM_ADDRESSES_COLUMN = 8;
185    public static final int ACCOUNT_SAVE_DRAFT_URI_COLUMN = 9;
186    public static final int ACCOUNT_SEND_MESSAGE_URI_COLUMN = 10;
187    public static final int ACCOUNT_EXPUNGE_MESSAGE_URI_COLUMN = 11;
188    public static final int ACCOUNT_UNDO_URI_COLUMN = 12;
189    public static final int ACCOUNT_SETTINGS_INTENT_URI_COLUMN = 13;
190    public static final int ACCOUNT_SYNC_STATUS_COLUMN = 14;
191    public static final int ACCOUNT_HELP_INTENT_URI_COLUMN = 15;
192    public static final int ACCOUNT_SEND_FEEDBACK_INTENT_URI_COLUMN = 16;
193    public static final int ACCOUNT_REAUTHENTICATION_INTENT_URI_COLUMN = 17;
194    public static final int ACCOUNT_COMPOSE_INTENT_URI_COLUMN = 18;
195    public static final int ACCOUNT_MIME_TYPE_COLUMN = 19;
196    public static final int ACCOUNT_RECENT_FOLDER_LIST_URI_COLUMN = 20;
197    public static final int ACCOUNT_COLOR_COLUMN = 21;
198    public static final int ACCOUNT_DEFAULT_RECENT_FOLDER_LIST_URI_COLUMN = 22;
199    public static final int ACCOUNT_MANUAL_SYNC_URI_COLUMN = 23;
200    public static final int ACCOUNT_VIEW_INTENT_PROXY_URI_COLUMN = 24;
201    public static final int ACCOUNT_COOKIE_QUERY_URI_COLUMN = 25;
202
203    public static final int ACCOUNT_SETTINGS_SIGNATURE_COLUMN = 26;
204    public static final int ACCOUNT_SETTINGS_AUTO_ADVANCE_COLUMN = 27;
205    public static final int ACCOUNT_SETTINGS_MESSAGE_TEXT_SIZE_COLUMN = 28;
206    public static final int ACCOUNT_SETTINGS_SNAP_HEADERS_COLUMN = 29;
207    public static final int ACCOUNT_SETTINGS_REPLY_BEHAVIOR_COLUMN = 30;
208    public static final int ACCOUNT_SETTINGS_HIDE_CHECKBOXES_COLUMN = 31;
209    public static final int ACCOUNT_SETTINGS_CONFIRM_DELETE_COLUMN = 32;
210    public static final int ACCOUNT_SETTINGS_CONFIRM_ARCHIVE_COLUMN = 33;
211    public static final int ACCOUNT_SETTINGS_CONFIRM_SEND_COLUMN = 34;
212    public static final int ACCOUNT_SETTINGS_DEFAULT_INBOX_COLUMN = 35;
213    public static final int ACCOUNT_SETTINGS_DEFAULT_INBOX_NAME_COLUMN = 36;
214    public static final int ACCOUNT_SETTINGS_FORCE_REPLY_FROM_DEFAULT_COLUMN = 37;
215    public static final int ACCOUNT_SETTINGS_MAX_ATTACHMENT_SIZE_COLUMN = 38;
216    public static final int ACCOUNT_SETTINGS_SWIPE_COLUMN = 39;
217    public static final int ACCOUNT_SETTINGS_PRIORITY_ARROWS_ENABLED_COLUMN = 40;
218    public static final int ACCOUNT_SETTINGS_SETUP_INTENT_URI = 41;
219    public static final int ACCOUNT_SETTINGS_CONVERSATION_MODE_COLUMN = 42;
220
221    public static final class AccountCapabilities {
222        /**
223         * Whether folders can be synchronized back to the server.
224         */
225        public static final int SYNCABLE_FOLDERS = 0x0001;
226        /**
227         * Whether the server allows reporting spam back.
228         */
229        public static final int REPORT_SPAM = 0x0002;
230        /**
231         * Whether the server allows reporting phishing back.
232         */
233        public static final int REPORT_PHISHING = 0x0004;
234        /**
235         * Whether the server supports a concept of Archive: removing mail from the Inbox but
236         * keeping it around.
237         */
238        public static final int ARCHIVE = 0x0008;
239        /**
240         * Whether the server will stop notifying on updates to this thread? This requires
241         * THREADED_CONVERSATIONS to be true, otherwise it should be ignored.
242         */
243        public static final int MUTE = 0x0010;
244        /**
245         * Whether the server supports searching over all messages. This requires SYNCABLE_FOLDERS
246         * to be true, otherwise it should be ignored.
247         */
248        public static final int SERVER_SEARCH = 0x0020;
249        /**
250         * Whether the server supports constraining search to a single folder. Requires
251         * SYNCABLE_FOLDERS, otherwise it should be ignored.
252         */
253        public static final int FOLDER_SERVER_SEARCH = 0x0040;
254        /**
255         * Whether the server sends us sanitized HTML (guaranteed to not contain malicious HTML).
256         */
257        public static final int SANITIZED_HTML = 0x0080;
258        /**
259         * Whether the server allows synchronization of draft messages. This does NOT require
260         * SYNCABLE_FOLDERS to be set.
261         */
262        public static final int DRAFT_SYNCHRONIZATION = 0x0100;
263        /**
264         * Does the server allow the user to compose mails (and reply) using addresses other than
265         * their account name? For instance, GMail allows users to set FROM addresses that are
266         * different from account@gmail.com address. For instance, user@gmail.com could have another
267         * FROM: address like user@android.com. If the user has enabled multiple FROM address, he
268         * can compose (and reply) using either address.
269         */
270        public static final int MULTIPLE_FROM_ADDRESSES = 0x0200;
271        /**
272         * Whether the server allows the original message to be included in the reply by setting a
273         * flag on the reply. If we can avoid including the entire previous message, we save on
274         * bandwidth (replies are shorter).
275         */
276        public static final int SMART_REPLY = 0x0400;
277        /**
278         * Does this account support searching locally, on the device? This requires the backend
279         * storage to support a mechanism for searching.
280         */
281        public static final int LOCAL_SEARCH = 0x0800;
282        /**
283         * Whether the server supports a notion of threaded conversations: where replies to messages
284         * are tagged to keep conversations grouped. This could be full threading (each message
285         * lists its parent) or conversation-level threading (each message lists one conversation
286         * which it belongs to)
287         */
288        public static final int THREADED_CONVERSATIONS = 0x1000;
289        /**
290         * Whether the server supports allowing a conversation to be in multiple folders. (Or allows
291         * multiple folders on a single conversation)
292         */
293        public static final int MULTIPLE_FOLDERS_PER_CONV = 0x2000;
294        /**
295         * Whether the provider supports undoing operations. If it doesn't, never show the undo bar.
296         */
297        public static final int UNDO = 0x4000;
298        /**
299         * Whether the account provides help content.
300         */
301        public static final int HELP_CONTENT = 0x8000;
302        /**
303         * Whether the account provides a way to send feedback content.
304         */
305        public static final int SEND_FEEDBACK = 0x10000;
306        /**
307         * Whether the account provides a mechanism for marking conversations as important.
308         */
309        public static final int MARK_IMPORTANT = 0x20000;
310        /**
311         * Whether initial conversation queries should use a limit parameter
312         */
313        public static final int INITIAL_CONVERSATION_LIMIT = 0x40000;
314        /**
315         * Whether the account cannot be used for sending
316         */
317        public static final int SENDING_UNAVAILABLE = 0x80000;
318        /**
319         * Whether the account supports discarding drafts from a conversation.  This should be
320         * removed when all providers support this capability
321         */
322        public static final int DISCARD_CONVERSATION_DRAFTS = 0x100000;
323    }
324
325    public static final class AccountColumns {
326        /**
327         * This string column contains the human visible name for the account.
328         */
329        public static final String NAME = "name";
330
331        /**
332         * This integer contains the type of the account: Google versus non google. This is not
333         * returned by the UIProvider, rather this is a notion in the system.
334         */
335        public static final String TYPE = "type";
336
337        /**
338         * This integer column returns the version of the UI provider schema from which this
339         * account provider will return results.
340         */
341        public static final String PROVIDER_VERSION = "providerVersion";
342
343        /**
344         * This string column contains the uri to directly access the information for this account.
345         */
346        public static final String URI = "accountUri";
347
348        /**
349         * This integer column contains a bit field of the possible capabilities that this account
350         * supports.
351         */
352        public static final String CAPABILITIES = "capabilities";
353
354        /**
355         * This string column contains the content provider uri to return the
356         * list of top level folders for this account.
357         */
358        public static final String FOLDER_LIST_URI = "folderListUri";
359
360        /**
361         * This string column contains the content provider uri to return the
362         * list of all folders for this account.
363         */
364        public static final String FULL_FOLDER_LIST_URI = "fullFolderListUri";
365
366        /**
367         * This string column contains the content provider uri that can be queried for search
368         * results.
369         * The supported query parameters are limited to those listed
370         * in {@link SearchQueryParameters}
371         * The cursor returned from this query is expected have one row, where the columnm are a
372         * subset of the columns specified in {@link FolderColumns}
373         */
374        public static final String SEARCH_URI = "searchUri";
375
376        /**
377         * This string column contains a json array of json objects representing
378         * custom from addresses for this account or null if there are none.
379         */
380        public static final String ACCOUNT_FROM_ADDRESSES = "accountFromAddresses";
381
382        /**
383         * This string column contains the content provider uri that can be used to save (insert)
384         * new draft messages for this account. NOTE: This might be better to
385         * be an update operation on the messageUri.
386         */
387        @Deprecated
388        public static final String SAVE_DRAFT_URI = "saveDraftUri";
389
390        /**
391         * This string column contains the content provider uri that can be used to send
392         * a message for this account.
393         * NOTE: This might be better to be an update operation on the messageUri.
394         */
395        @Deprecated
396        public static final String SEND_MAIL_URI = "sendMailUri";
397
398        /**
399         * This string column contains the content provider uri that can be used
400         * to expunge a message from this account. NOTE: This might be better to
401         * be an update operation on the messageUri.
402         * When {@link android.content.ContentResolver#update(Uri, ContentValues, String, String[])}
403         * is called with this uri, the {@link ContentValues} object is expected to have
404         * {@link BaseColumns#_ID} specified with the local message id of the message.
405         */
406        public static final String EXPUNGE_MESSAGE_URI = "expungeMessageUri";
407
408        /**
409         * This string column contains the content provider uri that can be used
410         * to undo the last committed action.
411         */
412        public static final String UNDO_URI = "undoUri";
413
414        /**
415         * Uri for EDIT intent that will cause the settings screens for this account type to be
416         * shown.
417         * Optionally, extra values from {@link EditSettingsExtras} can be used to indicate
418         * which settings the user wants to edit.
419         * TODO: When we want to support a heterogeneous set of account types, this value may need
420         * to be moved to a global content provider.
421         */
422        public static String SETTINGS_INTENT_URI = "accountSettingsIntentUri";
423
424        /**
425         * Uri for VIEW intent that will cause the help screens for this account type to be
426         * shown.
427         * TODO: When we want to support a heterogeneous set of account types, this value may need
428         * to be moved to a global content provider.
429         */
430        public static String HELP_INTENT_URI = "helpIntentUri";
431
432        /**
433         * Uri for VIEW intent that will cause the send feedback for this account type to be
434         * shown.
435         * TODO: When we want to support a heterogeneous set of account types, this value may need
436         * to be moved to a global content provider.
437         */
438        public static String SEND_FEEDBACK_INTENT_URI = "sendFeedbackIntentUri";
439
440        /**
441         * Uri for VIEW intent that will cause the user to be prompted for authentication for
442         * this account.  startActivityForResult() will be called with this intent. Activities that
443         * handle this intent are expected to return {@link android.app.Activity#RESULT_OK} if the
444         * user successfully authenticated.
445         */
446        public static String REAUTHENTICATION_INTENT_URI = "reauthenticationUri";
447
448        /**
449         * This int column contains the current sync status of the account (the logical AND of the
450         * sync status of folders in this account)
451         */
452        public static final String SYNC_STATUS = "syncStatus";
453        /**
454         * Uri for VIEW intent that will cause the compose screens for this type
455         * of account to be shown.
456         */
457        public static final String COMPOSE_URI = "composeUri";
458        /**
459         * Mime-type defining this account.
460         */
461        public static final String MIME_TYPE = "mimeType";
462        /**
463         * URI for location of recent folders viewed on this account.
464         */
465        public static final String RECENT_FOLDER_LIST_URI = "recentFolderListUri";
466        /**
467         * URI for default recent folders for this account, if any.
468         */
469        public static final String DEFAULT_RECENT_FOLDER_LIST_URI = "defaultRecentFolderListUri";
470        /**
471         * Color used for this account (for Email/Combined view)
472         */
473        public static final String COLOR = "color";
474        /**
475         * URI for forcing a manual sync of this account.
476         */
477        public static final String MANUAL_SYNC_URI = "manualSyncUri";
478        /**
479         * Optional URI of this account for proxying view intents.
480         */
481        public static final String VIEW_INTENT_PROXY_URI = "viewProxyUri";
482        /**
483         * Optional URI for querying for the cookie needed for accessing inline content.  The cookie
484         * specified here will be set on the uri specified in the
485         * {@link ConversationColumns#CONVERSATION_BASE_URI} column. The cursor returned from this
486         * query is expected have one row, where the columns are specified in
487         * {@link AccountCookieColumns}
488         */
489        public static final String ACCOUNT_COOKIE_QUERY_URI = "accountCookieUri";
490
491        public static final class SettingsColumns {
492            /**
493             * String column containing the contents of the signature for this account.  If no
494             * signature has been specified, the value will be null.
495             */
496            public static final String SIGNATURE = "signature";
497
498            /**
499             * Integer column containing the user's specified auto-advance policy.  This value will
500             * be one of the values in {@link UIProvider.AutoAdvance}
501             */
502            public static final String AUTO_ADVANCE = "auto_advance";
503
504            /**
505             * Integer column containing the user's specified message text size preference.  This
506             * value will be one of the values in {@link UIProvider.MessageTextSize}
507             */
508            public static final String MESSAGE_TEXT_SIZE = "message_text_size";
509
510            /**
511             * Integer column contaning the user's specified snap header preference.  This value
512             * will be one of the values in {@link UIProvider.SnapHeaderValue}
513             */
514            public static final String SNAP_HEADERS = "snap_headers";
515
516            /**
517             * Integer column containing the user's specified default reply behavior.  This value
518             * will be one of the values in {@link UIProvider.DefaultReplyBehavior}
519             */
520            public static final String REPLY_BEHAVIOR = "reply_behavior";
521
522            /**
523             * Integer column containing the user's specified checkbox preference. A
524             * non zero value means to hide checkboxes.
525             */
526            public static final String HIDE_CHECKBOXES = "hide_checkboxes";
527
528            /**
529             * Integer column containing the user's specified confirm delete preference value.
530             * A non zero value indicates that the user has indicated that a confirmation should
531             * be shown when a delete action is performed.
532             */
533            public static final String CONFIRM_DELETE = "confirm_delete";
534
535            /**
536             * Integer column containing the user's specified confirm archive preference value.
537             * A non zero value indicates that the user has indicated that a confirmation should
538             * be shown when an archive action is performed.
539             */
540            public static final String CONFIRM_ARCHIVE = "confirm_archive";
541
542            /**
543             * Integer column containing the user's specified confirm send preference value.
544             * A non zero value indicates that the user has indicated that a confirmation should
545             * be shown when a send action is performed.
546             */
547            public static final String CONFIRM_SEND = "confirm_send";
548            /**
549             * String containing the URI for the default inbox for this account.
550             */
551            public static final String DEFAULT_INBOX = "default_inbox";
552            /**
553             * String containing the name of the default Inbox for this account
554             */
555            public static final String DEFAULT_INBOX_NAME = "default_inbox_name";
556            /**
557             * Integer column containing a non zero value if replies should always be sent from
558             * a default address instead of a recipient.
559             */
560            public static final String FORCE_REPLY_FROM_DEFAULT = "force_reply_from_default";
561            /**
562             * Integer column containing the max attachment size in kb.
563             */
564            public static final String MAX_ATTACHMENT_SIZE = "max_attachment_size";
565            /**
566             * Integer column containing a value matching one of the constants from {@link Swipe}
567             */
568            public static final String SWIPE = "swipe";
569            /**
570             * Boolean column containing whether priority inbox arrows are enabled.
571             */
572            public static final String PRIORITY_ARROWS_ENABLED = "priority_inbox_arrows_enabled";
573            /**
574             * Uri for EDIT intent that will cause account-specific setup UI to be shown. If not
575             * null, this intent should be used when an account is "entered" (i.e. viewing a folder
576             * in the account, etc.)
577             */
578            public static final String SETUP_INTENT_URI = "setup_intent_uri";
579            /**
580             * Integer column containing the Conversation view mode.  This value will match one of
581             * constants from  {@link ConversationViewMode}
582             */
583            public static final String CONVERSATION_VIEW_MODE = "conversation_view_mode";
584        }
585    }
586
587    /**
588     * Map to go from account column name to account column. Can only be used through
589     * {@link #getAccountColumn(String)}.
590     */
591    private static final ImmutableMap<String, Integer> ACCOUNT_TO_ID_MAP =
592            new ImmutableMap.Builder<String, Integer>()
593            .put(BaseColumns._ID, ACCOUNT_ID_COLUMN)
594            .put(AccountColumns.NAME, ACCOUNT_NAME_COLUMN)
595            .put(AccountColumns.TYPE, -1)
596            .put(AccountColumns.PROVIDER_VERSION, ACCOUNT_PROVIDER_VERISON_COLUMN)
597            .put(AccountColumns.URI, ACCOUNT_URI_COLUMN)
598            .put(AccountColumns.CAPABILITIES, ACCOUNT_CAPABILITIES_COLUMN)
599            .put(AccountColumns.FOLDER_LIST_URI, ACCOUNT_FOLDER_LIST_URI_COLUMN)
600            .put(AccountColumns.FULL_FOLDER_LIST_URI, ACCOUNT_FULL_FOLDER_LIST_URI_COLUMN)
601            .put(AccountColumns.SEARCH_URI, ACCOUNT_SEARCH_URI_COLUMN)
602            .put(AccountColumns.ACCOUNT_FROM_ADDRESSES, ACCOUNT_FROM_ADDRESSES_COLUMN)
603            .put(AccountColumns.SAVE_DRAFT_URI, ACCOUNT_SAVE_DRAFT_URI_COLUMN)
604            .put(AccountColumns.SEND_MAIL_URI, ACCOUNT_SEND_MESSAGE_URI_COLUMN)
605            .put(AccountColumns.EXPUNGE_MESSAGE_URI, ACCOUNT_EXPUNGE_MESSAGE_URI_COLUMN)
606            .put(AccountColumns.UNDO_URI, ACCOUNT_UNDO_URI_COLUMN)
607            .put(AccountColumns.SETTINGS_INTENT_URI, ACCOUNT_SETTINGS_INTENT_URI_COLUMN)
608            .put(AccountColumns.HELP_INTENT_URI, ACCOUNT_HELP_INTENT_URI_COLUMN)
609            .put(AccountColumns.SEND_FEEDBACK_INTENT_URI, ACCOUNT_SEND_FEEDBACK_INTENT_URI_COLUMN)
610            .put(AccountColumns.REAUTHENTICATION_INTENT_URI,
611                    ACCOUNT_REAUTHENTICATION_INTENT_URI_COLUMN)
612            .put(AccountColumns.SYNC_STATUS, ACCOUNT_SYNC_STATUS_COLUMN)
613            .put(AccountColumns.COMPOSE_URI, ACCOUNT_COMPOSE_INTENT_URI_COLUMN)
614            .put(AccountColumns.MIME_TYPE, ACCOUNT_MIME_TYPE_COLUMN)
615            .put(AccountColumns.RECENT_FOLDER_LIST_URI, ACCOUNT_RECENT_FOLDER_LIST_URI_COLUMN)
616            .put(AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI,
617                    ACCOUNT_DEFAULT_RECENT_FOLDER_LIST_URI_COLUMN)
618            .put(AccountColumns.COLOR, ACCOUNT_COLOR_COLUMN)
619            .put(AccountColumns.MANUAL_SYNC_URI, ACCOUNT_MANUAL_SYNC_URI_COLUMN)
620            .put(AccountColumns.VIEW_INTENT_PROXY_URI, ACCOUNT_VIEW_INTENT_PROXY_URI_COLUMN)
621            .put(AccountColumns.ACCOUNT_COOKIE_QUERY_URI, ACCOUNT_COOKIE_QUERY_URI_COLUMN)
622            .put(AccountColumns.SettingsColumns.SIGNATURE, ACCOUNT_SETTINGS_SIGNATURE_COLUMN)
623            .put(AccountColumns.SettingsColumns.AUTO_ADVANCE, ACCOUNT_SETTINGS_AUTO_ADVANCE_COLUMN)
624            .put(AccountColumns.SettingsColumns.MESSAGE_TEXT_SIZE,
625                    ACCOUNT_SETTINGS_MESSAGE_TEXT_SIZE_COLUMN)
626            .put(AccountColumns.SettingsColumns.SNAP_HEADERS,ACCOUNT_SETTINGS_SNAP_HEADERS_COLUMN)
627            .put(AccountColumns.SettingsColumns.REPLY_BEHAVIOR,
628                    ACCOUNT_SETTINGS_REPLY_BEHAVIOR_COLUMN)
629            .put(AccountColumns.SettingsColumns.HIDE_CHECKBOXES,
630                    ACCOUNT_SETTINGS_HIDE_CHECKBOXES_COLUMN)
631            .put(AccountColumns.SettingsColumns.CONFIRM_DELETE,
632                    ACCOUNT_SETTINGS_CONFIRM_DELETE_COLUMN)
633            .put(AccountColumns.SettingsColumns.CONFIRM_ARCHIVE,
634                    ACCOUNT_SETTINGS_CONFIRM_ARCHIVE_COLUMN)
635            .put(AccountColumns.SettingsColumns.CONFIRM_SEND,
636                    ACCOUNT_SETTINGS_CONFIRM_SEND_COLUMN)
637            .put(AccountColumns.SettingsColumns.DEFAULT_INBOX,
638                    ACCOUNT_SETTINGS_DEFAULT_INBOX_COLUMN)
639            .put(AccountColumns.SettingsColumns.DEFAULT_INBOX_NAME,
640                    ACCOUNT_SETTINGS_DEFAULT_INBOX_NAME_COLUMN)
641            .put(AccountColumns.SettingsColumns.FORCE_REPLY_FROM_DEFAULT,
642                    ACCOUNT_SETTINGS_FORCE_REPLY_FROM_DEFAULT_COLUMN)
643            .put(AccountColumns.SettingsColumns.MAX_ATTACHMENT_SIZE,
644                    ACCOUNT_SETTINGS_MAX_ATTACHMENT_SIZE_COLUMN)
645            .put(AccountColumns.SettingsColumns.SWIPE, ACCOUNT_SETTINGS_SWIPE_COLUMN)
646            .put(AccountColumns.SettingsColumns.PRIORITY_ARROWS_ENABLED,
647                    ACCOUNT_SETTINGS_PRIORITY_ARROWS_ENABLED_COLUMN)
648            .put(AccountColumns.SettingsColumns.SETUP_INTENT_URI,
649                    ACCOUNT_SETTINGS_SETUP_INTENT_URI)
650            .put(AccountColumns.SettingsColumns.CONVERSATION_VIEW_MODE,
651                    ACCOUNT_SETTINGS_CONVERSATION_MODE_COLUMN)
652            .build();
653
654    /**
655     * Returns the column number for a given column name. The column numbers are guaranteed to be
656     * unique for distinct column names. Column names are values from {@link AccountColumns} while
657     * columns are integers.
658     * @param columnName
659     * @return
660     */
661    public static final int getAccountColumn(String columnName) {
662        final Integer id = ACCOUNT_TO_ID_MAP.get(columnName);
663        if (id == null) {
664            return -1;
665        }
666        return id.intValue();
667    }
668
669    public static final String[] ACCOUNT_COOKIE_PROJECTION = {
670        AccountCookieColumns.COOKIE
671    };
672
673    public static final class AccountCookieColumns {
674        /**
675         * String column containing the cookie string for this account.
676         */
677        public static final String COOKIE = "cookie";
678    }
679
680    public static final class SearchQueryParameters {
681        /**
682         * Parameter used to specify the search query.
683         */
684        public static final String QUERY = "query";
685
686        /**
687         * If specified, the query results will be limited to this folder.
688         */
689        public static final String FOLDER = "folder";
690
691        private SearchQueryParameters() {}
692    }
693
694    public static final class ConversationListQueryParameters {
695        public static final String DEFAULT_LIMIT = "50";
696        /**
697         * Parameter used to limit the number of rows returned by a conversation list query
698         */
699        public static final String LIMIT = "limit";
700
701        /**
702         * Parameter used to control whether the this query a remote server.
703         */
704        public static final String USE_NETWORK = "use_network";
705
706        /**
707         * Parameter used to allow the caller to indicate desire to receive all notifications.
708         * (Including ones for user initiated actions)
709         */
710        public static final String ALL_NOTIFICATIONS = "all_notifications";
711
712        private ConversationListQueryParameters() {}
713    }
714
715    // We define a "folder" as anything that contains a list of conversations.
716    public static final String FOLDER_LIST_TYPE =
717            "vnd.android.cursor.dir/vnd.com.android.mail.folder";
718    public static final String FOLDER_TYPE =
719            "vnd.android.cursor.item/vnd.com.android.mail.folder";
720
721    public static final String[] FOLDERS_PROJECTION = {
722        BaseColumns._ID,
723        FolderColumns.URI,
724        FolderColumns.NAME,
725        FolderColumns.HAS_CHILDREN,
726        FolderColumns.CAPABILITIES,
727        FolderColumns.SYNC_WINDOW,
728        FolderColumns.CONVERSATION_LIST_URI,
729        FolderColumns.CHILD_FOLDERS_LIST_URI,
730        FolderColumns.UNREAD_COUNT,
731        FolderColumns.TOTAL_COUNT,
732        FolderColumns.REFRESH_URI,
733        FolderColumns.SYNC_STATUS,
734        FolderColumns.LAST_SYNC_RESULT,
735        FolderColumns.TYPE,
736        FolderColumns.ICON_RES_ID,
737        FolderColumns.BG_COLOR,
738        FolderColumns.FG_COLOR,
739        FolderColumns.LOAD_MORE_URI,
740        FolderColumns.HIERARCHICAL_DESC
741    };
742
743    public static final int FOLDER_ID_COLUMN = 0;
744    public static final int FOLDER_URI_COLUMN = 1;
745    public static final int FOLDER_NAME_COLUMN = 2;
746    public static final int FOLDER_HAS_CHILDREN_COLUMN = 3;
747    public static final int FOLDER_CAPABILITIES_COLUMN = 4;
748    public static final int FOLDER_SYNC_WINDOW_COLUMN = 5;
749    public static final int FOLDER_CONVERSATION_LIST_URI_COLUMN = 6;
750    public static final int FOLDER_CHILD_FOLDERS_LIST_COLUMN = 7;
751    public static final int FOLDER_UNREAD_COUNT_COLUMN = 8;
752    public static final int FOLDER_TOTAL_COUNT_COLUMN = 9;
753    public static final int FOLDER_REFRESH_URI_COLUMN = 10;
754    public static final int FOLDER_SYNC_STATUS_COLUMN = 11;
755    public static final int FOLDER_LAST_SYNC_RESULT_COLUMN = 12;
756    public static final int FOLDER_TYPE_COLUMN = 13;
757    public static final int FOLDER_ICON_RES_ID_COLUMN = 14;
758    public static final int FOLDER_BG_COLOR_COLUMN = 15;
759    public static final int FOLDER_FG_COLOR_COLUMN = 16;
760    public static final int FOLDER_LOAD_MORE_URI_COLUMN = 17;
761    public static final int FOLDER_HIERARCHICAL_DESC_COLUMN = 18;
762
763    public static final class FolderType {
764        /** A user defined label. */
765        public static final int DEFAULT = 0;
766        /** A system defined inbox */
767        public static final int INBOX = 1;
768        /** A system defined containing mails to be edited before sending. */
769        public static final int DRAFT = 2;
770        /** A system defined folder containing mails <b>to be</b> sent */
771        public static final int OUTBOX = 3;
772        /** A system defined folder containing sent mails */
773        public static final int SENT = 4;
774        /** A system defined trash folder */
775        public static final int TRASH = 5;
776        /** A system defined spam folder */
777        public static final int SPAM = 6;
778        /** A system defined starred folder */
779        public static final int STARRED = 7;
780        /** Any other system label that we do not have a specific name for. */
781        public static final int OTHER_PROVIDER_FOLDER = 8;
782        /** All mail folder **/
783        public static final int ALL_MAIL = 9;
784    }
785
786    public static final class FolderCapabilities {
787        public static final int SYNCABLE = 0x0001;
788        public static final int PARENT = 0x0002;
789        public static final int CAN_HOLD_MAIL = 0x0004;
790        public static final int CAN_ACCEPT_MOVED_MESSAGES = 0x0008;
791         /**
792         * For accounts that support archive, this will indicate that this folder supports
793         * the archive functionality.
794         */
795        public static final int ARCHIVE = 0x0010;
796
797        /**
798         * This will indicated that this folder supports the delete functionality.
799         */
800        public static final int DELETE = 0x0020;
801
802        /**
803         * For accounts that support report spam, this will indicate that this folder supports
804         * the report spam functionality.
805         */
806        public static final int REPORT_SPAM = 0x0040;
807
808        /**
809         * For accounts that support report spam, this will indicate that this folder supports
810         * the mark not spam functionality.
811         */
812        public static final int MARK_NOT_SPAM = 0x0080;
813
814        /**
815         * For accounts that support mute, this will indicate if a mute is performed from within
816         * this folder, the action is destructive.
817         */
818        public static final int DESTRUCTIVE_MUTE = 0x0100;
819
820        /**
821         * Indicates that a folder supports settings (sync lookback, etc.)
822         */
823        public static final int SUPPORTS_SETTINGS = 0x0200;
824        /**
825         * All the messages in this folder are important.
826         */
827        public static final int ONLY_IMPORTANT = 0x0400;
828        /**
829         * Deletions in this folder can't be undone (could include archive if desirable)
830         */
831        public static final int DELETE_ACTION_FINAL = 0x0800;
832        /**
833         * This folder is virtual, i.e. contains conversations potentially pulled from other
834         * folders, potentially even from different accounts.  Examples might be a "starred"
835         * folder, or an "unread" folder (per account or provider-wide)
836         */
837        public static final int IS_VIRTUAL = 0x1000;
838
839        /**
840         * For accounts that support report phishing, this will indicate that this folder supports
841         * the report phishing functionality.
842         */
843        public static final int REPORT_PHISHING = 0x2000;
844    }
845
846    public static final class FolderColumns {
847        /**
848         * This string column contains the uri of the folder.
849         */
850        public static final String URI = "folderUri";
851        /**
852         * This string column contains the human visible name for the folder.
853         */
854        public static final String NAME = "name";
855        /**
856         * This int column represents the capabilities of the folder specified by
857         * FolderCapabilities flags.
858         */
859        public static String CAPABILITIES = "capabilities";
860        /**
861         * This int column represents whether or not this folder has any
862         * child folders.
863         */
864        public static String HAS_CHILDREN = "hasChildren";
865        /**
866         * This int column represents how large the sync window is.
867         */
868        public static String SYNC_WINDOW = "syncWindow";
869        /**
870         * This string column contains the content provider uri to return the
871         * list of conversations for this folder.
872         */
873        public static final String CONVERSATION_LIST_URI = "conversationListUri";
874        /**
875         * This string column contains the content provider uri to return the
876         * list of child folders of this folder.
877         */
878        public static final String CHILD_FOLDERS_LIST_URI = "childFoldersListUri";
879
880        public static final String UNREAD_COUNT = "unreadCount";
881
882        public static final String TOTAL_COUNT = "totalCount";
883        /**
884         * This string column contains the content provider uri to force a
885         * refresh of this folder.
886         */
887        public static final  String REFRESH_URI = "refreshUri";
888        /**
889         * This int column contains current sync status of the folder; some combination of the
890         * SyncStatus bits defined above
891         */
892        public static final String SYNC_STATUS  = "syncStatus";
893        /**
894         * This int column contains the sync status of the last sync attempt; one of the
895         * LastSyncStatus values defined above
896         */
897        public static final String LAST_SYNC_RESULT  = "lastSyncResult";
898        /**
899         * This long column contains the icon res id for this folder, or 0 if there is none.
900         */
901        public static final String ICON_RES_ID = "iconResId";
902        /**
903         * This int column contains the type of the folder. Zero is default.
904         */
905        public static final String TYPE = "type";
906        /**
907         * String representing the integer background color associated with this
908         * folder, or null.
909         */
910        public static final String BG_COLOR = "bgColor";
911        /**
912         * String representing the integer of the foreground color associated
913         * with this folder, or null.
914         */
915        public static final String FG_COLOR = "fgColor";
916        /**
917         * String with the content provider Uri used to request more items in the folder, or null.
918         */
919        public static final String LOAD_MORE_URI = "loadMoreUri";
920
921        /**
922         * Possibly empty string that describes the full hierarchy of a folder
923         * along with its name.
924         */
925        public static final String HIERARCHICAL_DESC = "hierarchicalDesc";
926
927        public FolderColumns() {}
928    }
929
930    // We define a "folder" as anything that contains a list of conversations.
931    public static final String CONVERSATION_LIST_TYPE =
932            "vnd.android.cursor.dir/vnd.com.android.mail.conversation";
933    public static final String CONVERSATION_TYPE =
934            "vnd.android.cursor.item/vnd.com.android.mail.conversation";
935
936
937    public static final String[] CONVERSATION_PROJECTION = {
938        BaseColumns._ID,
939        ConversationColumns.URI,
940        ConversationColumns.MESSAGE_LIST_URI,
941        ConversationColumns.SUBJECT,
942        ConversationColumns.SNIPPET,
943        ConversationColumns.CONVERSATION_INFO,
944        ConversationColumns.DATE_RECEIVED_MS,
945        ConversationColumns.HAS_ATTACHMENTS,
946        ConversationColumns.NUM_MESSAGES,
947        ConversationColumns.NUM_DRAFTS,
948        ConversationColumns.SENDING_STATE,
949        ConversationColumns.PRIORITY,
950        ConversationColumns.READ,
951        ConversationColumns.STARRED,
952        ConversationColumns.RAW_FOLDERS,
953        ConversationColumns.FLAGS,
954        ConversationColumns.PERSONAL_LEVEL,
955        ConversationColumns.SPAM,
956        ConversationColumns.PHISHING,
957        ConversationColumns.MUTED,
958        ConversationColumns.COLOR,
959        ConversationColumns.ACCOUNT_URI,
960        ConversationColumns.SENDER_INFO,
961        ConversationColumns.CONVERSATION_BASE_URI,
962        ConversationColumns.REMOTE
963    };
964
965    // These column indexes only work when the caller uses the
966    // default CONVERSATION_PROJECTION defined above.
967    public static final int CONVERSATION_ID_COLUMN = 0;
968    public static final int CONVERSATION_URI_COLUMN = 1;
969    public static final int CONVERSATION_MESSAGE_LIST_URI_COLUMN = 2;
970    public static final int CONVERSATION_SUBJECT_COLUMN = 3;
971    public static final int CONVERSATION_SNIPPET_COLUMN = 4;
972    public static final int CONVERSATION_INFO_COLUMN = 5;
973    public static final int CONVERSATION_DATE_RECEIVED_MS_COLUMN = 6;
974    public static final int CONVERSATION_HAS_ATTACHMENTS_COLUMN = 7;
975    public static final int CONVERSATION_NUM_MESSAGES_COLUMN = 8;
976    public static final int CONVERSATION_NUM_DRAFTS_COLUMN = 9;
977    public static final int CONVERSATION_SENDING_STATE_COLUMN = 10;
978    public static final int CONVERSATION_PRIORITY_COLUMN = 11;
979    public static final int CONVERSATION_READ_COLUMN = 12;
980    public static final int CONVERSATION_STARRED_COLUMN = 13;
981    public static final int CONVERSATION_RAW_FOLDERS_COLUMN = 14;
982    public static final int CONVERSATION_FLAGS_COLUMN = 15;
983    public static final int CONVERSATION_PERSONAL_LEVEL_COLUMN = 16;
984    public static final int CONVERSATION_IS_SPAM_COLUMN = 17;
985    public static final int CONVERSATION_IS_PHISHING_COLUMN = 18;
986    public static final int CONVERSATION_MUTED_COLUMN = 19;
987    public static final int CONVERSATION_COLOR_COLUMN = 20;
988    public static final int CONVERSATION_ACCOUNT_URI_COLUMN = 21;
989    public static final int CONVERSATION_SENDER_INFO_COLUMN = 22;
990    public static final int CONVERSATION_BASE_URI_COLUMN = 23;
991    public static final int CONVERSATION_REMOTE_COLUMN = 24;
992
993    public static final class ConversationSendingState {
994        public static final int OTHER = 0;
995        public static final int QUEUED = 1;
996        public static final int SENDING = 2;
997        public static final int SENT = 3;
998        public static final int SEND_ERROR = -1;
999    }
1000
1001    public static final class ConversationPriority {
1002        public static final int DEFAULT = 0;
1003        public static final int IMPORTANT = 1;
1004        public static final int LOW = 0;
1005        public static final int HIGH = 1;
1006    }
1007
1008    public static final class ConversationPersonalLevel {
1009        public static final int NOT_TO_ME = 0;
1010        public static final int TO_ME_AND_OTHERS = 1;
1011        public static final int ONLY_TO_ME = 2;
1012    }
1013
1014    public static final class ConversationFlags {
1015        public static final int REPLIED = 1<<2;
1016        public static final int FORWARDED = 1<<3;
1017        public static final int CALENDAR_INVITE = 1<<4;
1018    }
1019
1020    public static final class ConversationPhishing {
1021        public static final int NOT_PHISHING = 0;
1022        public static final int PHISHING = 1;
1023    }
1024
1025    /**
1026     * Names of columns representing fields in a Conversation.
1027     */
1028    public static final class ConversationColumns {
1029        public static final String URI = "conversationUri";
1030        /**
1031         * This string column contains the content provider uri to return the
1032         * list of messages for this conversation.
1033         * The cursor returned by this query can return a {@link android.os.Bundle}
1034         * from a call to {@link android.database.Cursor#getExtras()}.  This Bundle may have
1035         * values with keys listed in {@link CursorExtraKeys}
1036         */
1037        public static final String MESSAGE_LIST_URI = "messageListUri";
1038        /**
1039         * This string column contains the subject string for a conversation.
1040         */
1041        public static final String SUBJECT = "subject";
1042        /**
1043         * This string column contains the snippet string for a conversation.
1044         */
1045        public static final String SNIPPET = "snippet";
1046        /**
1047         * @deprecated
1048         */
1049        public static final String SENDER_INFO = "senderInfo";
1050        /**
1051         * This string column contains the string representation of the
1052         * ConversationInfo JSON object for a conversation.
1053         */
1054        public static final String CONVERSATION_INFO = "conversationInfo";
1055        /**
1056         * This long column contains the time in ms of the latest update to a
1057         * conversation.
1058         */
1059        public static final String DATE_RECEIVED_MS = "dateReceivedMs";
1060
1061        /**
1062         * This boolean column contains whether any messages in this conversation
1063         * have attachments.
1064         */
1065        public static final String HAS_ATTACHMENTS = "hasAttachments";
1066
1067        /**
1068         * This int column contains the number of messages in this conversation.
1069         * For unthreaded, this will always be 1.
1070         */
1071        public static String NUM_MESSAGES = "numMessages";
1072
1073        /**
1074         * This int column contains the number of drafts associated with this
1075         * conversation.
1076         */
1077        public static String NUM_DRAFTS = "numDrafts";
1078
1079        /**
1080         * This int column contains the state of drafts and replies associated
1081         * with this conversation. Use ConversationSendingState to interpret
1082         * this field.
1083         */
1084        public static String SENDING_STATE = "sendingState";
1085
1086        /**
1087         * This int column contains the priority of this conversation. Use
1088         * ConversationPriority to interpret this field.
1089         */
1090        public static String PRIORITY = "priority";
1091
1092        /**
1093         * This int column indicates whether the conversation has been read
1094         */
1095        public static String READ = "read";
1096        /**
1097         * This int column indicates whether the conversation has been starred
1098         */
1099        public static String STARRED = "starred";
1100
1101        /**
1102         * This string column contains a serialized list of all folders
1103         * separated by a Folder.FOLDER_SEPARATOR that are associated with this
1104         * conversation. The folders should be only those that the provider
1105         * wants to have displayed, so rawFolders will ALWAYS intentionally
1106         * exclude the folder currently being viewed. Ideally, only ever use
1107         * this for rendering the folder list for a conversation.
1108         */
1109        public static final String RAW_FOLDERS = "rawFolders";
1110        public static final String FLAGS = "conversationFlags";
1111        /**
1112         * This int column indicates the personal level of a conversation per
1113         * {@link ConversationPersonalLevel}.
1114         */
1115        public static final String PERSONAL_LEVEL = "personalLevel";
1116
1117        /**
1118         * This int column indicates whether the conversation is marked spam.
1119         */
1120        public static final String SPAM = "spam";
1121
1122        /**
1123         * This int column indicates whether the conversation is marked phishing.
1124         */
1125        public static final String PHISHING = "phishing";
1126
1127        /**
1128         * This int column indicates whether the conversation was muted.
1129         */
1130        public static final String MUTED = "muted";
1131
1132        /**
1133         * This int column contains a color for the conversation (used in Email only)
1134         */
1135        public static final String COLOR = "color";
1136
1137        /**
1138         * This String column contains the Uri for this conversation's account
1139         */
1140        public static final String ACCOUNT_URI = "accountUri";
1141        /**
1142         * This int column indicates whether a conversation is remote (non-local), and would require
1143         * a network fetch to load.
1144         */
1145        public static final String REMOTE = "remote";
1146        /**
1147         * This int column indicates whether the conversation was displayed on the UI and the
1148         * user got a chance to read it. The UI does not read this value, it is meant only to
1149         * write the status back to the provider. As a result, it is not available in the
1150         * {@link Conversation} object.
1151         */
1152        public static final String VIEWED = "viewed";
1153        /**
1154         * This String column contains the base uri for this conversation.  This uri can be used
1155         * when handling relative urls in the message content
1156         */
1157        public static final String CONVERSATION_BASE_URI = "conversationBaseUri";
1158
1159        private ConversationColumns() {
1160        }
1161    }
1162
1163    public static final class ConversationCursorCommand {
1164
1165        public static final String COMMAND_RESPONSE_OK = "ok";
1166        public static final String COMMAND_RESPONSE_FAILED = "failed";
1167
1168        /**
1169         * This bundle key has a boolean value: true to allow cursor network access (whether this
1170         * is true by default is up to the provider), false to temporarily disable network access.
1171         * <p>
1172         * A provider that implements this command should include this key in its response with a
1173         * value of {@link #COMMAND_RESPONSE_OK} or {@link #COMMAND_RESPONSE_FAILED}.
1174         */
1175        public static final String COMMAND_KEY_ALLOW_NETWORK_ACCESS = "allowNetwork";
1176
1177        /**
1178         * This bundle key has a boolean value: true to indicate that this cursor has been shown
1179         * to the user.
1180         * <p>
1181         * A provider that implements this command should include this key in its response with a
1182         * value of {@link #COMMAND_RESPONSE_OK} or {@link #COMMAND_RESPONSE_FAILED}.
1183         */
1184        public static final String COMMAND_KEY_SET_VISIBILITY = "setVisibility";
1185
1186        /**
1187         * This key has a boolean value: true to indicate that this folder list is shown to the user
1188         * either on first call (launcher/widget/notification) or after switching from an existing
1189         * folder: Inbox -> Folder. Repeated calls are sent when switching back to the folder. Inbox
1190         * -> Folder -> Spam -> Folder will generate two calls to respond() with the value true for
1191         * "Folder".
1192         * <p>
1193         * A provider that implements this command should include the
1194         * {@link #COMMAND_KEY_SET_VISIBILITY} key in its response with a value of
1195         * {@link #COMMAND_RESPONSE_OK} or {@link #COMMAND_RESPONSE_FAILED}. This is <b>always</b>
1196         * set with {@link #COMMAND_KEY_SET_VISIBILITY} because this is only set when the folder
1197         * list is made visible.
1198         */
1199        public static final String COMMAND_KEY_ENTERED_FOLDER = "enteredFolder";
1200
1201        private ConversationCursorCommand() {}
1202    }
1203
1204    /**
1205     * List of operations that can can be performed on a conversation. These operations are applied
1206     * with {@link ContentProvider#update(Uri, ContentValues, String, String[])}
1207     * where the conversation uri is specified, and the ContentValues specifies the operation to
1208     * be performed.
1209     * <p/>
1210     * The operation to be performed is specified in the ContentValues by
1211     * the {@link ConversationOperations#OPERATION_KEY}
1212     * <p/>
1213     * Note not all UI providers will support these operations.  {@link AccountCapabilities} can
1214     * be used to determine which operations are supported.
1215     */
1216    public static final class ConversationOperations {
1217        /**
1218         * ContentValues key used to specify the operation to be performed
1219         */
1220        public static final String OPERATION_KEY = "operation";
1221
1222        /**
1223         * Archive operation
1224         */
1225        public static final String ARCHIVE = "archive";
1226
1227        /**
1228         * Mute operation
1229         */
1230        public static final String MUTE = "mute";
1231
1232        /**
1233         * Report spam operation
1234         */
1235        public static final String REPORT_SPAM = "report_spam";
1236
1237        /**
1238         * Report not spam operation
1239         */
1240        public static final String REPORT_NOT_SPAM = "report_not_spam";
1241
1242        /**
1243         * Report phishing operation
1244         */
1245        public static final String REPORT_PHISHING = "report_phishing";
1246
1247        /**
1248         * Discard drafts operation
1249         */
1250        public static final String DISCARD_DRAFTS = "discard_drafts";
1251
1252        private ConversationOperations() {
1253        }
1254    }
1255
1256    /**
1257     * Methods that can be "called" using the account uri, through
1258     * {@link android.content.ContentResolver#call()}  Note, the arg parmateter of call should be
1259     * the account uri.
1260     */
1261    public static final class AccountCallMethods {
1262        /**
1263         * Save message method.  The Bundle for the call to
1264         * {@link android.content.ContentResolver#call()} should have the columns specified in
1265         * {@link MessageColumns}, and if this is a save for an existing message, an entry for the
1266         * {@link MessageColumns#URI} should reference the existing message
1267         *
1268         * The Bundle returned will contain the message uri in the returned bundled with the
1269         * {@link MessageColumns#URI} key.
1270         */
1271        public static final String SAVE_MESSAGE = "save_message";
1272
1273        /**
1274         * Send message method.  The Bundle for the call to
1275         * {@link android.content.ContentResolver#call()} should have the columns specified in
1276         * {@link MessageColumns}, and if this is a send of an existing message, an entry for the
1277         * {@link MessageColumns#URI} should reference the existing message
1278         *
1279         * The Bundle returned will contain the message uri in the returned bundled with the
1280         * {@link MessageColumns#URI} key.
1281         */
1282        public static final String SEND_MESSAGE = "send_message";
1283
1284        private AccountCallMethods() {}
1285    }
1286
1287    /**
1288     * Keys used for parameters to {@link AccountCallMethods#SEND_MESSAGE} or
1289     * {@link AccountCallMethods#SAVE_MESSAGE} methods.
1290     */
1291    public static final class SendOrSaveMethodParamKeys {
1292        /**
1293         * Bundle key used to store any opened file descriptors.
1294         * The keys of this Bundle are the contentUri for each attachment, and the
1295         * values are {@link android.os.ParcelFileDescriptor} objects.
1296         */
1297        public static final String OPENED_FD_MAP = "opened_fds";
1298
1299        private SendOrSaveMethodParamKeys() {}
1300    }
1301
1302    public static final class DraftType {
1303        public static final int NOT_A_DRAFT = 0;
1304        public static final int COMPOSE = 1;
1305        public static final int REPLY = 2;
1306        public static final int REPLY_ALL = 3;
1307        public static final int FORWARD = 4;
1308
1309        private DraftType() {}
1310    }
1311
1312    /**
1313     * Class for the enum values to determine whether this
1314     * string should be displayed as a high priority warning
1315     * or a low priority warning. The current design has
1316     * high priority warnings in red while low priority warnings
1317     * are grey.
1318     */
1319    public static final class SpamWarningLevel {
1320        public static final int NO_WARNING = 0;
1321        public static final int LOW_WARNING = 1;
1322        public static final int HIGH_WARNING = 2;
1323
1324        private SpamWarningLevel() {}
1325    }
1326
1327    /**
1328     * Class for the enum values to determine which type
1329     * of link to show in the spam warning.
1330     */
1331    public static final class SpamWarningLinkType {
1332        public static final int NO_LINK = 0;
1333        public static final int IGNORE_WARNING = 1;
1334        public static final int REPORT_PHISHING = 2;
1335
1336        private SpamWarningLinkType() {}
1337    }
1338
1339    public static final String[] MESSAGE_PROJECTION = {
1340        BaseColumns._ID,
1341        MessageColumns.SERVER_ID,
1342        MessageColumns.URI,
1343        MessageColumns.CONVERSATION_ID,
1344        MessageColumns.SUBJECT,
1345        MessageColumns.SNIPPET,
1346        MessageColumns.FROM,
1347        MessageColumns.TO,
1348        MessageColumns.CC,
1349        MessageColumns.BCC,
1350        MessageColumns.REPLY_TO,
1351        MessageColumns.DATE_RECEIVED_MS,
1352        MessageColumns.BODY_HTML,
1353        MessageColumns.BODY_TEXT,
1354        MessageColumns.EMBEDS_EXTERNAL_RESOURCES,
1355        MessageColumns.REF_MESSAGE_ID,
1356        MessageColumns.DRAFT_TYPE,
1357        MessageColumns.APPEND_REF_MESSAGE_CONTENT,
1358        MessageColumns.HAS_ATTACHMENTS,
1359        MessageColumns.ATTACHMENT_LIST_URI,
1360        MessageColumns.MESSAGE_FLAGS,
1361        MessageColumns.JOINED_ATTACHMENT_INFOS,
1362        MessageColumns.SAVE_MESSAGE_URI,
1363        MessageColumns.SEND_MESSAGE_URI,
1364        MessageColumns.ALWAYS_SHOW_IMAGES,
1365        MessageColumns.READ,
1366        MessageColumns.STARRED,
1367        MessageColumns.QUOTE_START_POS,
1368        MessageColumns.ATTACHMENTS,
1369        MessageColumns.CUSTOM_FROM_ADDRESS,
1370        MessageColumns.MESSAGE_ACCOUNT_URI,
1371        MessageColumns.EVENT_INTENT_URI,
1372        MessageColumns.SPAM_WARNING_STRING,
1373        MessageColumns.SPAM_WARNING_LEVEL,
1374        MessageColumns.SPAM_WARNING_LINK_TYPE,
1375        MessageColumns.VIA_DOMAIN,
1376        MessageColumns.IS_SENDING
1377    };
1378
1379    /** Separates attachment info parts in strings in a message. */
1380    @Deprecated
1381    public static final String MESSAGE_ATTACHMENT_INFO_SEPARATOR = "\n";
1382    public static final String MESSAGE_LIST_TYPE =
1383            "vnd.android.cursor.dir/vnd.com.android.mail.message";
1384    public static final String MESSAGE_TYPE =
1385            "vnd.android.cursor.item/vnd.com.android.mail.message";
1386
1387    public static final int MESSAGE_ID_COLUMN = 0;
1388    public static final int MESSAGE_SERVER_ID_COLUMN = 1;
1389    public static final int MESSAGE_URI_COLUMN = 2;
1390    public static final int MESSAGE_CONVERSATION_URI_COLUMN = 3;
1391    public static final int MESSAGE_SUBJECT_COLUMN = 4;
1392    public static final int MESSAGE_SNIPPET_COLUMN = 5;
1393    public static final int MESSAGE_FROM_COLUMN = 6;
1394    public static final int MESSAGE_TO_COLUMN = 7;
1395    public static final int MESSAGE_CC_COLUMN = 8;
1396    public static final int MESSAGE_BCC_COLUMN = 9;
1397    public static final int MESSAGE_REPLY_TO_COLUMN = 10;
1398    public static final int MESSAGE_DATE_RECEIVED_MS_COLUMN = 11;
1399    public static final int MESSAGE_BODY_HTML_COLUMN = 12;
1400    public static final int MESSAGE_BODY_TEXT_COLUMN = 13;
1401    public static final int MESSAGE_EMBEDS_EXTERNAL_RESOURCES_COLUMN = 14;
1402    public static final int MESSAGE_REF_MESSAGE_ID_COLUMN = 15;
1403    public static final int MESSAGE_DRAFT_TYPE_COLUMN = 16;
1404    public static final int MESSAGE_APPEND_REF_MESSAGE_CONTENT_COLUMN = 17;
1405    public static final int MESSAGE_HAS_ATTACHMENTS_COLUMN = 18;
1406    public static final int MESSAGE_ATTACHMENT_LIST_URI_COLUMN = 19;
1407    public static final int MESSAGE_FLAGS_COLUMN = 20;
1408    public static final int MESSAGE_JOINED_ATTACHMENT_INFOS_COLUMN = 21;
1409    public static final int MESSAGE_SAVE_URI_COLUMN = 22;
1410    public static final int MESSAGE_SEND_URI_COLUMN = 23;
1411    public static final int MESSAGE_ALWAYS_SHOW_IMAGES_COLUMN = 24;
1412    public static final int MESSAGE_READ_COLUMN = 25;
1413    public static final int MESSAGE_STARRED_COLUMN = 26;
1414    public static final int QUOTED_TEXT_OFFSET_COLUMN = 27;
1415    public static final int MESSAGE_ATTACHMENTS_COLUMN = 28;
1416    public static final int MESSAGE_CUSTOM_FROM_ADDRESS_COLUMN = 29;
1417    public static final int MESSAGE_ACCOUNT_URI_COLUMN = 30;
1418    public static final int MESSAGE_EVENT_INTENT_COLUMN = 31;
1419    public static final int MESSAGE_SPAM_WARNING_STRING_ID_COLUMN = 32;
1420    public static final int MESSAGE_SPAM_WARNING_LEVEL_COLUMN = 33;
1421    public static final int MESSAGE_SPAM_WARNING_LINK_TYPE_COLUMN = 34;
1422    public static final int MESSAGE_VIA_DOMAIN_COLUMN = 35;
1423    public static final int MESSAGE_IS_SENDING_COLUMN = 36;
1424
1425    public static final class CursorStatus {
1426        // The cursor is actively loading more data
1427        public static final int LOADING =      1 << 0;
1428
1429        // The cursor is currently not loading more data, but more data may be available
1430        public static final int LOADED =       1 << 1;
1431
1432        // An error occured while loading data
1433        public static final int ERROR =        1 << 2;
1434
1435        // The cursor is loaded, and there will be no more data
1436        public static final int COMPLETE =     1 << 3;
1437
1438        public static boolean isWaitingForResults(int cursorStatus) {
1439            return 0 != (cursorStatus & LOADING);
1440        }
1441    }
1442
1443
1444    public static final class CursorExtraKeys {
1445        /**
1446         * This integer column contains the staus of the message cursor.  The value will be
1447         * one defined in {@link CursorStatus}.
1448         */
1449        public static final String EXTRA_STATUS = "cursor_status";
1450
1451        /**
1452         * Used for finding the cause of an error.
1453         * TODO: define these values
1454         */
1455        public static final String EXTRA_ERROR = "cursor_error";
1456
1457    }
1458
1459    public static final class AccountCursorExtraKeys {
1460        /**
1461         * This integer column contains the staus of the account cursor.  The value will be
1462         * 1 if all accounts have been fully loaded or 0 if the account list hasn't been fully
1463         * initialized
1464         */
1465        public static final String ACCOUNTS_LOADED = "accounts_loaded";
1466    }
1467
1468
1469    public static final class MessageFlags {
1470        public static final int REPLIED =           1 << 2;
1471        public static final int FORWARDED =         1 << 3;
1472        public static final int CALENDAR_INVITE =   1 << 4;
1473    }
1474
1475    public static final class MessageColumns {
1476        /**
1477         * This string column contains a content provider URI that points to this single message.
1478         */
1479        public static final String URI = "messageUri";
1480        /**
1481         * This string column contains a server-assigned ID for this message.
1482         */
1483        public static final String SERVER_ID = "serverMessageId";
1484        public static final String CONVERSATION_ID = "conversationId";
1485        /**
1486         * This string column contains the subject of a message.
1487         */
1488        public static final String SUBJECT = "subject";
1489        /**
1490         * This string column contains a snippet of the message body.
1491         */
1492        public static final String SNIPPET = "snippet";
1493        /**
1494         * This string column contains the single email address (and optionally name) of the sender.
1495         */
1496        public static final String FROM = "fromAddress";
1497        /**
1498         * This string column contains a comma-delimited list of "To:" recipient email addresses.
1499         */
1500        public static final String TO = "toAddresses";
1501        /**
1502         * This string column contains a comma-delimited list of "CC:" recipient email addresses.
1503         */
1504        public static final String CC = "ccAddresses";
1505        /**
1506         * This string column contains a comma-delimited list of "BCC:" recipient email addresses.
1507         * This value will be null for incoming messages.
1508         */
1509        public static final String BCC = "bccAddresses";
1510        /**
1511         * This string column contains the single email address (and optionally name) of the
1512         * sender's reply-to address.
1513         */
1514        public static final String REPLY_TO = "replyToAddress";
1515        /**
1516         * This long column contains the timestamp (in millis) of receipt of the message.
1517         */
1518        public static final String DATE_RECEIVED_MS = "dateReceivedMs";
1519        /**
1520         * This string column contains the HTML form of the message body, if available. If not,
1521         * a provider must populate BODY_TEXT.
1522         */
1523        public static final String BODY_HTML = "bodyHtml";
1524        /**
1525         * This string column contains the plaintext form of the message body, if HTML is not
1526         * otherwise available. If HTML is available, this value should be left empty (null).
1527         */
1528        public static final String BODY_TEXT = "bodyText";
1529        public static final String EMBEDS_EXTERNAL_RESOURCES = "bodyEmbedsExternalResources";
1530        /**
1531         * This string column contains an opaque string used by the sendMessage api.
1532         */
1533        public static final String REF_MESSAGE_ID = "refMessageId";
1534        /**
1535         * This integer column contains the type of this draft, or zero (0) if this message is not a
1536         * draft. See {@link DraftType} for possible values.
1537         */
1538        public static final String DRAFT_TYPE = "draftType";
1539        /**
1540         * This boolean column indicates whether an outgoing message should trigger special quoted
1541         * text processing upon send. The value should default to zero (0) for protocols that do
1542         * not support or require this flag, and for all incoming messages.
1543         */
1544        public static final String APPEND_REF_MESSAGE_CONTENT = "appendRefMessageContent";
1545        /**
1546         * This boolean column indicates whether a message has attachments. The list of attachments
1547         * can be retrieved using the URI in {@link MessageColumns#ATTACHMENT_LIST_URI}.
1548         */
1549        public static final String HAS_ATTACHMENTS = "hasAttachments";
1550        /**
1551         * This string column contains the content provider URI for the list of
1552         * attachments associated with this message.
1553         */
1554        public static final String ATTACHMENT_LIST_URI = "attachmentListUri";
1555        /**
1556         * This long column is a bit field of flags defined in {@link MessageFlags}.
1557         */
1558        public static final String MESSAGE_FLAGS = "messageFlags";
1559        /**
1560         * This string column contains a specially formatted string representing all
1561         * attachments that we added to a message that is being sent or saved.
1562         *
1563         * TODO: remove this and use {@link #ATTACHMENTS} instead
1564         */
1565        @Deprecated
1566        public static final String JOINED_ATTACHMENT_INFOS = "joinedAttachmentInfos";
1567        /**
1568         * This string column contains the content provider URI for saving this
1569         * message.
1570         */
1571        @Deprecated
1572        public static final String SAVE_MESSAGE_URI = "saveMessageUri";
1573        /**
1574         * This string column contains content provider URI for sending this
1575         * message.
1576         */
1577        @Deprecated
1578        public static final String SEND_MESSAGE_URI = "sendMessageUri";
1579
1580        /**
1581         * This integer column represents whether the user has specified that images should always
1582         * be shown.  The value of "1" indicates that the user has specified that images should be
1583         * shown, while the value of "0" indicates that the user should be prompted before loading
1584         * any external images.
1585         */
1586        public static final String ALWAYS_SHOW_IMAGES = "alwaysShowImages";
1587
1588        /**
1589         * This boolean column indicates whether the message has been read
1590         */
1591        public static String READ = "read";
1592
1593        /**
1594         * This boolean column indicates whether the message has been starred
1595         */
1596        public static String STARRED = "starred";
1597
1598        /**
1599         * This integer column represents the offset in the message of quoted
1600         * text. If include_quoted_text is zero, the value contained in this
1601         * column is invalid.
1602         */
1603        public static final String QUOTE_START_POS = "quotedTextStartPos";
1604
1605        /**
1606         * This string columns contains a JSON array of serialized {@link Attachment} objects.
1607         */
1608        public static final String ATTACHMENTS = "attachments";
1609        public static final String CUSTOM_FROM_ADDRESS = "customFrom";
1610        /**
1611         * Uri of the account associated with this message. Except in the case
1612         * of showing a combined view, this column is almost always empty.
1613         */
1614        public static final String MESSAGE_ACCOUNT_URI = "messageAccountUri";
1615        /**
1616         * Intent Uri to launch when the user wants to view an event in their calendar, or null.
1617         */
1618        public static final String EVENT_INTENT_URI = "eventIntentUri";
1619        /**
1620         * This string column contains the string for the spam
1621         * warning of this message, or null if there is no spam warning for the message.
1622         */
1623        public static final String SPAM_WARNING_STRING = "spamWarningString";
1624        /**
1625         * This integer column contains the level of spam warning of this message,
1626         * or zero (0) if this message does not have a warning level.
1627         * See {@link SpamWarningLevel} for possible values.
1628         */
1629        public static final String SPAM_WARNING_LEVEL = "spamWarningLevel";
1630        /**
1631         * This integer column contains the type of link for the spam warning
1632         * of this message, or zero (0) if this message does not have a link type.
1633         * See {@link SpamWarningLinkType} for possible values.
1634         */
1635        public static final String SPAM_WARNING_LINK_TYPE = "spamWarningLinkType";
1636        /**
1637         * This string column contains the string for the via domain
1638         * to be included if this message was sent via an alternate
1639         * domain. This column should be null if no via domain exists.
1640         */
1641        public static final String VIA_DOMAIN = "viaDomain";
1642        /**
1643         * This boolean column indicates whether the message is an outgoing message in the process
1644         * of being sent (will be zero for incoming messages and messages that are already sent).
1645         */
1646        public static final String IS_SENDING = "isSending";
1647
1648        private MessageColumns() {}
1649    }
1650
1651    /**
1652     * List of operations that can can be performed on a message. These operations are applied
1653     * with {@link ContentProvider#update(Uri, ContentValues, String, String[])}
1654     * where the message uri is specified, and the ContentValues specifies the operation to
1655     * be performed, e.g. values.put(RESPOND_COLUMN, RESPOND_ACCEPT)
1656     * <p/>
1657     * Note not all UI providers will support these operations.
1658     */
1659    public static final class MessageOperations {
1660        /**
1661         * Respond to a calendar invitation
1662         */
1663        public static final String RESPOND_COLUMN = "respond";
1664
1665        public static final int RESPOND_ACCEPT = 1;
1666        public static final int RESPOND_TENTATIVE = 2;
1667        public static final int RESPOND_DECLINE = 3;
1668
1669        private MessageOperations() {
1670        }
1671    }
1672
1673    public static final String ATTACHMENT_LIST_TYPE =
1674            "vnd.android.cursor.dir/vnd.com.android.mail.attachment";
1675    public static final String ATTACHMENT_TYPE =
1676            "vnd.android.cursor.item/vnd.com.android.mail.attachment";
1677
1678    public static final String[] ATTACHMENT_PROJECTION = {
1679        AttachmentColumns.NAME,
1680        AttachmentColumns.SIZE,
1681        AttachmentColumns.URI,
1682        AttachmentColumns.CONTENT_TYPE,
1683        AttachmentColumns.STATE,
1684        AttachmentColumns.DESTINATION,
1685        AttachmentColumns.DOWNLOADED_SIZE,
1686        AttachmentColumns.CONTENT_URI,
1687        AttachmentColumns.THUMBNAIL_URI,
1688        AttachmentColumns.PREVIEW_INTENT_URI
1689    };
1690    private static final String EMAIL_SEPARATOR_PATTERN = "\n";
1691    public static final int ATTACHMENT_NAME_COLUMN = 0;
1692    public static final int ATTACHMENT_SIZE_COLUMN = 1;
1693    public static final int ATTACHMENT_URI_COLUMN = 2;
1694    public static final int ATTACHMENT_CONTENT_TYPE_COLUMN = 3;
1695    public static final int ATTACHMENT_STATE_COLUMN = 4;
1696    public static final int ATTACHMENT_DESTINATION_COLUMN = 5;
1697    public static final int ATTACHMENT_DOWNLOADED_SIZE_COLUMN = 6;
1698    public static final int ATTACHMENT_CONTENT_URI_COLUMN = 7;
1699    public static final int ATTACHMENT_THUMBNAIL_URI_COLUMN = 8;
1700    public static final int ATTACHMENT_PREVIEW_INTENT_COLUMN = 9;
1701
1702    /**
1703     * Valid states for the {@link AttachmentColumns#STATE} column.
1704     *
1705     */
1706    public static final class AttachmentState {
1707        /**
1708         * The full attachment is not present on device. When used as a command,
1709         * setting this state will tell the provider to cancel a download in
1710         * progress.
1711         * <p>
1712         * Valid next states: {@link #DOWNLOADING}
1713         */
1714        public static final int NOT_SAVED = 0;
1715        /**
1716         * The most recent attachment download attempt failed. The current UI
1717         * design does not require providers to persist this state, but
1718         * providers must return this state at least once after a download
1719         * failure occurs. This state may not be used as a command.
1720         * <p>
1721         * Valid next states: {@link #DOWNLOADING}
1722         */
1723        public static final int FAILED = 1;
1724        /**
1725         * The attachment is currently being downloaded by the provider.
1726         * {@link AttachmentColumns#DOWNLOADED_SIZE} should reflect the current
1727         * download progress while in this state. When used as a command,
1728         * setting this state will tell the provider to initiate a download to
1729         * the accompanying destination in {@link AttachmentColumns#DESTINATION}
1730         * .
1731         * <p>
1732         * Valid next states: {@link #NOT_SAVED}, {@link #FAILED},
1733         * {@link #SAVED}
1734         */
1735        public static final int DOWNLOADING = 2;
1736        /**
1737         * The attachment was successfully downloaded to the destination in
1738         * {@link AttachmentColumns#DESTINATION}. If a provider later detects
1739         * that a download is missing, it should reset the state to
1740         * {@link #NOT_SAVED}. This state may not be used as a command on its
1741         * own. To move a file from cache to external, update
1742         * {@link AttachmentColumns#DESTINATION}.
1743         * <p>
1744         * Valid next states: {@link #NOT_SAVED}
1745         */
1746        public static final int SAVED = 3;
1747        /**
1748         * This is only used as a command, not as a state. The attachment is
1749         * currently being redownloaded by the provider.
1750         * {@link AttachmentColumns#DOWNLOADED_SIZE} should reflect the current
1751         * download progress while in this state. When used as a command,
1752         * setting this state will tell the provider to initiate a download to
1753         * the accompanying destination in {@link AttachmentColumns#DESTINATION}
1754         * .
1755         * <p>
1756         * Valid next states: {@link #NOT_SAVED}, {@link #FAILED},
1757         * {@link #SAVED}
1758         */
1759        public static final int REDOWNLOADING = 4;
1760
1761        private AttachmentState() {}
1762    }
1763
1764    public static final class AttachmentDestination {
1765
1766        /**
1767         * The attachment will be or is already saved to the app-private cache partition.
1768         */
1769        public static final int CACHE = 0;
1770        /**
1771         * The attachment will be or is already saved to external shared device storage.
1772         */
1773        public static final int EXTERNAL = 1;
1774
1775        private AttachmentDestination() {}
1776    }
1777
1778    public static final class AttachmentColumns {
1779        /**
1780         * This string column is the attachment's file name, intended for display in UI. It is not
1781         * the full path of the file.
1782         */
1783        public static final String NAME = OpenableColumns.DISPLAY_NAME;
1784        /**
1785         * This integer column is the file size of the attachment, in bytes.
1786         */
1787        public static final String SIZE = OpenableColumns.SIZE;
1788        /**
1789         * This column is a {@link Uri} that can be queried to monitor download state and progress
1790         * for this individual attachment (resulting cursor has one single row for this attachment).
1791         */
1792        public static final String URI = "uri";
1793        /**
1794         * This string column is the MIME type of the attachment.
1795         */
1796        public static final String CONTENT_TYPE = "contentType";
1797        /**
1798         * This integer column is the current downloading state of the
1799         * attachment as defined in {@link AttachmentState}.
1800         * <p>
1801         * Providers must accept updates to {@link #URI} with new values of
1802         * this column to initiate or cancel downloads.
1803         */
1804        public static final String STATE = "state";
1805        /**
1806         * This integer column is the file destination for the current download
1807         * in progress (when {@link #STATE} is
1808         * {@link AttachmentState#DOWNLOADING}) or the resulting downloaded file
1809         * ( when {@link #STATE} is {@link AttachmentState#SAVED}), as defined
1810         * in {@link AttachmentDestination}. This value is undefined in any
1811         * other state.
1812         * <p>
1813         * Providers must accept updates to {@link #URI} with new values of
1814         * this column to move an existing downloaded file.
1815         */
1816        public static final String DESTINATION = "destination";
1817        /**
1818         * This integer column is the current number of bytes downloaded when
1819         * {@link #STATE} is {@link AttachmentState#DOWNLOADING}. This value is
1820         * undefined in any other state.
1821         */
1822        public static final String DOWNLOADED_SIZE = "downloadedSize";
1823        /**
1824         * This column is a {@link Uri} that points to the downloaded local file
1825         * when {@link #STATE} is {@link AttachmentState#SAVED}. This value is
1826         * undefined in any other state.
1827         */
1828        public static final String CONTENT_URI = "contentUri";
1829        /**
1830         * This column is a {@link Uri} that points to a local thumbnail file
1831         * for the attachment. Providers that do not support downloading
1832         * attachment thumbnails may leave this null.
1833         */
1834        public static final String THUMBNAIL_URI = "thumbnailUri";
1835        /**
1836         * This column is an {@link Uri} used in an {@link Intent#ACTION_VIEW} Intent to launch a
1837         * preview activity that allows the user to efficiently view an attachment without having to
1838         * first download the entire file. Providers that do not support
1839         * previewing attachments may leave this null.
1840         */
1841        public static final String PREVIEW_INTENT_URI = "previewIntentUri";
1842
1843        private AttachmentColumns() {}
1844    }
1845
1846    public static String getAttachmentTypeSetting() {
1847        // TODO: query the account to see what kinds of attachments it supports?
1848        return "com.google.android.gm.allowAddAnyAttachment";
1849    }
1850
1851    public static void incrementRecipientsTimesContacted(Context context, String addressString) {
1852        DataUsageStatUpdater statsUpdater = new DataUsageStatUpdater(context);
1853        ArrayList<String> recipients = new ArrayList<String>();
1854        if (TextUtils.isEmpty(addressString)) {
1855            return;
1856        }
1857        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(addressString);
1858        for (int i = 0; i < tokens.length;i++) {
1859            recipients.add(tokens[i].getAddress());
1860        }
1861        statsUpdater.updateWithAddress(recipients);
1862    }
1863
1864    public static final String[] UNDO_PROJECTION = {
1865        ConversationColumns.MESSAGE_LIST_URI
1866    };
1867    public static final int UNDO_MESSAGE_LIST_COLUMN = 0;
1868
1869    // Parameter used to indicate the sequence number for an undoable operation
1870    public static final String SEQUENCE_QUERY_PARAMETER = "seq";
1871
1872    /**
1873     * Settings for auto advancing when the current conversation has been destroyed.
1874     */
1875    public static final class AutoAdvance {
1876        /** No setting specified. */
1877        public static final int UNSET = 0;
1878        /** Go to the older message (if available) */
1879        public static final int OLDER = 1;
1880        /** Go to the newer message (if available) */
1881        public static final int NEWER = 2;
1882        /** Go back to conversation list*/
1883        public static final int LIST = 3;
1884    }
1885
1886    /**
1887     * Settings for what swipe should do.
1888     */
1889    public static final class Swipe {
1890        /** Archive or remove label, if available. */
1891        public static final int ARCHIVE = 0;
1892        /** Delete */
1893        public static final int DELETE = 1;
1894        /** No swipe */
1895        public static final int DISABLED = 2;
1896        /** Default is delete */
1897        public static final int DEFAULT = ARCHIVE;
1898    }
1899
1900    /**
1901     * Settings for Conversation view mode.
1902     */
1903    public static final class ConversationViewMode {
1904        /**
1905         * The user hasn't specified a mode.
1906         */
1907        public static final int UNDEFINED = -1;
1908        /**
1909         * Default to fit the conversation to screen view
1910         */
1911        public static final int OVERVIEW = 0;
1912        /**
1913         * Conversation text size should be the device default, and wide conversations may
1914         * require panning
1915         */
1916        public static final int READING = 1;
1917    }
1918
1919    public static final class SnapHeaderValue {
1920        public static final int ALWAYS = 0;
1921        public static final int PORTRAIT_ONLY = 1;
1922        public static final int NEVER = 2;
1923    }
1924
1925    public static final class MessageTextSize {
1926        public static final int TINY = -2;
1927        public static final int SMALL = -1;
1928        public static final int NORMAL = 0;
1929        public static final int LARGE = 1;
1930        public static final int HUGE = 2;
1931    }
1932
1933    public static final class DefaultReplyBehavior {
1934        public static final int REPLY = 0;
1935        public static final int REPLY_ALL = 1;
1936    }
1937
1938    /**
1939     * Action for an intent used to update/create new notifications.  The mime type of this
1940     * intent should be set to the mimeType of the account that is generating this notification.
1941     * An intent of this action is required to have the following extras:
1942     * {@link UpdateNotificationExtras#EXTRA_FOLDER} {@link UpdateNotificationExtras#EXTRA_ACCOUNT}
1943     */
1944    public static final String ACTION_UPDATE_NOTIFICATION =
1945            "com.android.mail.action.update_notification";
1946
1947    public static final class UpdateNotificationExtras {
1948        /**
1949         * Parcelable extra containing a {@link Uri} to a {@link Folder}
1950         */
1951        public static final String EXTRA_FOLDER = "notification_extra_folder";
1952
1953        /**
1954         * Parcelable extra containing a {@link Uri} to an {@link Account}
1955         */
1956        public static final String EXTRA_ACCOUNT = "notification_extra_account";
1957
1958        /**
1959         * Integer extra containing the update unread count for the account/folder.
1960         * If this value is 0, the UI will not block the intent to allow code to clear notifications
1961         * to run.
1962         */
1963        public static final String EXTRA_UPDATED_UNREAD_COUNT = "notification_updated_unread_count";
1964    }
1965
1966    public static final class EditSettingsExtras {
1967        /**
1968         * Parcelable extra containing account for which the user wants to
1969         * modify settings
1970         */
1971        public static final String EXTRA_ACCOUNT = "extra_account";
1972
1973        /**
1974         * Parcelable extra containing folder for which the user wants to
1975         * modify settings
1976         */
1977        public static final String EXTRA_FOLDER = "extra_folder";
1978
1979        /**
1980         * Boolean extra which is set true if the user wants to "manage folders"
1981         */
1982        public static final String EXTRA_MANAGE_FOLDERS = "extra_manage_folders";
1983    }
1984
1985    public static final class SendFeedbackExtras {
1986        /**
1987         * Optional boolean extras which indicates that the user is reporting a problem.
1988         */
1989        public static final String EXTRA_REPORTING_PROBLEM = "reporting_problem";
1990    }
1991
1992    public static final class ViewProxyExtras {
1993        /**
1994         * Uri extra passed to the proxy which indicates the original Uri that was intended to be
1995         * viewed.
1996         */
1997        public static final String EXTRA_ORIGINAL_URI = "original_uri";
1998        /**
1999         * Parcelable extra passed to the proxy which indicates the account being viewed from.
2000         */
2001        public static final String EXTRA_ACCOUNT = "account";
2002        /**
2003         * String extra passed from the proxy which indicates the salt used to generate the digest.
2004         */
2005        public static final String EXTRA_SALT = "salt";
2006        /**
2007         * Byte[] extra passed from the proxy which indicates the digest of the salted account name.
2008         */
2009        public static final String EXTRA_ACCOUNT_DIGEST = "digest";
2010    }
2011}
2012