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