Telephony.java revision 90271d9ef1377b25b78359039fb2e87f32aba25b
1/*
2 * Copyright (C) 2006 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 android.provider;
18
19import android.annotation.SdkConstant;
20import android.annotation.SdkConstant.SdkConstantType;
21import android.content.ContentResolver;
22import android.content.ContentValues;
23import android.content.Context;
24import android.content.Intent;
25import android.database.Cursor;
26import android.database.sqlite.SqliteWrapper;
27import android.net.Uri;
28import android.telephony.SmsMessage;
29import android.text.TextUtils;
30import android.telephony.Rlog;
31import android.util.Patterns;
32
33
34import java.util.HashSet;
35import java.util.Set;
36import java.util.regex.Matcher;
37import java.util.regex.Pattern;
38
39/**
40 * The Telephony provider contains data related to phone operation.
41 *
42 * @hide
43 */
44public final class Telephony {
45    private static final String TAG = "Telephony";
46
47    // Constructor
48    public Telephony() {
49    }
50
51    /**
52     * Base columns for tables that contain text based SMSs.
53     */
54    public interface TextBasedSmsColumns {
55        /**
56         * The type of the message
57         * <P>Type: INTEGER</P>
58         */
59        public static final String TYPE = "type";
60
61        public static final int MESSAGE_TYPE_ALL    = 0;
62        public static final int MESSAGE_TYPE_INBOX  = 1;
63        public static final int MESSAGE_TYPE_SENT   = 2;
64        public static final int MESSAGE_TYPE_DRAFT  = 3;
65        public static final int MESSAGE_TYPE_OUTBOX = 4;
66        public static final int MESSAGE_TYPE_FAILED = 5; // for failed outgoing messages
67        public static final int MESSAGE_TYPE_QUEUED = 6; // for messages to send later
68
69
70        /**
71         * The thread ID of the message
72         * <P>Type: INTEGER</P>
73         */
74        public static final String THREAD_ID = "thread_id";
75
76        /**
77         * The address of the other party
78         * <P>Type: TEXT</P>
79         */
80        public static final String ADDRESS = "address";
81
82        /**
83         * The person ID of the sender
84         * <P>Type: INTEGER (long)</P>
85         */
86        public static final String PERSON_ID = "person";
87
88        /**
89         * The date the message was received
90         * <P>Type: INTEGER (long)</P>
91         */
92        public static final String DATE = "date";
93
94        /**
95         * The date the message was sent
96         * <P>Type: INTEGER (long)</P>
97         */
98        public static final String DATE_SENT = "date_sent";
99
100        /**
101         * Has the message been read
102         * <P>Type: INTEGER (boolean)</P>
103         */
104        public static final String READ = "read";
105
106        /**
107         * Indicates whether this message has been seen by the user. The "seen" flag will be
108         * used to figure out whether we need to throw up a statusbar notification or not.
109         */
110        public static final String SEEN = "seen";
111
112        /**
113         * The TP-Status value for the message, or -1 if no status has
114         * been received
115         */
116        public static final String STATUS = "status";
117
118        public static final int STATUS_NONE = -1;
119        public static final int STATUS_COMPLETE = 0;
120        public static final int STATUS_PENDING = 32;
121        public static final int STATUS_FAILED = 64;
122
123        /**
124         * The subject of the message, if present
125         * <P>Type: TEXT</P>
126         */
127        public static final String SUBJECT = "subject";
128
129        /**
130         * The body of the message
131         * <P>Type: TEXT</P>
132         */
133        public static final String BODY = "body";
134
135        /**
136         * The id of the sender of the conversation, if present
137         * <P>Type: INTEGER (reference to item in content://contacts/people)</P>
138         */
139        public static final String PERSON = "person";
140
141        /**
142         * The protocol identifier code
143         * <P>Type: INTEGER</P>
144         */
145        public static final String PROTOCOL = "protocol";
146
147        /**
148         * Whether the <code>TP-Reply-Path</code> bit was set on this message
149         * <P>Type: BOOLEAN</P>
150         */
151        public static final String REPLY_PATH_PRESENT = "reply_path_present";
152
153        /**
154         * The service center (SC) through which to send the message, if present
155         * <P>Type: TEXT</P>
156         */
157        public static final String SERVICE_CENTER = "service_center";
158
159        /**
160         * Has the message been locked?
161         * <P>Type: INTEGER (boolean)</P>
162         */
163        public static final String LOCKED = "locked";
164
165        /**
166         * Error code associated with sending or receiving this message
167         * <P>Type: INTEGER</P>
168         */
169        public static final String ERROR_CODE = "error_code";
170
171        /**
172         * Meta data used externally.
173         * <P>Type: TEXT</P>
174         */
175        public static final String META_DATA = "meta_data";
176    }
177
178    /**
179     * Contains all text based SMS messages.
180     */
181    public static final class Sms implements BaseColumns, TextBasedSmsColumns {
182        public static final Cursor query(ContentResolver cr, String[] projection) {
183            return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
184        }
185
186        public static final Cursor query(ContentResolver cr, String[] projection,
187                String where, String orderBy) {
188            return cr.query(CONTENT_URI, projection, where,
189                                         null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
190        }
191
192        /**
193         * The content:// style URL for this table
194         */
195        public static final Uri CONTENT_URI =
196            Uri.parse("content://sms");
197
198        /**
199         * The default sort order for this table
200         */
201        public static final String DEFAULT_SORT_ORDER = "date DESC";
202
203        /**
204         * Add an SMS to the given URI.
205         *
206         * @param resolver the content resolver to use
207         * @param uri the URI to add the message to
208         * @param address the address of the sender
209         * @param body the body of the message
210         * @param subject the psuedo-subject of the message
211         * @param date the timestamp for the message
212         * @param read true if the message has been read, false if not
213         * @param deliveryReport true if a delivery report was requested, false if not
214         * @return the URI for the new message
215         */
216        public static Uri addMessageToUri(ContentResolver resolver,
217                Uri uri, String address, String body, String subject,
218                Long date, boolean read, boolean deliveryReport) {
219            return addMessageToUri(resolver, uri, address, body, subject,
220                    date, read, deliveryReport, -1L);
221        }
222
223        /**
224         * Add an SMS to the given URI with thread_id specified.
225         *
226         * @param resolver the content resolver to use
227         * @param uri the URI to add the message to
228         * @param address the address of the sender
229         * @param body the body of the message
230         * @param subject the psuedo-subject of the message
231         * @param date the timestamp for the message
232         * @param read true if the message has been read, false if not
233         * @param deliveryReport true if a delivery report was requested, false if not
234         * @param threadId the thread_id of the message
235         * @return the URI for the new message
236         */
237        public static Uri addMessageToUri(ContentResolver resolver,
238                Uri uri, String address, String body, String subject,
239                Long date, boolean read, boolean deliveryReport, long threadId) {
240            ContentValues values = new ContentValues(7);
241
242            values.put(ADDRESS, address);
243            if (date != null) {
244                values.put(DATE, date);
245            }
246            values.put(READ, read ? Integer.valueOf(1) : Integer.valueOf(0));
247            values.put(SUBJECT, subject);
248            values.put(BODY, body);
249            if (deliveryReport) {
250                values.put(STATUS, STATUS_PENDING);
251            }
252            if (threadId != -1L) {
253                values.put(THREAD_ID, threadId);
254            }
255            return resolver.insert(uri, values);
256        }
257
258        /**
259         * Move a message to the given folder.
260         *
261         * @param context the context to use
262         * @param uri the message to move
263         * @param folder the folder to move to
264         * @return true if the operation succeeded
265         */
266        public static boolean moveMessageToFolder(Context context,
267                Uri uri, int folder, int error) {
268            if (uri == null) {
269                return false;
270            }
271
272            boolean markAsUnread = false;
273            boolean markAsRead = false;
274            switch(folder) {
275            case MESSAGE_TYPE_INBOX:
276            case MESSAGE_TYPE_DRAFT:
277                break;
278            case MESSAGE_TYPE_OUTBOX:
279            case MESSAGE_TYPE_SENT:
280                markAsRead = true;
281                break;
282            case MESSAGE_TYPE_FAILED:
283            case MESSAGE_TYPE_QUEUED:
284                markAsUnread = true;
285                break;
286            default:
287                return false;
288            }
289
290            ContentValues values = new ContentValues(3);
291
292            values.put(TYPE, folder);
293            if (markAsUnread) {
294                values.put(READ, Integer.valueOf(0));
295            } else if (markAsRead) {
296                values.put(READ, Integer.valueOf(1));
297            }
298            values.put(ERROR_CODE, error);
299
300            return 1 == SqliteWrapper.update(context, context.getContentResolver(),
301                            uri, values, null, null);
302        }
303
304        /**
305         * Returns true iff the folder (message type) identifies an
306         * outgoing message.
307         */
308        public static boolean isOutgoingFolder(int messageType) {
309            return  (messageType == MESSAGE_TYPE_FAILED)
310                    || (messageType == MESSAGE_TYPE_OUTBOX)
311                    || (messageType == MESSAGE_TYPE_SENT)
312                    || (messageType == MESSAGE_TYPE_QUEUED);
313        }
314
315        /**
316         * Contains all text based SMS messages in the SMS app's inbox.
317         */
318        public static final class Inbox implements BaseColumns, TextBasedSmsColumns {
319            /**
320             * The content:// style URL for this table
321             */
322            public static final Uri CONTENT_URI =
323                Uri.parse("content://sms/inbox");
324
325            /**
326             * The default sort order for this table
327             */
328            public static final String DEFAULT_SORT_ORDER = "date DESC";
329
330            /**
331             * Add an SMS to the Draft box.
332             *
333             * @param resolver the content resolver to use
334             * @param address the address of the sender
335             * @param body the body of the message
336             * @param subject the psuedo-subject of the message
337             * @param date the timestamp for the message
338             * @param read true if the message has been read, false if not
339             * @return the URI for the new message
340             */
341            public static Uri addMessage(ContentResolver resolver,
342                    String address, String body, String subject, Long date,
343                    boolean read) {
344                return addMessageToUri(resolver, CONTENT_URI, address, body,
345                        subject, date, read, false);
346            }
347        }
348
349        /**
350         * Contains all sent text based SMS messages in the SMS app's.
351         */
352        public static final class Sent implements BaseColumns, TextBasedSmsColumns {
353            /**
354             * The content:// style URL for this table
355             */
356            public static final Uri CONTENT_URI =
357                    Uri.parse("content://sms/sent");
358
359            /**
360             * The default sort order for this table
361             */
362            public static final String DEFAULT_SORT_ORDER = "date DESC";
363
364            /**
365             * Add an SMS to the Draft box.
366             *
367             * @param resolver the content resolver to use
368             * @param address the address of the sender
369             * @param body the body of the message
370             * @param subject the psuedo-subject of the message
371             * @param date the timestamp for the message
372             * @return the URI for the new message
373             */
374            public static Uri addMessage(ContentResolver resolver,
375                    String address, String body, String subject, Long date) {
376                return addMessageToUri(resolver, CONTENT_URI, address, body,
377                        subject, date, true, false);
378            }
379        }
380
381        /**
382         * Contains all sent text based SMS messages in the SMS app's.
383         */
384        public static final class Draft implements BaseColumns, TextBasedSmsColumns {
385            /**
386             * The content:// style URL for this table
387             */
388            public static final Uri CONTENT_URI =
389                    Uri.parse("content://sms/draft");
390
391            /**
392             * The default sort order for this table
393             */
394            public static final String DEFAULT_SORT_ORDER = "date DESC";
395
396            /**
397             * Add an SMS to the Draft box.
398             *
399             * @param resolver the content resolver to use
400             * @param address the address of the sender
401             * @param body the body of the message
402             * @param subject the psuedo-subject of the message
403             * @param date the timestamp for the message
404             * @return the URI for the new message
405             */
406            public static Uri addMessage(ContentResolver resolver,
407                    String address, String body, String subject, Long date) {
408                return addMessageToUri(resolver, CONTENT_URI, address, body,
409                        subject, date, true, false);
410            }
411
412            /**
413             * Save over an existing draft message.
414             *
415             * @param resolver the content resolver to use
416             * @param uri of existing message
417             * @param body the new body for the draft message
418             * @return true is successful, false otherwise
419             */
420            public static boolean saveMessage(ContentResolver resolver,
421                    Uri uri, String body) {
422                ContentValues values = new ContentValues(2);
423                values.put(BODY, body);
424                values.put(DATE, System.currentTimeMillis());
425                return resolver.update(uri, values, null, null) == 1;
426            }
427        }
428
429        /**
430         * Contains all pending outgoing text based SMS messages.
431         */
432        public static final class Outbox implements BaseColumns, TextBasedSmsColumns {
433            /**
434             * The content:// style URL for this table
435             */
436            public static final Uri CONTENT_URI =
437                Uri.parse("content://sms/outbox");
438
439            /**
440             * The default sort order for this table
441             */
442            public static final String DEFAULT_SORT_ORDER = "date DESC";
443
444            /**
445             * Add an SMS to the Out box.
446             *
447             * @param resolver the content resolver to use
448             * @param address the address of the sender
449             * @param body the body of the message
450             * @param subject the psuedo-subject of the message
451             * @param date the timestamp for the message
452             * @param deliveryReport whether a delivery report was requested for the message
453             * @return the URI for the new message
454             */
455            public static Uri addMessage(ContentResolver resolver,
456                    String address, String body, String subject, Long date,
457                    boolean deliveryReport, long threadId) {
458                return addMessageToUri(resolver, CONTENT_URI, address, body,
459                        subject, date, true, deliveryReport, threadId);
460            }
461        }
462
463        /**
464         * Contains all sent text-based SMS messages in the SMS app's.
465         */
466        public static final class Conversations
467                implements BaseColumns, TextBasedSmsColumns {
468            /**
469             * The content:// style URL for this table
470             */
471            public static final Uri CONTENT_URI =
472                Uri.parse("content://sms/conversations");
473
474            /**
475             * The default sort order for this table
476             */
477            public static final String DEFAULT_SORT_ORDER = "date DESC";
478
479            /**
480             * The first 45 characters of the body of the message
481             * <P>Type: TEXT</P>
482             */
483            public static final String SNIPPET = "snippet";
484
485            /**
486             * The number of messages in the conversation
487             * <P>Type: INTEGER</P>
488             */
489            public static final String MESSAGE_COUNT = "msg_count";
490        }
491
492        /**
493         * Contains info about SMS related Intents that are broadcast.
494         */
495        public static final class Intents {
496            /**
497             * Set by BroadcastReceiver. Indicates the message was handled
498             * successfully.
499             */
500            public static final int RESULT_SMS_HANDLED = 1;
501
502            /**
503             * Set by BroadcastReceiver. Indicates a generic error while
504             * processing the message.
505             */
506            public static final int RESULT_SMS_GENERIC_ERROR = 2;
507
508            /**
509             * Set by BroadcastReceiver. Indicates insufficient memory to store
510             * the message.
511             */
512            public static final int RESULT_SMS_OUT_OF_MEMORY = 3;
513
514            /**
515             * Set by BroadcastReceiver. Indicates the message, while
516             * possibly valid, is of a format or encoding that is not
517             * supported.
518             */
519            public static final int RESULT_SMS_UNSUPPORTED = 4;
520
521            /**
522             * Set by BroadcastReceiver. Indicates the duplicated imcoming message.
523             */
524            public static final int RESULT_SMS_DUPLICATED = 5;
525
526            /**
527             * Broadcast Action: A new text based SMS message has been received
528             * by the device. The intent will have the following extra
529             * values:</p>
530             *
531             * <ul>
532             *   <li><em>pdus</em> - An Object[] od byte[]s containing the PDUs
533             *   that make up the message.</li>
534             * </ul>
535             *
536             * <p>The extra values can be extracted using
537             * {@link #getMessagesFromIntent(Intent)}.</p>
538             *
539             * <p>If a BroadcastReceiver encounters an error while processing
540             * this intent it should set the result code appropriately.</p>
541             */
542            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
543            public static final String SMS_RECEIVED_ACTION =
544                    "android.provider.Telephony.SMS_RECEIVED";
545
546            /**
547             * Broadcast Action: A new data based SMS message has been received
548             * by the device. The intent will have the following extra
549             * values:</p>
550             *
551             * <ul>
552             *   <li><em>pdus</em> - An Object[] of byte[]s containing the PDUs
553             *   that make up the message.</li>
554             * </ul>
555             *
556             * <p>The extra values can be extracted using
557             * {@link #getMessagesFromIntent(Intent)}.</p>
558             *
559             * <p>If a BroadcastReceiver encounters an error while processing
560             * this intent it should set the result code appropriately.</p>
561             */
562            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
563            public static final String DATA_SMS_RECEIVED_ACTION =
564                    "android.intent.action.DATA_SMS_RECEIVED";
565
566            /**
567             * Broadcast Action: A new WAP PUSH message has been received by the
568             * device. The intent will have the following extra
569             * values:</p>
570             *
571             * <ul>
572             *   <li><em>transactionId (Integer)</em> - The WAP transaction ID</li>
573             *   <li><em>pduType (Integer)</em> - The WAP PDU type</li>
574             *   <li><em>header (byte[])</em> - The header of the message</li>
575             *   <li><em>data (byte[])</em> - The data payload of the message</li>
576             *   <li><em>contentTypeParameters (HashMap&lt;String,String&gt;)</em>
577             *   - Any parameters associated with the content type
578             *   (decoded from the WSP Content-Type header)</li>
579             * </ul>
580             *
581             * <p>If a BroadcastReceiver encounters an error while processing
582             * this intent it should set the result code appropriately.</p>
583             *
584             * <p>The contentTypeParameters extra value is map of content parameters keyed by
585             * their names.</p>
586             *
587             * <p>If any unassigned well-known parameters are encountered, the key of the map will
588             * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter.  If
589             * a parameter has No-Value the value in the map will be null.</p>
590             */
591            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
592            public static final String WAP_PUSH_RECEIVED_ACTION =
593                    "android.provider.Telephony.WAP_PUSH_RECEIVED";
594
595            /**
596             * Broadcast Action: A new Cell Broadcast message has been received
597             * by the device. The intent will have the following extra
598             * values:</p>
599             *
600             * <ul>
601             *   <li><em>message</em> - An SmsCbMessage object containing the broadcast message
602             *   data. This is not an emergency alert, so ETWS and CMAS data will be null.</li>
603             * </ul>
604             *
605             * <p>The extra values can be extracted using
606             * {@link #getMessagesFromIntent(Intent)}.</p>
607             *
608             * <p>If a BroadcastReceiver encounters an error while processing
609             * this intent it should set the result code appropriately.</p>
610             */
611            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
612            public static final String SMS_CB_RECEIVED_ACTION =
613                    "android.provider.Telephony.SMS_CB_RECEIVED";
614
615            /**
616             * Broadcast Action: A new Emergency Broadcast message has been received
617             * by the device. The intent will have the following extra
618             * values:</p>
619             *
620             * <ul>
621             *   <li><em>message</em> - An SmsCbMessage object containing the broadcast message
622             *   data, including ETWS or CMAS warning notification info if present.</li>
623             * </ul>
624             *
625             * <p>The extra values can be extracted using
626             * {@link #getMessagesFromIntent(Intent)}.</p>
627             *
628             * <p>If a BroadcastReceiver encounters an error while processing
629             * this intent it should set the result code appropriately.</p>
630             */
631            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
632            public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION =
633                    "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
634
635            /**
636             * Broadcast Action: A new CDMA SMS has been received containing Service Category
637             * Program Data (updates the list of enabled broadcast channels). The intent will
638             * have the following extra values:</p>
639             *
640             * <ul>
641             *   <li><em>operations</em> - An array of CdmaSmsCbProgramData objects containing
642             *   the service category operations (add/delete/clear) to perform.</li>
643             * </ul>
644             *
645             * <p>The extra values can be extracted using
646             * {@link #getMessagesFromIntent(Intent)}.</p>
647             *
648             * <p>If a BroadcastReceiver encounters an error while processing
649             * this intent it should set the result code appropriately.</p>
650             */
651            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
652            public static final String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION =
653                    "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED";
654
655            /**
656             * Broadcast Action: The SIM storage for SMS messages is full.  If
657             * space is not freed, messages targeted for the SIM (class 2) may
658             * not be saved.
659             */
660            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
661            public static final String SIM_FULL_ACTION =
662                    "android.provider.Telephony.SIM_FULL";
663
664            /**
665             * Broadcast Action: An incoming SMS has been rejected by the
666             * telephony framework.  This intent is sent in lieu of any
667             * of the RECEIVED_ACTION intents.  The intent will have the
668             * following extra value:</p>
669             *
670             * <ul>
671             *   <li><em>result</em> - An int result code, eg,
672             *   <code>{@link #RESULT_SMS_OUT_OF_MEMORY}</code>,
673             *   indicating the error returned to the network.</li>
674             * </ul>
675
676             */
677            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
678            public static final String SMS_REJECTED_ACTION =
679                "android.provider.Telephony.SMS_REJECTED";
680
681            /**
682             * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
683             * {@link #DATA_SMS_RECEIVED_ACTION} intent.
684             *
685             * @param intent the intent to read from
686             * @return an array of SmsMessages for the PDUs
687             */
688            public static SmsMessage[] getMessagesFromIntent(
689                    Intent intent) {
690                Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
691                String format = intent.getStringExtra("format");
692                byte[][] pduObjs = new byte[messages.length][];
693
694                for (int i = 0; i < messages.length; i++) {
695                    pduObjs[i] = (byte[]) messages[i];
696                }
697                byte[][] pdus = new byte[pduObjs.length][];
698                int pduCount = pdus.length;
699                SmsMessage[] msgs = new SmsMessage[pduCount];
700                for (int i = 0; i < pduCount; i++) {
701                    pdus[i] = pduObjs[i];
702                    msgs[i] = SmsMessage.createFromPdu(pdus[i], format);
703                }
704                return msgs;
705            }
706        }
707    }
708
709    /**
710     * Base columns for tables that contain MMSs.
711     */
712    public interface BaseMmsColumns extends BaseColumns {
713
714        public static final int MESSAGE_BOX_ALL    = 0;
715        public static final int MESSAGE_BOX_INBOX  = 1;
716        public static final int MESSAGE_BOX_SENT   = 2;
717        public static final int MESSAGE_BOX_DRAFTS = 3;
718        public static final int MESSAGE_BOX_OUTBOX = 4;
719
720        /**
721         * The date the message was received.
722         * <P>Type: INTEGER (long)</P>
723         */
724        public static final String DATE = "date";
725
726        /**
727         * The date the message was sent.
728         * <P>Type: INTEGER (long)</P>
729         */
730        public static final String DATE_SENT = "date_sent";
731
732        /**
733         * The box which the message belong to, for example, MESSAGE_BOX_INBOX.
734         * <P>Type: INTEGER</P>
735         */
736        public static final String MESSAGE_BOX = "msg_box";
737
738        /**
739         * Has the message been read.
740         * <P>Type: INTEGER (boolean)</P>
741         */
742        public static final String READ = "read";
743
744        /**
745         * Indicates whether this message has been seen by the user. The "seen" flag will be
746         * used to figure out whether we need to throw up a statusbar notification or not.
747         */
748        public static final String SEEN = "seen";
749
750        /**
751         * Indicates whether this message has only a text part (can also have a subject) and
752         * no picture, slideshow, or sound, etc., parts. The value is a boolean, 1 or 0.
753         */
754        public static final String TEXT_ONLY = "text_only";
755
756        /**
757         * The Message-ID of the message.
758         * <P>Type: TEXT</P>
759         */
760        public static final String MESSAGE_ID = "m_id";
761
762        /**
763         * The subject of the message, if present.
764         * <P>Type: TEXT</P>
765         */
766        public static final String SUBJECT = "sub";
767
768        /**
769         * The character set of the subject, if present.
770         * <P>Type: INTEGER</P>
771         */
772        public static final String SUBJECT_CHARSET = "sub_cs";
773
774        /**
775         * The Content-Type of the message.
776         * <P>Type: TEXT</P>
777         */
778        public static final String CONTENT_TYPE = "ct_t";
779
780        /**
781         * The Content-Location of the message.
782         * <P>Type: TEXT</P>
783         */
784        public static final String CONTENT_LOCATION = "ct_l";
785
786        /**
787         * The address of the sender.
788         * <P>Type: TEXT</P>
789         */
790        public static final String FROM = "from";
791
792        /**
793         * The address of the recipients.
794         * <P>Type: TEXT</P>
795         */
796        public static final String TO = "to";
797
798        /**
799         * The address of the cc. recipients.
800         * <P>Type: TEXT</P>
801         */
802        public static final String CC = "cc";
803
804        /**
805         * The address of the bcc. recipients.
806         * <P>Type: TEXT</P>
807         */
808        public static final String BCC = "bcc";
809
810        /**
811         * The expiry time of the message.
812         * <P>Type: INTEGER</P>
813         */
814        public static final String EXPIRY = "exp";
815
816        /**
817         * The class of the message.
818         * <P>Type: TEXT</P>
819         */
820        public static final String MESSAGE_CLASS = "m_cls";
821
822        /**
823         * The type of the message defined by MMS spec.
824         * <P>Type: INTEGER</P>
825         */
826        public static final String MESSAGE_TYPE = "m_type";
827
828        /**
829         * The version of specification that this message conform.
830         * <P>Type: INTEGER</P>
831         */
832        public static final String MMS_VERSION = "v";
833
834        /**
835         * The size of the message.
836         * <P>Type: INTEGER</P>
837         */
838        public static final String MESSAGE_SIZE = "m_size";
839
840        /**
841         * The priority of the message.
842         * <P>Type: TEXT</P>
843         */
844        public static final String PRIORITY = "pri";
845
846        /**
847         * The read-report of the message.
848         * <P>Type: TEXT</P>
849         */
850        public static final String READ_REPORT = "rr";
851
852        /**
853         * Whether the report is allowed.
854         * <P>Type: TEXT</P>
855         */
856        public static final String REPORT_ALLOWED = "rpt_a";
857
858        /**
859         * The response-status of the message.
860         * <P>Type: INTEGER</P>
861         */
862        public static final String RESPONSE_STATUS = "resp_st";
863
864        /**
865         * The status of the message.
866         * <P>Type: INTEGER</P>
867         */
868        public static final String STATUS = "st";
869
870        /**
871         * The transaction-id of the message.
872         * <P>Type: TEXT</P>
873         */
874        public static final String TRANSACTION_ID = "tr_id";
875
876        /**
877         * The retrieve-status of the message.
878         * <P>Type: INTEGER</P>
879         */
880        public static final String RETRIEVE_STATUS = "retr_st";
881
882        /**
883         * The retrieve-text of the message.
884         * <P>Type: TEXT</P>
885         */
886        public static final String RETRIEVE_TEXT = "retr_txt";
887
888        /**
889         * The character set of the retrieve-text.
890         * <P>Type: TEXT</P>
891         */
892        public static final String RETRIEVE_TEXT_CHARSET = "retr_txt_cs";
893
894        /**
895         * The read-status of the message.
896         * <P>Type: INTEGER</P>
897         */
898        public static final String READ_STATUS = "read_status";
899
900        /**
901         * The content-class of the message.
902         * <P>Type: INTEGER</P>
903         */
904        public static final String CONTENT_CLASS = "ct_cls";
905
906        /**
907         * The delivery-report of the message.
908         * <P>Type: INTEGER</P>
909         */
910        public static final String DELIVERY_REPORT = "d_rpt";
911
912        /**
913         * The delivery-time-token of the message.
914         * <P>Type: INTEGER</P>
915         */
916        public static final String DELIVERY_TIME_TOKEN = "d_tm_tok";
917
918        /**
919         * The delivery-time of the message.
920         * <P>Type: INTEGER</P>
921         */
922        public static final String DELIVERY_TIME = "d_tm";
923
924        /**
925         * The response-text of the message.
926         * <P>Type: TEXT</P>
927         */
928        public static final String RESPONSE_TEXT = "resp_txt";
929
930        /**
931         * The sender-visibility of the message.
932         * <P>Type: TEXT</P>
933         */
934        public static final String SENDER_VISIBILITY = "s_vis";
935
936        /**
937         * The reply-charging of the message.
938         * <P>Type: INTEGER</P>
939         */
940        public static final String REPLY_CHARGING = "r_chg";
941
942        /**
943         * The reply-charging-deadline-token of the message.
944         * <P>Type: INTEGER</P>
945         */
946        public static final String REPLY_CHARGING_DEADLINE_TOKEN = "r_chg_dl_tok";
947
948        /**
949         * The reply-charging-deadline of the message.
950         * <P>Type: INTEGER</P>
951         */
952        public static final String REPLY_CHARGING_DEADLINE = "r_chg_dl";
953
954        /**
955         * The reply-charging-id of the message.
956         * <P>Type: TEXT</P>
957         */
958        public static final String REPLY_CHARGING_ID = "r_chg_id";
959
960        /**
961         * The reply-charging-size of the message.
962         * <P>Type: INTEGER</P>
963         */
964        public static final String REPLY_CHARGING_SIZE = "r_chg_sz";
965
966        /**
967         * The previously-sent-by of the message.
968         * <P>Type: TEXT</P>
969         */
970        public static final String PREVIOUSLY_SENT_BY = "p_s_by";
971
972        /**
973         * The previously-sent-date of the message.
974         * <P>Type: INTEGER</P>
975         */
976        public static final String PREVIOUSLY_SENT_DATE = "p_s_d";
977
978        /**
979         * The store of the message.
980         * <P>Type: TEXT</P>
981         */
982        public static final String STORE = "store";
983
984        /**
985         * The mm-state of the message.
986         * <P>Type: INTEGER</P>
987         */
988        public static final String MM_STATE = "mm_st";
989
990        /**
991         * The mm-flags-token of the message.
992         * <P>Type: INTEGER</P>
993         */
994        public static final String MM_FLAGS_TOKEN = "mm_flg_tok";
995
996        /**
997         * The mm-flags of the message.
998         * <P>Type: TEXT</P>
999         */
1000        public static final String MM_FLAGS = "mm_flg";
1001
1002        /**
1003         * The store-status of the message.
1004         * <P>Type: TEXT</P>
1005         */
1006        public static final String STORE_STATUS = "store_st";
1007
1008        /**
1009         * The store-status-text of the message.
1010         * <P>Type: TEXT</P>
1011         */
1012        public static final String STORE_STATUS_TEXT = "store_st_txt";
1013
1014        /**
1015         * The stored of the message.
1016         * <P>Type: TEXT</P>
1017         */
1018        public static final String STORED = "stored";
1019
1020        /**
1021         * The totals of the message.
1022         * <P>Type: TEXT</P>
1023         */
1024        public static final String TOTALS = "totals";
1025
1026        /**
1027         * The mbox-totals of the message.
1028         * <P>Type: TEXT</P>
1029         */
1030        public static final String MBOX_TOTALS = "mb_t";
1031
1032        /**
1033         * The mbox-totals-token of the message.
1034         * <P>Type: INTEGER</P>
1035         */
1036        public static final String MBOX_TOTALS_TOKEN = "mb_t_tok";
1037
1038        /**
1039         * The quotas of the message.
1040         * <P>Type: TEXT</P>
1041         */
1042        public static final String QUOTAS = "qt";
1043
1044        /**
1045         * The mbox-quotas of the message.
1046         * <P>Type: TEXT</P>
1047         */
1048        public static final String MBOX_QUOTAS = "mb_qt";
1049
1050        /**
1051         * The mbox-quotas-token of the message.
1052         * <P>Type: INTEGER</P>
1053         */
1054        public static final String MBOX_QUOTAS_TOKEN = "mb_qt_tok";
1055
1056        /**
1057         * The message-count of the message.
1058         * <P>Type: INTEGER</P>
1059         */
1060        public static final String MESSAGE_COUNT = "m_cnt";
1061
1062        /**
1063         * The start of the message.
1064         * <P>Type: INTEGER</P>
1065         */
1066        public static final String START = "start";
1067
1068        /**
1069         * The distribution-indicator of the message.
1070         * <P>Type: TEXT</P>
1071         */
1072        public static final String DISTRIBUTION_INDICATOR = "d_ind";
1073
1074        /**
1075         * The element-descriptor of the message.
1076         * <P>Type: TEXT</P>
1077         */
1078        public static final String ELEMENT_DESCRIPTOR = "e_des";
1079
1080        /**
1081         * The limit of the message.
1082         * <P>Type: INTEGER</P>
1083         */
1084        public static final String LIMIT = "limit";
1085
1086        /**
1087         * The recommended-retrieval-mode of the message.
1088         * <P>Type: INTEGER</P>
1089         */
1090        public static final String RECOMMENDED_RETRIEVAL_MODE = "r_r_mod";
1091
1092        /**
1093         * The recommended-retrieval-mode-text of the message.
1094         * <P>Type: TEXT</P>
1095         */
1096        public static final String RECOMMENDED_RETRIEVAL_MODE_TEXT = "r_r_mod_txt";
1097
1098        /**
1099         * The status-text of the message.
1100         * <P>Type: TEXT</P>
1101         */
1102        public static final String STATUS_TEXT = "st_txt";
1103
1104        /**
1105         * The applic-id of the message.
1106         * <P>Type: TEXT</P>
1107         */
1108        public static final String APPLIC_ID = "apl_id";
1109
1110        /**
1111         * The reply-applic-id of the message.
1112         * <P>Type: TEXT</P>
1113         */
1114        public static final String REPLY_APPLIC_ID = "r_apl_id";
1115
1116        /**
1117         * The aux-applic-id of the message.
1118         * <P>Type: TEXT</P>
1119         */
1120        public static final String AUX_APPLIC_ID = "aux_apl_id";
1121
1122        /**
1123         * The drm-content of the message.
1124         * <P>Type: TEXT</P>
1125         */
1126        public static final String DRM_CONTENT = "drm_c";
1127
1128        /**
1129         * The adaptation-allowed of the message.
1130         * <P>Type: TEXT</P>
1131         */
1132        public static final String ADAPTATION_ALLOWED = "adp_a";
1133
1134        /**
1135         * The replace-id of the message.
1136         * <P>Type: TEXT</P>
1137         */
1138        public static final String REPLACE_ID = "repl_id";
1139
1140        /**
1141         * The cancel-id of the message.
1142         * <P>Type: TEXT</P>
1143         */
1144        public static final String CANCEL_ID = "cl_id";
1145
1146        /**
1147         * The cancel-status of the message.
1148         * <P>Type: INTEGER</P>
1149         */
1150        public static final String CANCEL_STATUS = "cl_st";
1151
1152        /**
1153         * The thread ID of the message
1154         * <P>Type: INTEGER</P>
1155         */
1156        public static final String THREAD_ID = "thread_id";
1157
1158        /**
1159         * Has the message been locked?
1160         * <P>Type: INTEGER (boolean)</P>
1161         */
1162        public static final String LOCKED = "locked";
1163
1164        /**
1165         * Meta data used externally.
1166         * <P>Type: TEXT</P>
1167         */
1168        public static final String META_DATA = "meta_data";
1169    }
1170
1171    /**
1172     * Columns for the "canonical_addresses" table used by MMS and
1173     * SMS."
1174     */
1175    public interface CanonicalAddressesColumns extends BaseColumns {
1176        /**
1177         * An address used in MMS or SMS.  Email addresses are
1178         * converted to lower case and are compared by string
1179         * equality.  Other addresses are compared using
1180         * PHONE_NUMBERS_EQUAL.
1181         * <P>Type: TEXT</P>
1182         */
1183        public static final String ADDRESS = "address";
1184    }
1185
1186    /**
1187     * Columns for the "threads" table used by MMS and SMS.
1188     */
1189    public interface ThreadsColumns extends BaseColumns {
1190        /**
1191         * The date at which the thread was created.
1192         *
1193         * <P>Type: INTEGER (long)</P>
1194         */
1195        public static final String DATE = "date";
1196
1197        /**
1198         * A string encoding of the recipient IDs of the recipients of
1199         * the message, in numerical order and separated by spaces.
1200         * <P>Type: TEXT</P>
1201         */
1202        public static final String RECIPIENT_IDS = "recipient_ids";
1203
1204        /**
1205         * The message count of the thread.
1206         * <P>Type: INTEGER</P>
1207         */
1208        public static final String MESSAGE_COUNT = "message_count";
1209        /**
1210         * Indicates whether all messages of the thread have been read.
1211         * <P>Type: INTEGER</P>
1212         */
1213        public static final String READ = "read";
1214
1215        /**
1216         * The snippet of the latest message in the thread.
1217         * <P>Type: TEXT</P>
1218         */
1219        public static final String SNIPPET = "snippet";
1220        /**
1221         * The charset of the snippet.
1222         * <P>Type: INTEGER</P>
1223         */
1224        public static final String SNIPPET_CHARSET = "snippet_cs";
1225        /**
1226         * Type of the thread, either Threads.COMMON_THREAD or
1227         * Threads.BROADCAST_THREAD.
1228         * <P>Type: INTEGER</P>
1229         */
1230        public static final String TYPE = "type";
1231        /**
1232         * Indicates whether there is a transmission error in the thread.
1233         * <P>Type: INTEGER</P>
1234         */
1235        public static final String ERROR = "error";
1236        /**
1237         * Indicates whether this thread contains any attachments.
1238         * <P>Type: INTEGER</P>
1239         */
1240        public static final String HAS_ATTACHMENT = "has_attachment";
1241    }
1242
1243    /**
1244     * Helper functions for the "threads" table used by MMS and SMS.
1245     */
1246    public static final class Threads implements ThreadsColumns {
1247        private static final String[] ID_PROJECTION = { BaseColumns._ID };
1248        private static final Uri THREAD_ID_CONTENT_URI = Uri.parse(
1249                "content://mms-sms/threadID");
1250        public static final Uri CONTENT_URI = Uri.withAppendedPath(
1251                MmsSms.CONTENT_URI, "conversations");
1252        public static final Uri OBSOLETE_THREADS_URI = Uri.withAppendedPath(
1253                CONTENT_URI, "obsolete");
1254
1255        public static final int COMMON_THREAD    = 0;
1256        public static final int BROADCAST_THREAD = 1;
1257
1258        // No one should construct an instance of this class.
1259        private Threads() {
1260        }
1261
1262        /**
1263         * This is a single-recipient version of
1264         * getOrCreateThreadId.  It's convenient for use with SMS
1265         * messages.
1266         */
1267        public static long getOrCreateThreadId(Context context, String recipient) {
1268            Set<String> recipients = new HashSet<String>();
1269
1270            recipients.add(recipient);
1271            return getOrCreateThreadId(context, recipients);
1272        }
1273
1274        /**
1275         * Given the recipients list and subject of an unsaved message,
1276         * return its thread ID.  If the message starts a new thread,
1277         * allocate a new thread ID.  Otherwise, use the appropriate
1278         * existing thread ID.
1279         *
1280         * Find the thread ID of the same set of recipients (in
1281         * any order, without any additions). If one
1282         * is found, return it.  Otherwise, return a unique thread ID.
1283         */
1284        public static long getOrCreateThreadId(
1285                Context context, Set<String> recipients) {
1286            Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon();
1287
1288            for (String recipient : recipients) {
1289                if (Mms.isEmailAddress(recipient)) {
1290                    recipient = Mms.extractAddrSpec(recipient);
1291                }
1292
1293                uriBuilder.appendQueryParameter("recipient", recipient);
1294            }
1295
1296            Uri uri = uriBuilder.build();
1297            //if (DEBUG) Rlog.v(TAG, "getOrCreateThreadId uri: " + uri);
1298
1299            Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
1300                    uri, ID_PROJECTION, null, null, null);
1301            if (cursor != null) {
1302                try {
1303                    if (cursor.moveToFirst()) {
1304                        return cursor.getLong(0);
1305                    } else {
1306                        Rlog.e(TAG, "getOrCreateThreadId returned no rows!");
1307                    }
1308                } finally {
1309                    cursor.close();
1310                }
1311            }
1312
1313            Rlog.e(TAG, "getOrCreateThreadId failed with uri " + uri.toString());
1314            throw new IllegalArgumentException("Unable to find or allocate a thread ID.");
1315        }
1316    }
1317
1318    /**
1319     * Contains all MMS messages.
1320     */
1321    public static final class Mms implements BaseMmsColumns {
1322        /**
1323         * The content:// style URL for this table
1324         */
1325        public static final Uri CONTENT_URI = Uri.parse("content://mms");
1326
1327        public static final Uri REPORT_REQUEST_URI = Uri.withAppendedPath(
1328                                            CONTENT_URI, "report-request");
1329
1330        public static final Uri REPORT_STATUS_URI = Uri.withAppendedPath(
1331                                            CONTENT_URI, "report-status");
1332
1333        /**
1334         * The default sort order for this table
1335         */
1336        public static final String DEFAULT_SORT_ORDER = "date DESC";
1337
1338        /**
1339         * mailbox         =       name-addr
1340         * name-addr       =       [display-name] angle-addr
1341         * angle-addr      =       [CFWS] "<" addr-spec ">" [CFWS]
1342         */
1343        public static final Pattern NAME_ADDR_EMAIL_PATTERN =
1344                Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*");
1345
1346        /**
1347         * quoted-string   =       [CFWS]
1348         *                         DQUOTE *([FWS] qcontent) [FWS] DQUOTE
1349         *                         [CFWS]
1350         */
1351        public static final Pattern QUOTED_STRING_PATTERN =
1352                Pattern.compile("\\s*\"([^\"]*)\"\\s*");
1353
1354        public static final Cursor query(
1355                ContentResolver cr, String[] projection) {
1356            return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
1357        }
1358
1359        public static final Cursor query(
1360                ContentResolver cr, String[] projection,
1361                String where, String orderBy) {
1362            return cr.query(CONTENT_URI, projection,
1363                    where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
1364        }
1365
1366        public static final String getMessageBoxName(int msgBox) {
1367            switch (msgBox) {
1368                case MESSAGE_BOX_ALL:
1369                    return "all";
1370                case MESSAGE_BOX_INBOX:
1371                    return "inbox";
1372                case MESSAGE_BOX_SENT:
1373                    return "sent";
1374                case MESSAGE_BOX_DRAFTS:
1375                    return "drafts";
1376                case MESSAGE_BOX_OUTBOX:
1377                    return "outbox";
1378                default:
1379                    throw new IllegalArgumentException("Invalid message box: " + msgBox);
1380            }
1381        }
1382
1383        public static String extractAddrSpec(String address) {
1384            Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address);
1385
1386            if (match.matches()) {
1387                return match.group(2);
1388            }
1389            return address;
1390        }
1391
1392        /**
1393         * Returns true if the address is an email address
1394         *
1395         * @param address the input address to be tested
1396         * @return true if address is an email address
1397         */
1398        public static boolean isEmailAddress(String address) {
1399            if (TextUtils.isEmpty(address)) {
1400                return false;
1401            }
1402
1403            String s = extractAddrSpec(address);
1404            Matcher match = Patterns.EMAIL_ADDRESS.matcher(s);
1405            return match.matches();
1406        }
1407
1408        /**
1409         * Returns true if the number is a Phone number
1410         *
1411         * @param number the input number to be tested
1412         * @return true if number is a Phone number
1413         */
1414        public static boolean isPhoneNumber(String number) {
1415            if (TextUtils.isEmpty(number)) {
1416                return false;
1417            }
1418
1419            Matcher match = Patterns.PHONE.matcher(number);
1420            return match.matches();
1421        }
1422
1423        /**
1424         * Contains all MMS messages in the MMS app's inbox.
1425         */
1426        public static final class Inbox implements BaseMmsColumns {
1427            /**
1428             * The content:// style URL for this table
1429             */
1430            public static final Uri
1431                    CONTENT_URI = Uri.parse("content://mms/inbox");
1432
1433            /**
1434             * The default sort order for this table
1435             */
1436            public static final String DEFAULT_SORT_ORDER = "date DESC";
1437        }
1438
1439        /**
1440         * Contains all MMS messages in the MMS app's sent box.
1441         */
1442        public static final class Sent implements BaseMmsColumns {
1443            /**
1444             * The content:// style URL for this table
1445             */
1446            public static final Uri
1447                    CONTENT_URI = Uri.parse("content://mms/sent");
1448
1449            /**
1450             * The default sort order for this table
1451             */
1452            public static final String DEFAULT_SORT_ORDER = "date DESC";
1453        }
1454
1455        /**
1456         * Contains all MMS messages in the MMS app's drafts box.
1457         */
1458        public static final class Draft implements BaseMmsColumns {
1459            /**
1460             * The content:// style URL for this table
1461             */
1462            public static final Uri
1463                    CONTENT_URI = Uri.parse("content://mms/drafts");
1464
1465            /**
1466             * The default sort order for this table
1467             */
1468            public static final String DEFAULT_SORT_ORDER = "date DESC";
1469        }
1470
1471        /**
1472         * Contains all MMS messages in the MMS app's outbox.
1473         */
1474        public static final class Outbox implements BaseMmsColumns {
1475            /**
1476             * The content:// style URL for this table
1477             */
1478            public static final Uri
1479                    CONTENT_URI = Uri.parse("content://mms/outbox");
1480
1481            /**
1482             * The default sort order for this table
1483             */
1484            public static final String DEFAULT_SORT_ORDER = "date DESC";
1485        }
1486
1487        public static final class Addr implements BaseColumns {
1488            /**
1489             * The ID of MM which this address entry belongs to.
1490             */
1491            public static final String MSG_ID = "msg_id";
1492
1493            /**
1494             * The ID of contact entry in Phone Book.
1495             */
1496            public static final String CONTACT_ID = "contact_id";
1497
1498            /**
1499             * The address text.
1500             */
1501            public static final String ADDRESS = "address";
1502
1503            /**
1504             * Type of address, must be one of PduHeaders.BCC,
1505             * PduHeaders.CC, PduHeaders.FROM, PduHeaders.TO.
1506             */
1507            public static final String TYPE = "type";
1508
1509            /**
1510             * Character set of this entry.
1511             */
1512            public static final String CHARSET = "charset";
1513        }
1514
1515        public static final class Part implements BaseColumns {
1516            /**
1517             * The identifier of the message which this part belongs to.
1518             * <P>Type: INTEGER</P>
1519             */
1520            public static final String MSG_ID = "mid";
1521
1522            /**
1523             * The order of the part.
1524             * <P>Type: INTEGER</P>
1525             */
1526            public static final String SEQ = "seq";
1527
1528            /**
1529             * The content type of the part.
1530             * <P>Type: TEXT</P>
1531             */
1532            public static final String CONTENT_TYPE = "ct";
1533
1534            /**
1535             * The name of the part.
1536             * <P>Type: TEXT</P>
1537             */
1538            public static final String NAME = "name";
1539
1540            /**
1541             * The charset of the part.
1542             * <P>Type: TEXT</P>
1543             */
1544            public static final String CHARSET = "chset";
1545
1546            /**
1547             * The file name of the part.
1548             * <P>Type: TEXT</P>
1549             */
1550            public static final String FILENAME = "fn";
1551
1552            /**
1553             * The content disposition of the part.
1554             * <P>Type: TEXT</P>
1555             */
1556            public static final String CONTENT_DISPOSITION = "cd";
1557
1558            /**
1559             * The content ID of the part.
1560             * <P>Type: INTEGER</P>
1561             */
1562            public static final String CONTENT_ID = "cid";
1563
1564            /**
1565             * The content location of the part.
1566             * <P>Type: INTEGER</P>
1567             */
1568            public static final String CONTENT_LOCATION = "cl";
1569
1570            /**
1571             * The start of content-type of the message.
1572             * <P>Type: INTEGER</P>
1573             */
1574            public static final String CT_START = "ctt_s";
1575
1576            /**
1577             * The type of content-type of the message.
1578             * <P>Type: TEXT</P>
1579             */
1580            public static final String CT_TYPE = "ctt_t";
1581
1582            /**
1583             * The location(on filesystem) of the binary data of the part.
1584             * <P>Type: INTEGER</P>
1585             */
1586            public static final String _DATA = "_data";
1587
1588            public static final String TEXT = "text";
1589
1590        }
1591
1592        public static final class Rate {
1593            public static final Uri CONTENT_URI = Uri.withAppendedPath(
1594                    Mms.CONTENT_URI, "rate");
1595            /**
1596             * When a message was successfully sent.
1597             * <P>Type: INTEGER</P>
1598             */
1599            public static final String SENT_TIME = "sent_time";
1600        }
1601
1602        public static final class Intents {
1603            private Intents() {
1604                // Non-instantiatable.
1605            }
1606
1607            /**
1608             * The extra field to store the contents of the Intent,
1609             * which should be an array of Uri.
1610             */
1611            public static final String EXTRA_CONTENTS = "contents";
1612            /**
1613             * The extra field to store the type of the contents,
1614             * which should be an array of String.
1615             */
1616            public static final String EXTRA_TYPES    = "types";
1617            /**
1618             * The extra field to store the 'Cc' addresses.
1619             */
1620            public static final String EXTRA_CC       = "cc";
1621            /**
1622             * The extra field to store the 'Bcc' addresses;
1623             */
1624            public static final String EXTRA_BCC      = "bcc";
1625            /**
1626             * The extra field to store the 'Subject'.
1627             */
1628            public static final String EXTRA_SUBJECT  = "subject";
1629            /**
1630             * Indicates that the contents of specified URIs were changed.
1631             * The application which is showing or caching these contents
1632             * should be updated.
1633             */
1634            public static final String
1635            CONTENT_CHANGED_ACTION = "android.intent.action.CONTENT_CHANGED";
1636            /**
1637             * An extra field which stores the URI of deleted contents.
1638             */
1639            public static final String DELETED_CONTENTS = "deleted_contents";
1640        }
1641    }
1642
1643    /**
1644     * Contains all MMS and SMS messages.
1645     */
1646    public static final class MmsSms implements BaseColumns {
1647        /**
1648         * The column to distinguish SMS &amp; MMS messages in query results.
1649         */
1650        public static final String TYPE_DISCRIMINATOR_COLUMN =
1651                "transport_type";
1652
1653        public static final Uri CONTENT_URI = Uri.parse("content://mms-sms/");
1654
1655        public static final Uri CONTENT_CONVERSATIONS_URI = Uri.parse(
1656                "content://mms-sms/conversations");
1657
1658        public static final Uri CONTENT_FILTER_BYPHONE_URI = Uri.parse(
1659                "content://mms-sms/messages/byphone");
1660
1661        public static final Uri CONTENT_UNDELIVERED_URI = Uri.parse(
1662                "content://mms-sms/undelivered");
1663
1664        public static final Uri CONTENT_DRAFT_URI = Uri.parse(
1665                "content://mms-sms/draft");
1666
1667        public static final Uri CONTENT_LOCKED_URI = Uri.parse(
1668                "content://mms-sms/locked");
1669
1670        /***
1671         * Pass in a query parameter called "pattern" which is the text
1672         * to search for.
1673         * The sort order is fixed to be thread_id ASC,date DESC.
1674         */
1675        public static final Uri SEARCH_URI = Uri.parse(
1676                "content://mms-sms/search");
1677
1678        // Constants for message protocol types.
1679        public static final int SMS_PROTO = 0;
1680        public static final int MMS_PROTO = 1;
1681
1682        // Constants for error types of pending messages.
1683        public static final int NO_ERROR                      = 0;
1684        public static final int ERR_TYPE_GENERIC              = 1;
1685        public static final int ERR_TYPE_SMS_PROTO_TRANSIENT  = 2;
1686        public static final int ERR_TYPE_MMS_PROTO_TRANSIENT  = 3;
1687        public static final int ERR_TYPE_TRANSPORT_FAILURE    = 4;
1688        public static final int ERR_TYPE_GENERIC_PERMANENT    = 10;
1689        public static final int ERR_TYPE_SMS_PROTO_PERMANENT  = 11;
1690        public static final int ERR_TYPE_MMS_PROTO_PERMANENT  = 12;
1691
1692        public static final class PendingMessages implements BaseColumns {
1693            public static final Uri CONTENT_URI = Uri.withAppendedPath(
1694                    MmsSms.CONTENT_URI, "pending");
1695            /**
1696             * The type of transport protocol(MMS or SMS).
1697             * <P>Type: INTEGER</P>
1698             */
1699            public static final String PROTO_TYPE = "proto_type";
1700            /**
1701             * The ID of the message to be sent or downloaded.
1702             * <P>Type: INTEGER</P>
1703             */
1704            public static final String MSG_ID = "msg_id";
1705            /**
1706             * The type of the message to be sent or downloaded.
1707             * This field is only valid for MM. For SM, its value is always
1708             * set to 0.
1709             */
1710            public static final String MSG_TYPE = "msg_type";
1711            /**
1712             * The type of the error code.
1713             * <P>Type: INTEGER</P>
1714             */
1715            public static final String ERROR_TYPE = "err_type";
1716            /**
1717             * The error code of sending/retrieving process.
1718             * <P>Type:  INTEGER</P>
1719             */
1720            public static final String ERROR_CODE = "err_code";
1721            /**
1722             * How many times we tried to send or download the message.
1723             * <P>Type:  INTEGER</P>
1724             */
1725            public static final String RETRY_INDEX = "retry_index";
1726            /**
1727             * The time to do next retry.
1728             */
1729            public static final String DUE_TIME = "due_time";
1730            /**
1731             * The time we last tried to send or download the message.
1732             */
1733            public static final String LAST_TRY = "last_try";
1734        }
1735
1736        public static final class WordsTable {
1737            public static final String ID = "_id";
1738            public static final String SOURCE_ROW_ID = "source_id";
1739            public static final String TABLE_ID = "table_to_use";
1740            public static final String INDEXED_TEXT = "index_text";
1741        }
1742    }
1743
1744    public static final class Carriers implements BaseColumns {
1745        /**
1746         * The content:// style URL for this table
1747         */
1748        public static final Uri CONTENT_URI =
1749            Uri.parse("content://telephony/carriers");
1750
1751        /**
1752         * The default sort order for this table
1753         */
1754        public static final String DEFAULT_SORT_ORDER = "name ASC";
1755
1756        public static final String NAME = "name";
1757
1758        public static final String APN = "apn";
1759
1760        public static final String PROXY = "proxy";
1761
1762        public static final String PORT = "port";
1763
1764        public static final String MMSPROXY = "mmsproxy";
1765
1766        public static final String MMSPORT = "mmsport";
1767
1768        public static final String SERVER = "server";
1769
1770        public static final String USER = "user";
1771
1772        public static final String PASSWORD = "password";
1773
1774        public static final String MMSC = "mmsc";
1775
1776        public static final String MCC = "mcc";
1777
1778        public static final String MNC = "mnc";
1779
1780        public static final String NUMERIC = "numeric";
1781
1782        public static final String AUTH_TYPE = "authtype";
1783
1784        public static final String TYPE = "type";
1785
1786        public static final String INACTIVE_TIMER = "inactivetimer";
1787
1788        // Only if enabled try Data Connection.
1789        public static final String ENABLED = "enabled";
1790
1791        // Rules apply based on class.
1792        public static final String CLASS = "class";
1793
1794        /**
1795         * The protocol to be used to connect to this APN.
1796         *
1797         * One of the PDP_type values in TS 27.007 section 10.1.1.
1798         * For example, "IP", "IPV6", "IPV4V6", or "PPP".
1799         */
1800        public static final String PROTOCOL = "protocol";
1801
1802        /**
1803          * The protocol to be used to connect to this APN when roaming.
1804          *
1805          * The syntax is the same as protocol.
1806          */
1807        public static final String ROAMING_PROTOCOL = "roaming_protocol";
1808
1809        public static final String CURRENT = "current";
1810
1811        /**
1812          * Current status of APN
1813          * true : enabled APN, false : disabled APN.
1814          */
1815        public static final String CARRIER_ENABLED = "carrier_enabled";
1816
1817        /**
1818          * Radio Access Technology info
1819          * To check what values can hold, refer to ServiceState.java.
1820          * This should be spread to other technologies,
1821          * but currently only used for LTE(14) and EHRPD(13).
1822          */
1823        public static final String BEARER = "bearer";
1824
1825        /**
1826          * MVNO type
1827          * spn(Service Provider Name), imsi, gid(Group Identifier Level 1)
1828          */
1829        public static final String MVNO_TYPE = "mvno_type";
1830
1831        /**
1832          * MVNO data
1833          * Use the following examples.
1834          * spn: A MOBILE, BEN NL, ...
1835          * imsi: 302720x94, 2060188, ...
1836          * gid: 4E, 33, ...
1837          */
1838        public static final String MVNO_MATCH_DATA = "mvno_match_data";
1839    }
1840
1841    /**
1842     * Contains received SMS cell broadcast messages.
1843     */
1844    public static final class CellBroadcasts implements BaseColumns {
1845
1846        /** Not instantiable. */
1847        private CellBroadcasts() {}
1848
1849        /**
1850         * The content:// style URL for this table
1851         */
1852        public static final Uri CONTENT_URI =
1853            Uri.parse("content://cellbroadcasts");
1854
1855        /**
1856         * Message geographical scope.
1857         * <P>Type: INTEGER</P>
1858         */
1859        public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
1860
1861        /**
1862         * Message serial number.
1863         * <P>Type: INTEGER</P>
1864         */
1865        public static final String SERIAL_NUMBER = "serial_number";
1866
1867        /**
1868         * PLMN of broadcast sender. (SERIAL_NUMBER + PLMN + LAC + CID) uniquely identifies a
1869         * broadcast for duplicate detection purposes.
1870         * <P>Type: TEXT</P>
1871         */
1872        public static final String PLMN = "plmn";
1873
1874        /**
1875         * Location Area (GSM) or Service Area (UMTS) of broadcast sender. Unused for CDMA.
1876         * Only included if Geographical Scope of message is not PLMN wide (01).
1877         * <P>Type: INTEGER</P>
1878         */
1879        public static final String LAC = "lac";
1880
1881        /**
1882         * Cell ID of message sender (GSM/UMTS). Unused for CDMA. Only included when the
1883         * Geographical Scope of message is cell wide (00 or 11).
1884         * <P>Type: INTEGER</P>
1885         */
1886        public static final String CID = "cid";
1887
1888        /**
1889         * Message code (OBSOLETE: merged into SERIAL_NUMBER).
1890         * <P>Type: INTEGER</P>
1891         */
1892        public static final String V1_MESSAGE_CODE = "message_code";
1893
1894        /**
1895         * Message identifier (OBSOLETE: renamed to SERVICE_CATEGORY).
1896         * <P>Type: INTEGER</P>
1897         */
1898        public static final String V1_MESSAGE_IDENTIFIER = "message_id";
1899
1900        /**
1901         * Service category (GSM/UMTS message identifier, CDMA service category).
1902         * <P>Type: INTEGER</P>
1903         */
1904        public static final String SERVICE_CATEGORY = "service_category";
1905
1906        /**
1907         * Message language code.
1908         * <P>Type: TEXT</P>
1909         */
1910        public static final String LANGUAGE_CODE = "language";
1911
1912        /**
1913         * Message body.
1914         * <P>Type: TEXT</P>
1915         */
1916        public static final String MESSAGE_BODY = "body";
1917
1918        /**
1919         * Message delivery time.
1920         * <P>Type: INTEGER (long)</P>
1921         */
1922        public static final String DELIVERY_TIME = "date";
1923
1924        /**
1925         * Has the message been viewed?
1926         * <P>Type: INTEGER (boolean)</P>
1927         */
1928        public static final String MESSAGE_READ = "read";
1929
1930        /**
1931         * Message format (3GPP or 3GPP2).
1932         * <P>Type: INTEGER</P>
1933         */
1934        public static final String MESSAGE_FORMAT = "format";
1935
1936        /**
1937         * Message priority (including emergency).
1938         * <P>Type: INTEGER</P>
1939         */
1940        public static final String MESSAGE_PRIORITY = "priority";
1941
1942        /**
1943         * ETWS warning type (ETWS alerts only).
1944         * <P>Type: INTEGER</P>
1945         */
1946        public static final String ETWS_WARNING_TYPE = "etws_warning_type";
1947
1948        /**
1949         * CMAS message class (CMAS alerts only).
1950         * <P>Type: INTEGER</P>
1951         */
1952        public static final String CMAS_MESSAGE_CLASS = "cmas_message_class";
1953
1954        /**
1955         * CMAS category (CMAS alerts only).
1956         * <P>Type: INTEGER</P>
1957         */
1958        public static final String CMAS_CATEGORY = "cmas_category";
1959
1960        /**
1961         * CMAS response type (CMAS alerts only).
1962         * <P>Type: INTEGER</P>
1963         */
1964        public static final String CMAS_RESPONSE_TYPE = "cmas_response_type";
1965
1966        /**
1967         * CMAS severity (CMAS alerts only).
1968         * <P>Type: INTEGER</P>
1969         */
1970        public static final String CMAS_SEVERITY = "cmas_severity";
1971
1972        /**
1973         * CMAS urgency (CMAS alerts only).
1974         * <P>Type: INTEGER</P>
1975         */
1976        public static final String CMAS_URGENCY = "cmas_urgency";
1977
1978        /**
1979         * CMAS certainty (CMAS alerts only).
1980         * <P>Type: INTEGER</P>
1981         */
1982        public static final String CMAS_CERTAINTY = "cmas_certainty";
1983
1984        /**
1985         * The default sort order for this table
1986         */
1987        public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";
1988
1989        /**
1990         * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
1991         */
1992        public static final String[] QUERY_COLUMNS = {
1993                _ID,
1994                GEOGRAPHICAL_SCOPE,
1995                PLMN,
1996                LAC,
1997                CID,
1998                SERIAL_NUMBER,
1999                SERVICE_CATEGORY,
2000                LANGUAGE_CODE,
2001                MESSAGE_BODY,
2002                DELIVERY_TIME,
2003                MESSAGE_READ,
2004                MESSAGE_FORMAT,
2005                MESSAGE_PRIORITY,
2006                ETWS_WARNING_TYPE,
2007                CMAS_MESSAGE_CLASS,
2008                CMAS_CATEGORY,
2009                CMAS_RESPONSE_TYPE,
2010                CMAS_SEVERITY,
2011                CMAS_URGENCY,
2012                CMAS_CERTAINTY
2013        };
2014    }
2015}
2016