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