1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.bluetooth.mapapi;
18
19import android.content.ContentResolver;
20import android.net.Uri;
21
22
23/**
24 * This class defines the minimum sets of data needed for a client to
25 * implement to claim support for the Bluetooth Message Access Profile.
26 * Access to three data sets are needed:
27 * <ul>
28 *   <li>Message data set containing lists of messages.</li>
29 *   <li>Account data set containing info on the existing accounts, and whether to expose
30 *     these accounts. The content of the account data set is often sensitive information,
31 *     hence care must be taken, not to reveal any personal information nor passwords.
32 *     The accounts in this data base will be exposed in the settings menu, where the user
33 *     is able to enable and disable the EXPOSE_FLAG, and thereby provide access to an
34 *     account from another device, without any password protection the e-mail client
35 *     might provide.</li>
36 *   <li>Folder data set with the folder structure for the messages. Each message is linked to an
37 *     entry in this data set.</li>
38 *   <li>Conversation data set with the thread structure of the messages. Each message is linked
39 *     to an entry in this data set.</li>
40 * </ul>
41 *
42 * To enable that the Bluetooth Message Access Server can detect the content provider implementing
43 * this interface, the {@code provider} tag for the Bluetooth related content provider must
44 * have an intent-filter like the following in the manifest:
45 * <pre class="prettyprint">&lt;provider  android:authorities="[PROVIDER AUTHORITY]"
46              android:exported="true"
47              android:enabled="true"
48              android:permission="android.permission.BLUETOOTH_MAP"&gt;
49 *   ...
50 *      &lt;intent-filter&gt;
51           &lt;action android:name="android.content.action.BLEUETOOT_MAP_PROVIDER" /&gt;
52        &lt;/intent-filter&gt;
53 *   ...
54 *   &lt;/provider&gt;
55 * [PROVIDER AUTHORITY] shall be the providers authority value which implements this
56 * contract. Only a single authority shall be used. The android.permission.BLUETOOTH_MAP
57 * permission is needed for the provider.
58 */
59public final class BluetoothMapContract {
60    /**
61     * Constructor - should not be used
62     */
63    private BluetoothMapContract(){
64      /* class should not be instantiated */
65    }
66
67    /**
68     * Provider interface that should be used as intent-filter action in the provider section
69     * of the manifest file.
70     */
71    public static final String PROVIDER_INTERFACE_EMAIL =
72            "android.bluetooth.action.BLUETOOTH_MAP_PROVIDER";
73    public static final String PROVIDER_INTERFACE_IM =
74            "android.bluetooth.action.BLUETOOTH_MAP_IM_PROVIDER";
75    /**
76     * The Bluetooth Message Access profile allows a remote BT-MAP client to trigger
77     * an update of a folder for a specific e-mail account, register for reception
78     * of new messages from the server.
79     *
80     * Additionally the Bluetooth Message Access profile allows a remote BT-MAP client
81     * to push a message to a folder - e.g. outbox or draft. The Bluetooth profile
82     * implementation will place a new message in one of these existing folders through
83     * the content provider.
84     *
85     * ContentProvider.call() is used for these purposes, and the METHOD_UPDATE_FOLDER
86     * method name shall trigger an update of the specified folder for a specified
87     * account.
88     *
89     * This shall be a non blocking call simply starting the update, and the update should
90     * both send and receive messages, depending on what makes sense for the specified
91     * folder.
92     * Bundle extra parameter will carry two INTEGER (long) values:
93     *   EXTRA_UPDATE_ACCOUNT_ID containing the account_id
94     *   EXTRA_UPDATE_FOLDER_ID containing the folder_id of the folder to update
95     *
96     * The status for send complete of messages shall be reported by updating the sent-flag
97     * and e.g. for outbox messages, move them to the sent folder in the message table of the
98     * content provider and trigger a change notification to any attached content observer.
99     */
100    public static final String METHOD_UPDATE_FOLDER = "UpdateFolder";
101    public static final String EXTRA_UPDATE_ACCOUNT_ID = "UpdateAccountId";
102    public static final String EXTRA_UPDATE_FOLDER_ID = "UpdateFolderId";
103
104    /**
105     * The Bluetooth Message Access profile allows a remote BT-MAP Client to update
106     * the owners presence and chat state
107     *
108     * ContentProvider.call() is used for these purposes, and the METHOD_SET_OWNER_STATUS
109     * method name shall trigger a change in owner/users presence or chat properties for an
110     * account or conversation.
111     *
112     * This shall be a non blocking call simply setting the properties, and the change should
113     * be sent to the remote server/users, depending on what property is changed.
114     * Bundle extra parameter will carry following values:
115     *   EXTRA_ACCOUNT_ID containing the account_id
116     *   EXTRA_PRESENCE_STATE containing the presence state of the owner account
117     *   EXTRA_PRESENCE_STATUS containing the presence status text from the owner
118     *   EXTRA_LAST_ACTIVE containing the last activity time stamp of the owner account
119     *   EXTRA_CHAT_STATE containing the chat state of a specific conversation
120     *   EXTRA_CONVERSATION_ID containing the conversation that is changed
121     */
122    public static final String METHOD_SET_OWNER_STATUS = "SetOwnerStatus";
123    public static final String EXTRA_ACCOUNT_ID = "AccountId"; // Is this needed
124    public static final String EXTRA_PRESENCE_STATE = "PresenceState";
125    public static final String EXTRA_PRESENCE_STATUS = "PresenceStatus";
126    public static final String EXTRA_LAST_ACTIVE = "LastActive";
127    public static final String EXTRA_CHAT_STATE = "ChatState";
128    public static final String EXTRA_CONVERSATION_ID = "ConversationId";
129
130    /**
131     * The Bluetooth Message Access profile can inform the messaging application of the Bluetooth
132     * state, whether is is turned 'on' or 'off'
133     *
134     * ContentProvider.call() is used for these purposes, and the METHOD_SET_BLUETOOTH_STATE
135     * method name shall trigger a change in owner/users presence or chat properties for an
136     * account or conversation.
137     *
138     * This shall be a non blocking call simply setting the properties.
139     *
140     * Bundle extra parameter will carry following values:
141     *   EXTRA_BLUETOOTH_STATE containing the state of the Bluetooth connectivity
142     */
143    public static final String METHOD_SET_BLUETOOTH_STATE = "SetBtState";
144    public static final String EXTRA_BLUETOOTH_STATE = "BluetoothState";
145
146    /**
147     * These column names are used as last path segment of the URI (getLastPathSegment()).
148     * Access to a specific row in the tables is done by using the where-clause, hence
149     * support for .../#id if not needed for the Email clients.
150     * The URI format for accessing the tables are as follows:
151     *   content://ProviderAuthority/TABLE_ACCOUNT
152     *   content://ProviderAuthority/account_id/TABLE_MESSAGE
153     *   content://ProviderAuthority/account_id/TABLE_FOLDER
154     *   content://ProviderAuthority/account_id/TABLE_CONVERSATION
155     *   content://ProviderAuthority/account_id/TABLE_CONVOCONTACT
156     **/
157
158    /**
159     * Build URI representing the given Accounts data-set in a
160     * Bluetooth provider. When queried, the direct URI for the account
161     * with the given accountID is returned.
162     */
163    public static Uri buildAccountUri(String authority) {
164        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
165                .authority(authority).appendPath(TABLE_ACCOUNT).build();
166    }
167    /**
168     * Build URI representing the given Account data-set with specific Id in a
169     * Bluetooth provider. When queried, the direct URI for the account
170     * with the given accountID is returned.
171     */
172    public static Uri buildAccountUriwithId(String authority, String accountId) {
173        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
174                .authority(authority)
175                .appendPath(TABLE_ACCOUNT)
176                .appendPath(accountId)
177                .build();
178    }
179    /**
180     * Build URI representing the entire Message table in a
181     * Bluetooth provider.
182     */
183    public static Uri buildMessageUri(String authority) {
184        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
185                .authority(authority)
186                .appendPath(TABLE_MESSAGE)
187                .build();
188    }
189    /**
190     * Build URI representing the given Message data-set in a
191     * Bluetooth provider. When queried, the URI for the Messages
192     * with the given accountID is returned.
193     */
194    public static Uri buildMessageUri(String authority, String accountId) {
195        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
196                .authority(authority)
197                .appendPath(accountId)
198                .appendPath(TABLE_MESSAGE)
199                .build();
200    }
201    /**
202     * Build URI representing the given Message data-set with specific messageId in a
203     * Bluetooth provider. When queried, the direct URI for the account
204     * with the given accountID is returned.
205     */
206    public static Uri buildMessageUriWithId(String authority, String accountId,String messageId) {
207        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
208                .authority(authority)
209                .appendPath(accountId)
210                .appendPath(TABLE_MESSAGE)
211                .appendPath(messageId)
212                .build();
213    }
214    /**
215     * Build URI representing the given Message data-set in a
216     * Bluetooth provider. When queried, the direct URI for the folder
217     * with the given accountID is returned.
218     */
219    public static Uri buildFolderUri(String authority, String accountId) {
220        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
221                .authority(authority)
222                .appendPath(accountId)
223                .appendPath(TABLE_FOLDER)
224                .build();
225    }
226
227    /**
228     * Build URI representing the given Message data-set in a
229     * Bluetooth provider. When queried, the direct URI for the conversation
230     * with the given accountID is returned.
231     */
232    public static Uri buildConversationUri(String authority, String accountId) {
233        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
234                .authority(authority)
235                .appendPath(accountId)
236                .appendPath(TABLE_CONVERSATION)
237                .build();
238    }
239
240    /**
241     * Build URI representing the given Contact data-set in a
242     * Bluetooth provider. When queried, the direct URI for the contacts
243     * with the given accountID is returned.
244     */
245    public static Uri buildConvoContactsUri(String authority) {
246        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
247                .authority(authority)
248                .appendPath(TABLE_CONVOCONTACT)
249                .build();
250    }
251
252    /**
253     * Build URI representing the given Contact data-set in a
254     * Bluetooth provider. When queried, the direct URI for the contacts
255     * with the given accountID is returned.
256     */
257    public static Uri buildConvoContactsUri(String authority, String accountId) {
258        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
259                .authority(authority)
260                .appendPath(accountId)
261                .appendPath(TABLE_CONVOCONTACT)
262                .build();
263    }
264    /**
265     * Build URI representing the given Contact data-set in a
266     * Bluetooth provider. When queried, the direct URI for the contact
267     * with the given contactID and accountID is returned.
268     */
269    public static Uri buildConvoContactsUriWithId(String authority, String accountId,
270            String contactId) {
271        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
272                .authority(authority)
273                .appendPath(accountId)
274                .appendPath(TABLE_CONVOCONTACT)
275                .appendPath(contactId)
276                .build();
277    }
278    /**
279     *  @hide
280     */
281    public static final String TABLE_ACCOUNT        = "Account";
282    public static final String TABLE_MESSAGE        = "Message";
283    public static final String TABLE_MESSAGE_PART   = "Part";
284    public static final String TABLE_FOLDER         = "Folder";
285    public static final String TABLE_CONVERSATION   = "Conversation";
286    public static final String TABLE_CONVOCONTACT   = "ConvoContact";
287
288
289    /**
290     * Mandatory folders for the Bluetooth message access profile.
291     * The email client shall at least implement the following root folders.
292     * E.g. as a mapping for them such that the naming will match the underlying
293     * matching folder ID's.
294     */
295    public static final String FOLDER_NAME_INBOX   = "INBOX";
296    public static final String FOLDER_NAME_SENT    = "SENT";
297    public static final String FOLDER_NAME_OUTBOX  = "OUTBOX";
298    public static final String FOLDER_NAME_DRAFT   = "DRAFT";
299    public static final String FOLDER_NAME_DELETED = "DELETED";
300    public static final String FOLDER_NAME_OTHER   = "OTHER";
301
302    /**
303     * Folder IDs to be used with Instant Messaging virtual folders
304     */
305    public static final long FOLDER_ID_OTHER      = 0;
306    public static final long FOLDER_ID_INBOX      = 1;
307    public static final long FOLDER_ID_SENT       = 2;
308    public static final long FOLDER_ID_DRAFT      = 3;
309    public static final long FOLDER_ID_OUTBOX     = 4;
310    public static final long FOLDER_ID_DELETED    = 5;
311
312
313    /**
314     * To push RFC2822 encoded messages into a folder and read RFC2822 encoded messages from
315     * a folder, the openFile() interface will be used as follows:
316     * Open a file descriptor to a message.
317     * Two modes supported for read: With and without attachments.
318     * One mode exist for write and the actual content will be with or without
319     * attachments.
320     *
321     * mode will be "r" for read and "w" for write, never "rw".
322     *
323     * URI format:
324     * The URI scheme is as follows.
325     * For reading messages with attachments:
326     *   content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId
327     *   Note: This shall be an offline operation, including only message parts and attachments
328     *         already downloaded to the device.
329     *
330     * For reading messages without attachments:
331     *   content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_NO_ATTACHMENTS
332     *   Note: This shall be an offline operation, including only message parts already
333     *         downloaded to the device.
334     *
335     * For downloading and reading messages with attachments:
336     *   content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_DOWNLOAD
337     *   Note: This shall download the message content and all attachments if possible,
338     *         else throw an IOException.
339     *
340     * For downloading and reading messages without attachments:
341     *   content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_DOWNLOAD_NO_ATTACHMENTS
342     *   Note: This shall download the message content if possible, else throw an IOException.
343     *
344     * When reading from the file descriptor, the content provider shall return a stream
345     * of bytes containing a RFC2822 encoded message, as if the message was send to an email
346     * server.
347     *
348     * When a byte stream is written to the file descriptor, the content provider shall
349     * decode the RFC2822 encoded data and insert the message into the TABLE_MESSAGE at the ID
350     * supplied in URI - additionally the message content shall be stored in the underlying
351     * data base structure as if the message was received from an email server. The Message ID
352     * will be created using a insert on the TABLE_MESSAGE prior to calling openFile().
353     * Hence the procedure for inserting a message is:
354     *  - uri/msgId = insert(uri, value: folderId=xxx)
355     *  - fd = openFile(uri/msgId)
356     *  - fd.write (RFC2822 encoded data)
357     *
358     *  The Bluetooth Message Access Client might not know what to put into the From:
359     *  header nor have a valid time stamp, hence the content provider shall check
360     *  if the From: and Date: headers have been set by the message written, else
361     *  it must fill in appropriate values.
362     */
363    public static final String FILE_MSG_NO_ATTACHMENTS = "NO_ATTACHMENTS";
364    public static final String FILE_MSG_DOWNLOAD = "DOWNLOAD";
365    public static final String FILE_MSG_DOWNLOAD_NO_ATTACHMENTS = "DOWNLOAD_NO_ATTACHMENTS";
366
367    /**
368     * Account Table
369     * The columns needed to supply account information.
370     * The e-mail client app may choose to expose all e-mails as being from the same account,
371     * but it is not recommended, as this would be a violation of the Bluetooth specification.
372     * The Bluetooth Message Access settings activity will provide the user the ability to
373     * change the FLAG_EXPOSE values for each account in this table.
374     * The Bluetooth Message Access service will read the values when Bluetooth is turned on,
375     * and again on every notified change through the content observer interface.
376     */
377    public interface AccountColumns {
378
379        /**
380         * The unique ID for a row.
381         * <P>Type: INTEGER (long)</P>
382         */
383        public static final String _ID = "_id";
384
385        /**
386         * The account name to display to the user on the device when selecting whether
387         * or not to share the account over Bluetooth.
388         *
389         * The account display name should not reveal any sensitive information e.g. email-
390         * address, as it will be added to the Bluetooth SDP record, which can be read by
391         * any Bluetooth enabled device. (Access to any account content is only provided to
392         * authenticated devices). It is recommended that if the email client uses the email
393         * address as account name, then the address should be obfuscated (i.e. replace "@"
394         * with ".")
395         * <P>Type: TEXT</P>
396         * read-only
397         */
398        public static final String ACCOUNT_DISPLAY_NAME = "account_display_name";
399
400        /**
401         * Expose this account to other authenticated Bluetooth devices. If the expose flag
402         * is set, this account will be listed as an available account to access from another
403         * Bluetooth device.
404         *
405         * This is a read/write flag, that can be set either from within the E-mail client
406         * UI or the Bluetooth settings menu.
407         *
408         * It is recommended to either ask the user whether to expose the account, or set this
409         * to "show" as default.
410         *
411         * This setting shall not be used to enforce whether or not an account should be shared
412         * or not if the account is bound by an administrative security policy. In this case
413         * the email app should not list the account at all if it is not to be sharable over BT.
414         *
415         * <P>Type: INTEGER (boolean) hide = 0, show = 1</P>
416         */
417        public static final String FLAG_EXPOSE = "flag_expose";
418
419
420        /**
421         * The account unique identifier representing this account. For most IM clients this will be
422         * the fully qualified user name to which an invite message can be sent, from another use.
423         *
424         * e.g.: "map_test_user_12345@gmail.com" - for a Hangouts account
425         *
426         * This value will only be visible to authenticated Bluetooth devices, and will be
427         * transmitted using an encrypted link.
428         * <P>Type: TEXT</P>
429         * read-only
430         */
431        public static final String ACCOUNT_UCI = "account_uci";
432
433
434        /**
435         * The Bluetooth SIG maintains a list of assigned numbers(text strings) for IM clients.
436         * If your client/account has such a string, this is the place to return it.
437         * If supported by both devices, the presence of this prefix will make it possible to
438         * respond to a message by making a voice-call, using the same account information.
439         * (The call will be made using the HandsFree profile)
440         * https://www.bluetooth.org/en-us/specification/assigned-numbers/uniform-caller-identifiers
441         *
442         * e.g.: "hgus" - for Hangouts
443         *
444         * <P>Type: TEXT</P>
445         * read-only
446         */
447        public static final String ACCOUNT_UCI_PREFIX = "account_uci_PREFIX";
448
449    }
450
451    /**
452     * Message Data Parts Table
453     * The columns needed to contain the actual data of the messageparts in IM messages.
454     * Each "part" has its own row and represent a single mime-part in a multipart-mime
455     * formatted message.
456     *
457     */
458    public interface MessagePartColumns {
459
460        /**
461         * The unique ID for a row.
462         * <P>Type: INTEGER (long)</P>
463         * read-only
464         */
465        public static final String _ID = "_id";
466        // FIXME add message parts for IM attachments
467        /**
468         * is this a text part  yes/no?
469         * <P>Type: TEXT</P>
470         * read-only
471         */
472        public static final String TEXT = "text";
473
474        /**
475         * The charset used in the content if it is text or 8BIT if it is
476         * binary data
477         *
478         * <P>Type: TEXT</P>
479         * read-only
480         */
481        public static final String CHARSET = "charset";
482
483        /**
484         * The filename representing the data file of the raw data in the database
485         * If this is empty, then it must be text and part of the message body.
486         * This is the name that the data will have when it is included as attachment
487         *
488         * <P>Type: TEXT</P>
489         * read-only
490         */
491
492        public static final String FILENAME = "filename";
493
494        /**
495         * Identifier for the content in the data. This can be used to
496         * refer directly to the data in the body part.
497         *
498         * <P>Type: TEXT</P>
499         * read-only
500         */
501
502        public static final String CONTENT_ID = "cid";
503
504        /**
505         * The raw data in either text format or binary format
506         *
507         * <P>Type: BLOB</P>
508         * read-only
509         */
510        public static final String RAW_DATA = "raw_data";
511
512    }
513    /**
514     * The actual message table containing all messages.
515     * Content that must support filtering using WHERE clauses:
516     *   - To, From, Cc, Bcc, Date, ReadFlag, PriorityFlag, folder_id, account_id
517     * Additional content that must be supplied:
518     *   - Subject, AttachmentFlag, LoadedState, MessageSize, AttachmentSize
519     * Content that must support update:
520     *   - FLAG_READ and FOLDER_ID (FOLDER_ID is used to move a message to deleted)
521     * Additional insert of a new message with the following values shall be supported:
522     *   - FOLDER_ID
523     *
524     * When doing an insert on this table, the actual content of the message (subject,
525     * date etc) written through file-i/o takes precedence over the inserted values and should
526     * overwrite them.
527     */
528    public interface MessageColumns extends EmailMessageColumns {
529
530        /**
531         * The unique ID for a row.
532         * <P>Type: INTEGER (long)</P>
533         */
534        public static final String _ID = "_id";
535
536        /**
537         * The date the message was received as a unix timestamp
538         * (miliseconds since 00:00:00 UTC 1/1-1970).
539         *
540         * <P>Type: INTEGER (long)</P>
541         * read-only
542         */
543        public static final String DATE = "date";
544
545        //TODO REMOVE WHEN Parts Table is in place
546        /**
547         * Message body. Used by Instant Messaging
548         * <P>Type: TEXT</P>
549         * read-only.
550         */
551        public static final String BODY = "body";
552
553        /**
554         * Message subject.
555         * <P>Type: TEXT</P>
556         * read-only.
557         */
558        public static final String SUBJECT = "subject";
559
560        /**
561         * Message Read flag
562         * <P>Type: INTEGER (boolean) unread = 0, read = 1</P>
563         *  read/write
564         */
565        public static final String FLAG_READ = "flag_read";
566
567        /**
568         * Message Priority flag
569         * <P>Type: INTEGER (boolean) normal priority = 0, high priority = 1</P>
570         * read-only
571         */
572        public static final String FLAG_HIGH_PRIORITY = "high_priority";
573
574        /**
575         * Reception state - the amount of the message that have been loaded from the server.
576         * <P>Type: TEXT see RECEPTION_STATE_* constants below </P>
577         * read-only
578         */
579        public static final String RECEPTION_STATE = "reception_state";
580
581        /**
582         * Delivery state - the amount of the message that have been loaded from the server.
583         * <P>Type: TEXT see DELIVERY_STATE_* constants below </P>
584         * read-only
585         */
586        public static final String DEVILERY_STATE = "delivery_state";
587
588        /** To be able to filter messages with attachments, we need this flag.
589         * <P>Type: INTEGER (boolean) no attachment = 0, attachment = 1 </P>
590         * read-only
591         */
592        public static final String FLAG_ATTACHMENT = "flag_attachment";
593
594        /** The overall size in bytes of the attachments of the message.
595         * <P>Type: INTEGER </P>
596         */
597        public static final String ATTACHMENT_SIZE = "attachment_size";
598
599        /** The mine type of the attachments for the message.
600         * <P>Type: TEXT </P>
601         * read-only
602         */
603        public static final String ATTACHMENT_MINE_TYPES = "attachment_mime_types";
604
605        /** The overall size in bytes of the message including any attachments.
606         * This value is informative only and should be the size an email client
607         * would display as size for the message.
608         * <P>Type: INTEGER </P>
609         * read-only
610         */
611        public static final String MESSAGE_SIZE = "message_size";
612
613        /** Indicates that the message or a part of it is protected by a DRM scheme.
614         * <P>Type: INTEGER (boolean) no DRM = 0, DRM protected = 1 </P>
615         * read-only
616         */
617        public static final String FLAG_PROTECTED = "flag_protected";
618
619        /**
620         * A comma-delimited list of FROM addresses in RFC2822 format.
621         * The list must be compatible with Rfc822Tokenizer.tokenize();
622         * <P>Type: TEXT</P>
623         * read-only
624         */
625        public static final String FROM_LIST = "from_list";
626
627        /**
628         * A comma-delimited list of TO addresses in RFC2822 format.
629         * The list must be compatible with Rfc822Tokenizer.tokenize();
630         * <P>Type: TEXT</P>
631         * read-only
632         */
633        public static final String TO_LIST = "to_list";
634
635        /**
636         * The unique ID for a row in the folder table in which this message belongs.
637         * <P>Type: INTEGER (long)</P>
638         * read/write
639         */
640        public static final String FOLDER_ID = "folder_id";
641
642        /**
643         * The unique ID for a row in the account table which owns this message.
644         * <P>Type: INTEGER (long)</P>
645         * read-only
646         */
647        public static final String ACCOUNT_ID = "account_id";
648
649        /**
650         * The ID identify the thread/conversation a message belongs to.
651         * If no thread id is available, set value to "-1"
652         * <P>Type: INTEGER (long)</P>
653         * read-only
654         */
655        public static final String THREAD_ID = "thread_id";
656
657        /**
658         * The Name of the thread/conversation a message belongs to.
659         * <P>Type: TEXT</P>
660         * read-only
661         */
662        public static final String THREAD_NAME = "thread_name";
663    }
664
665    public interface EmailMessageColumns {
666
667
668
669        /**
670         * A comma-delimited list of CC addresses in RFC2822 format.
671         * The list must be compatible with Rfc822Tokenizer.tokenize();
672         * <P>Type: TEXT</P>
673         * read-only
674         */
675        public static final String CC_LIST = "cc_list";
676
677        /**
678         * A comma-delimited list of BCC addresses in RFC2822 format.
679         * The list must be compatible with Rfc822Tokenizer.tokenize();
680         * <P>Type: TEXT</P>
681         * read-only
682         */
683        public static final String BCC_LIST = "bcc_list";
684
685        /**
686         * A comma-delimited list of REPLY-TO addresses in RFC2822 format.
687         * The list must be compatible with Rfc822Tokenizer.tokenize();
688         * <P>Type: TEXT</P>
689         * read-only
690         */
691        public static final String REPLY_TO_LIST = "reply_to_List";
692
693
694    }
695
696    /**
697     * Indicates the complete message has been delivered to the recipient.
698     */
699    public static final String DELIVERY_STATE_DELIVERED = "delivered";
700    /**
701     * Indicates that the complete message has been sent from the MSE to the remote network.
702     */
703    public static final String DELIVERY_STATE_SENT = "sent";
704
705    /**
706     * Indicates that the message, including any attachments, has been received from the
707     * server to the device.
708     */
709    public static final String RECEPTION_STATE_COMPLETE = "complete";
710    /**
711     * Indicates the message is partially received from the email server.
712     */
713    public static final String RECEPTION_STATE_FRACTIONED = "fractioned";
714    /**
715     * Indicates that only a notification about the message have been received.
716     */
717    public static final String RECEPTION_STATE_NOTIFICATION = "notification";
718
719    /**
720     * Message folder structure
721     * MAP enforces use of a folder structure with mandatory folders:
722     *   - inbox, outbox, sent, deleted, draft
723     * User defined folders are supported.
724     * The folder table must provide filtering (use of WHERE clauses) of the following entries:
725     *   - account_id (linking the folder to an e-mail account)
726     *   - parent_id (linking the folders individually)
727     * The folder table must have a folder name for each entry, and the mandatory folders
728     * MUST exist for each account_id. The folders may be empty.
729     * Use the FOLDER_NAME_xxx constants for the mandatory folders. Their names must
730     * not be translated into other languages, as the folder browsing is string based, and
731     * many Bluetooth Message Clients will use these strings to navigate to the folders.
732     */
733    public interface FolderColumns {
734
735        /**
736         * The unique ID for a row.
737         * <P>Type: INTEGER (long)</P>
738         * read-only
739         */
740        public static final String _ID = "_id";
741
742        /**
743         * The folder display name to present to the user.
744         * <P>Type: TEXT</P>
745         * read-only
746         */
747        public static final String NAME = "name";
748
749        /**
750         * The _id-key to the account this folder refers to.
751         * <P>Type: INTEGER (long)</P>
752         * read-only
753         */
754        public static final String ACCOUNT_ID = "account_id";
755
756        /**
757         * The _id-key to the parent folder. -1 for root folders.
758         * <P>Type: INTEGER (long)</P>
759         * read-only
760         */
761        public static final String PARENT_FOLDER_ID = "parent_id";
762    }
763
764    /**
765     * Message conversation structure. Enables use of a conversation structure for messages across
766     * folders, further binding contacts to conversations.
767     * Content that must be supplied:
768     *   - Name, LastActivity, ReadStatus, VersionCounter
769     * Content that must support update:
770     *   - READ_STATUS, LAST_ACTIVITY and VERSION_COUNTER (VERSION_COUNTER used to validity of _ID)
771     * Additional insert of a new conversation with the following values shall be supported:
772     *   - FOLDER_ID
773     * When querying this table, the cursor returned must contain one row for each contact member
774     * in a thread.
775     * For filter/search parameters attributes to the URI will be used. The following columns must
776     * support filtering:
777     *  - ConvoContactColumns.NAME
778     *  - ConversationColumns.THREAD_ID
779     *  - ConversationColumns.LAST_ACTIVITY
780     *  - ConversationColumns.READ_STATUS
781     */
782    public interface ConversationColumns extends ConvoContactColumns {
783
784        /**
785         * The unique ID for a row.
786         * <P>Type: INTEGER (long)</P>
787         * read-only
788         */
789// Should not be needed anymore        public static final String _ID = "_id";
790
791        /**
792         * The unique ID for a Thread.
793         * <P>Type: INTEGER (long)</P>
794         * read-only
795         */
796        public static final String THREAD_ID = "thread_id";
797
798        /**
799         * The unique ID for a row.
800         * <P>Type: INTEGER (long)</P>
801         * read-only
802         */
803// TODO: IS THIS NECESSARY - or do we need the thread ID to hold thread Id from message
804//       or can we be sure we are in control and can use the _ID and put that in the message DB
805        //public static final String THREAD_ID = "thread_id";
806
807        /**
808         * The type of conversation, see {@link ConversationType}
809         * <P>Type: TEXT</P>
810         * read-only
811         */
812// TODO: IS THIS NECESSARY - no conversation type is available in the latest,
813//        guess it can be found from number of contacts in the conversation
814        //public static final String TYPE = "type";
815
816        /**
817         * The name of the conversation, e.g. group name in case of group chat
818         * <P>Type: TEXT</P>
819         * read-only
820         */
821        public static final String THREAD_NAME = "thread_name";
822
823        /**
824         * The time stamp of the last activity in the conversation as a unix timestamp
825         * (miliseconds since 00:00:00 UTC 1/1-1970)
826         * <P>Type: INTEGER (long)</P>
827         * read-only
828         */
829        public static final String LAST_THREAD_ACTIVITY = "last_thread_activity";
830
831        /**
832         * The status on the conversation, either 'read' or 'unread'
833         *  <P>Type: INTEGER (boolean) unread = 0, read = 1</P>
834         * read/write
835         */
836        public static final String READ_STATUS = "read_status";
837
838        /**
839         * A counter that keep tack of version of the table content, count up on ID reuse
840         * <P>Type: INTEGER (long)</P>
841         * read-only
842         */
843// TODO: IS THIS NECESSARY - skal den ligge i databasen?
844        // CB: If we need it, it must be in the database, or initialized with a random value at
845        //     BT-ON
846        // UPDATE: TODO: Change to the last_activity time stamp (as a long value). This will
847        //         provide the information needed for BT clients - currently unused
848        public static final String VERSION_COUNTER = "version_counter";
849
850        /**
851         * A short description of the latest activity on conversation - typically
852         * part of the last message.
853         * <P>Type: TEXT</P>
854         * read-only
855         */
856        public static final String SUMMARY = "convo_summary";
857
858
859    }
860
861    /**
862     * MAP enables access to contacts for the conversation
863     * The conversation table must provide filtering (using WHERE clauses) of following entries:
864     *   - convo_id linking contacts to conversations
865     *   - x_bt_uid linking contacts to PBAP contacts
866     * The conversation contact table must have a convo_id and a name for each entry.
867     */
868    public interface ConvoContactColumns extends ChatStatusColumns, PresenceColumns {
869        /**
870         * The unique ID for a contact in Conversation
871         * <P>Type: INTEGER (long)</P>
872         * read-only
873         */
874// Should not be needed anymore        public static final String _ID = "_id";
875
876        /**
877        * The ID of the conversation the contact is part of.
878        * <P>Type: INTEGER (long)</P>
879        * read-only
880        */
881        public static final String CONVO_ID = "convo_id";
882
883        /**
884         * The name of contact in instant message application
885         * <P>Type: TEXT</P>
886         * read-only
887         */
888        public static final String NAME = "name";
889
890        /**
891         * The nickname of contact in instant message group chat conversation.
892         * <P>Type: TEXT</P>
893         * read-only
894         */
895        public static final String NICKNAME = "nickname";
896
897
898        /**
899         * The unique ID for all Bluetooth contacts available through PBAP.
900         * <P>Type: INTEGER (long)</P>
901         * read-only
902         */
903        public static final String X_BT_UID = "x_bt_uid";
904
905        /**
906         * The unique ID for the contact within the domain of the interfacing service.
907         * (UCI: Unique Call Identity)
908         * It is expected that a message send to this ID will reach the recipient regardless
909         * through which interface the message is send.
910         * For E-mail this will be the e-mail address, for Google+ this will be the e-mail address
911         * associated with the contact account.
912         * This ID
913         * <P>Type: TEXT</P>
914         * read-only
915         */
916        public static final String UCI = "x_bt_uci";
917    }
918
919    /**
920     * The name of query parameter used to filter on recipient
921     */
922    public static final String FILTER_RECIPIENT_SUBSTRING = "rec_sub_str";
923
924    /**
925     * The name of query parameter used to filter on originator
926     */
927    public static final String FILTER_ORIGINATOR_SUBSTRING = "org_sub_str";
928
929    /**
930     * The name of query parameter used to filter on read status.
931     *  - true - return only threads with all messages marked as read
932     *  - false - return only threads with one or more unread messages
933     *  - omitted as query parameter - do not filter on read status
934     */
935    public static final String FILTER_READ_STATUS = "read";
936
937    /**
938     * Time in ms since epoch. For conversations this will be for last activity
939     * as a unix timestamp (miliseconds since 00:00:00 UTC 1/1-1970)
940     */
941    public static final String FILTER_PERIOD_BEGIN = "t_begin";
942
943    /**
944     * Time in ms since epoch. For conversations this will be for last activity
945     * as a unix timestamp (miliseconds since 00:00:00 UTC 1/1-1970)
946     */
947    public static final String FILTER_PERIOD_END = "t_end";
948
949    /**
950     * Filter for a specific ThreadId
951     */
952    public static final String FILTER_THREAD_ID = "thread_id";
953
954
955    public interface ChatState {
956        int UNKNOWN     = 0;
957        int INACITVE    = 1;
958        int ACITVE      = 2;
959        int COMPOSING   = 3;
960        int PAUSED      = 4;
961        int GONE        = 5;
962    }
963
964    /**
965     * Instant Messaging contact chat state information
966     * MAP enables access to contacts chat state for the instant messaging application
967     * The chat state table must provide filtering (use of WHERE clauses) of the following entries:
968     *   - contact_id (linking chat state to contacts)
969     *   - thread_id (linking chat state to conversations and messages)
970     * The presence table must have a contact_id for each entry.
971     */
972    public interface ChatStatusColumns {
973
974//        /**
975//         * The contact ID of a instant messaging contact.
976//         * <P>Type: TEXT </P>
977//         * read-only
978//         */
979//        public static final String CONTACT_ID = "contact_id";
980//
981//        /**
982//         * The thread id for a conversation.
983//         * <P>Type: INTEGER (long)</P>
984//         * read-only
985//         */
986//        public static final String CONVO_ID = "convo_id";
987
988        /**
989         * The chat state of contact in conversation, see {@link ChatState}
990         * <P>Type: INTERGER</P>
991         * read-only
992         */
993        public static final String CHAT_STATE = "chat_state";
994
995//        /**
996//         * The geo location of the contact
997//         * <P>Type: TEXT</P>
998//         * read-only
999//         */
1000//// TODO: IS THIS NEEDED - not in latest specification
1001//        public static final String GEOLOC = "geoloc";
1002
1003        /**
1004         * The time stamp of the last time this contact was active in the conversation
1005         * <P>Type: INTEGER (long)</P>
1006         * read-only
1007         */
1008        public static final String LAST_ACTIVE = "last_active";
1009
1010    }
1011
1012    public interface PresenceState {
1013        int UNKNOWN         = 0;
1014        int OFFLINE         = 1;
1015        int ONLINE          = 2;
1016        int AWAY            = 3;
1017        int DO_NOT_DISTURB  = 4;
1018        int BUSY            = 5;
1019        int IN_A_MEETING    = 6;
1020    }
1021
1022    /**
1023     * Instant Messaging contact presence information
1024     * MAP enables access to contacts presences information for the instant messaging application
1025     * The presence table must provide filtering (use of WHERE clauses) of the following entries:
1026     *   - contact_id (linking contacts to presence)
1027     * The presence table must have a contact_id for each entry.
1028     */
1029    public interface PresenceColumns {
1030
1031//        /**
1032//         * The contact ID of a instant messaging contact.
1033//         * <P>Type: TEXT </P>
1034//         * read-only
1035//         */
1036//        public static final String CONTACT_ID = "contact_id";
1037
1038        /**
1039         * The presence state of contact, see {@link PresenceState}
1040         * <P>Type: INTERGER</P>
1041         * read-only
1042         */
1043        public static final String PRESENCE_STATE = "presence_state";
1044
1045        /**
1046         * The priority of contact presence
1047         * <P>Type: INTERGER</P>
1048         * read-only
1049         */
1050// TODO: IS THIS NEEDED - not in latest specification
1051        public static final String PRIORITY = "priority";
1052
1053        /**
1054         * The last status text from contact
1055         * <P>Type: TEXT</P>
1056         * read-only
1057         */
1058        public static final String STATUS_TEXT = "status_text";
1059
1060        /**
1061         * The time stamp of the last time the contact was online
1062         * <P>Type: INTEGER (long)</P>
1063         * read-only
1064         */
1065        public static final String LAST_ONLINE = "last_online";
1066
1067    }
1068
1069
1070    /**
1071     * A projection of all the columns in the Message table
1072     */
1073    public static final String[] BT_MESSAGE_PROJECTION = new String[] {
1074        MessageColumns._ID,
1075        MessageColumns.DATE,
1076        MessageColumns.SUBJECT,
1077        //TODO REMOVE WHEN Parts Table is in place
1078        MessageColumns.BODY,
1079        MessageColumns.MESSAGE_SIZE,
1080        MessageColumns.FOLDER_ID,
1081        MessageColumns.FLAG_READ,
1082        MessageColumns.FLAG_PROTECTED,
1083        MessageColumns.FLAG_HIGH_PRIORITY,
1084        MessageColumns.FLAG_ATTACHMENT,
1085        MessageColumns.ATTACHMENT_SIZE,
1086        MessageColumns.FROM_LIST,
1087        MessageColumns.TO_LIST,
1088        MessageColumns.CC_LIST,
1089        MessageColumns.BCC_LIST,
1090        MessageColumns.REPLY_TO_LIST,
1091        MessageColumns.RECEPTION_STATE,
1092        MessageColumns.DEVILERY_STATE,
1093        MessageColumns.THREAD_ID
1094    };
1095
1096    public static final String[] BT_INSTANT_MESSAGE_PROJECTION = new String[] {
1097        MessageColumns._ID,
1098        MessageColumns.DATE,
1099        MessageColumns.SUBJECT,
1100        MessageColumns.MESSAGE_SIZE,
1101        MessageColumns.FOLDER_ID,
1102        MessageColumns.FLAG_READ,
1103        MessageColumns.FLAG_PROTECTED,
1104        MessageColumns.FLAG_HIGH_PRIORITY,
1105        MessageColumns.FLAG_ATTACHMENT,
1106        MessageColumns.ATTACHMENT_SIZE,
1107        MessageColumns.ATTACHMENT_MINE_TYPES,
1108        MessageColumns.FROM_LIST,
1109        MessageColumns.TO_LIST,
1110        MessageColumns.RECEPTION_STATE,
1111        MessageColumns.DEVILERY_STATE,
1112        MessageColumns.THREAD_ID,
1113        MessageColumns.THREAD_NAME
1114    };
1115
1116    /**
1117     * A projection of all the columns in the Account table
1118     */
1119    public static final String[] BT_ACCOUNT_PROJECTION = new String[] {
1120        AccountColumns._ID,
1121        AccountColumns.ACCOUNT_DISPLAY_NAME,
1122        AccountColumns.FLAG_EXPOSE,
1123    };
1124
1125    /**
1126     * A projection of all the columns in the Account table
1127     * TODO: Is this the way to differentiate
1128     */
1129    public static final String[] BT_IM_ACCOUNT_PROJECTION = new String[] {
1130        AccountColumns._ID,
1131        AccountColumns.ACCOUNT_DISPLAY_NAME,
1132        AccountColumns.FLAG_EXPOSE,
1133        AccountColumns.ACCOUNT_UCI,
1134        AccountColumns.ACCOUNT_UCI_PREFIX
1135    };
1136
1137    /**
1138     * A projection of all the columns in the Folder table
1139     */
1140    public static final String[] BT_FOLDER_PROJECTION = new String[] {
1141        FolderColumns._ID,
1142        FolderColumns.NAME,
1143        FolderColumns.ACCOUNT_ID,
1144        FolderColumns.PARENT_FOLDER_ID
1145    };
1146
1147
1148    /**
1149     * A projection of all the columns in the Conversation table
1150     */
1151    public static final String[] BT_CONVERSATION_PROJECTION = new String[] {
1152        /* Thread information */
1153        ConversationColumns.THREAD_ID,
1154        ConversationColumns.THREAD_NAME,
1155        ConversationColumns.READ_STATUS,
1156        ConversationColumns.LAST_THREAD_ACTIVITY,
1157        ConversationColumns.VERSION_COUNTER,
1158        ConversationColumns.SUMMARY,
1159        /* Contact information */
1160        ConversationColumns.UCI,
1161        ConversationColumns.NAME,
1162        ConversationColumns.NICKNAME,
1163        ConversationColumns.CHAT_STATE,
1164        ConversationColumns.LAST_ACTIVE,
1165        ConversationColumns.X_BT_UID,
1166        ConversationColumns.PRESENCE_STATE,
1167        ConversationColumns.STATUS_TEXT,
1168        ConversationColumns.PRIORITY
1169    };
1170
1171    /**
1172     * A projection of the Contact Info and Presence columns in the Contact Info in table
1173     */
1174    public static final String[] BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION = new String[] {
1175        ConvoContactColumns.UCI,
1176        ConvoContactColumns.CONVO_ID,
1177        ConvoContactColumns.NAME,
1178        ConvoContactColumns.NICKNAME,
1179        ConvoContactColumns.X_BT_UID,
1180        ConvoContactColumns.CHAT_STATE,
1181        ConvoContactColumns.LAST_ACTIVE,
1182        ConvoContactColumns.PRESENCE_STATE,
1183        ConvoContactColumns.PRIORITY,
1184        ConvoContactColumns.STATUS_TEXT,
1185        ConvoContactColumns.LAST_ONLINE
1186    };
1187
1188    /**
1189     * A projection of the Contact Info the columns in Contacts Info table
1190     */
1191    public static final String[] BT_CONTACT_PROJECTION = new String[] {
1192        ConvoContactColumns.UCI,
1193        ConvoContactColumns.CONVO_ID,
1194        ConvoContactColumns.X_BT_UID,
1195        ConvoContactColumns.NAME,
1196        ConvoContactColumns.NICKNAME
1197    };
1198
1199
1200    /**
1201     * A projection of all the columns in the Chat Status table
1202     */
1203    public static final String[] BT_CHATSTATUS_PROJECTION = new String[] {
1204        ChatStatusColumns.CHAT_STATE,
1205        ChatStatusColumns.LAST_ACTIVE,
1206    };
1207
1208    /**
1209     * A projection of all the columns in the Presence table
1210     */
1211    public static final String[] BT_PRESENCE_PROJECTION = new String[] {
1212        PresenceColumns.PRESENCE_STATE,
1213        PresenceColumns.PRIORITY,
1214        PresenceColumns.STATUS_TEXT,
1215        PresenceColumns.LAST_ONLINE
1216    };
1217
1218}
1219