Telephony.java revision b9b75edb2d5042f95b008fe497db2707c18d0ece
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.annotation.TestApi;
22import android.app.job.JobService;
23import android.content.ComponentName;
24import android.content.ContentResolver;
25import android.content.ContentValues;
26import android.content.Context;
27import android.content.Intent;
28import android.database.Cursor;
29import android.database.ContentObserver;
30import android.database.sqlite.SqliteWrapper;
31import android.net.Uri;
32import android.telephony.Rlog;
33import android.telephony.ServiceState;
34import android.telephony.SmsMessage;
35import android.telephony.SubscriptionManager;
36import android.text.TextUtils;
37import android.util.Patterns;
38
39import com.android.internal.telephony.PhoneConstants;
40import com.android.internal.telephony.SmsApplication;
41
42
43import java.util.HashSet;
44import java.util.Set;
45import java.util.regex.Matcher;
46import java.util.regex.Pattern;
47
48/**
49 * The Telephony provider contains data related to phone operation, specifically SMS and MMS
50 * messages, access to the APN list, including the MMSC to use, and the service state.
51 *
52 * <p class="note"><strong>Note:</strong> These APIs are not available on all Android-powered
53 * devices. If your app depends on telephony features such as for managing SMS messages, include
54 * a <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}
55 * </a> element in your manifest that declares the {@code "android.hardware.telephony"} hardware
56 * feature. Alternatively, you can check for telephony availability at runtime using either
57 * {@link android.content.pm.PackageManager#hasSystemFeature
58 * hasSystemFeature(PackageManager.FEATURE_TELEPHONY)} or {@link
59 * android.telephony.TelephonyManager#getPhoneType}.</p>
60 *
61 * <h3>Creating an SMS app</h3>
62 *
63 * <p>Only the default SMS app (selected by the user in system settings) is able to write to the
64 * SMS Provider (the tables defined within the {@code Telephony} class) and only the default SMS
65 * app receives the {@link android.provider.Telephony.Sms.Intents#SMS_DELIVER_ACTION} broadcast
66 * when the user receives an SMS or the {@link
67 * android.provider.Telephony.Sms.Intents#WAP_PUSH_DELIVER_ACTION} broadcast when the user
68 * receives an MMS.</p>
69 *
70 * <p>Any app that wants to behave as the user's default SMS app must handle the following intents:
71 * <ul>
72 * <li>In a broadcast receiver, include an intent filter for {@link Sms.Intents#SMS_DELIVER_ACTION}
73 * (<code>"android.provider.Telephony.SMS_DELIVER"</code>). The broadcast receiver must also
74 * require the {@link android.Manifest.permission#BROADCAST_SMS} permission.
75 * <p>This allows your app to directly receive incoming SMS messages.</p></li>
76 * <li>In a broadcast receiver, include an intent filter for {@link
77 * Sms.Intents#WAP_PUSH_DELIVER_ACTION}} ({@code "android.provider.Telephony.WAP_PUSH_DELIVER"})
78 * with the MIME type <code>"application/vnd.wap.mms-message"</code>.
79 * The broadcast receiver must also require the {@link
80 * android.Manifest.permission#BROADCAST_WAP_PUSH} permission.
81 * <p>This allows your app to directly receive incoming MMS messages.</p></li>
82 * <li>In your activity that delivers new messages, include an intent filter for
83 * {@link android.content.Intent#ACTION_SENDTO} (<code>"android.intent.action.SENDTO"
84 * </code>) with schemas, <code>sms:</code>, <code>smsto:</code>, <code>mms:</code>, and
85 * <code>mmsto:</code>.
86 * <p>This allows your app to receive intents from other apps that want to deliver a
87 * message.</p></li>
88 * <li>In a service, include an intent filter for {@link
89 * android.telephony.TelephonyManager#ACTION_RESPOND_VIA_MESSAGE}
90 * (<code>"android.intent.action.RESPOND_VIA_MESSAGE"</code>) with schemas,
91 * <code>sms:</code>, <code>smsto:</code>, <code>mms:</code>, and <code>mmsto:</code>.
92 * This service must also require the {@link
93 * android.Manifest.permission#SEND_RESPOND_VIA_MESSAGE} permission.
94 * <p>This allows users to respond to incoming phone calls with an immediate text message
95 * using your app.</p></li>
96 * </ul>
97 *
98 * <p>Other apps that are not selected as the default SMS app can only <em>read</em> the SMS
99 * Provider, but may also be notified when a new SMS arrives by listening for the {@link
100 * Sms.Intents#SMS_RECEIVED_ACTION}
101 * broadcast, which is a non-abortable broadcast that may be delivered to multiple apps. This
102 * broadcast is intended for apps that&mdash;while not selected as the default SMS app&mdash;need to
103 * read special incoming messages such as to perform phone number verification.</p>
104 *
105 * <p>For more information about building SMS apps, read the blog post, <a
106 * href="http://android-developers.blogspot.com/2013/10/getting-your-sms-apps-ready-for-kitkat.html"
107 * >Getting Your SMS Apps Ready for KitKat</a>.</p>
108 *
109 */
110public final class Telephony {
111    private static final String TAG = "Telephony";
112
113    /**
114     * Not instantiable.
115     * @hide
116     */
117    private Telephony() {
118    }
119
120    /**
121     * Base columns for tables that contain text-based SMSs.
122     */
123    public interface TextBasedSmsColumns {
124
125        /** Message type: all messages. */
126        public static final int MESSAGE_TYPE_ALL    = 0;
127
128        /** Message type: inbox. */
129        public static final int MESSAGE_TYPE_INBOX  = 1;
130
131        /** Message type: sent messages. */
132        public static final int MESSAGE_TYPE_SENT   = 2;
133
134        /** Message type: drafts. */
135        public static final int MESSAGE_TYPE_DRAFT  = 3;
136
137        /** Message type: outbox. */
138        public static final int MESSAGE_TYPE_OUTBOX = 4;
139
140        /** Message type: failed outgoing message. */
141        public static final int MESSAGE_TYPE_FAILED = 5;
142
143        /** Message type: queued to send later. */
144        public static final int MESSAGE_TYPE_QUEUED = 6;
145
146        /**
147         * The type of message.
148         * <P>Type: INTEGER</P>
149         */
150        public static final String TYPE = "type";
151
152        /**
153         * The thread ID of the message.
154         * <P>Type: INTEGER</P>
155         */
156        public static final String THREAD_ID = "thread_id";
157
158        /**
159         * The address of the other party.
160         * <P>Type: TEXT</P>
161         */
162        public static final String ADDRESS = "address";
163
164        /**
165         * The date the message was received.
166         * <P>Type: INTEGER (long)</P>
167         */
168        public static final String DATE = "date";
169
170        /**
171         * The date the message was sent.
172         * <P>Type: INTEGER (long)</P>
173         */
174        public static final String DATE_SENT = "date_sent";
175
176        /**
177         * Has the message been read?
178         * <P>Type: INTEGER (boolean)</P>
179         */
180        public static final String READ = "read";
181
182        /**
183         * Has the message been seen by the user? The "seen" flag determines
184         * whether we need to show a notification.
185         * <P>Type: INTEGER (boolean)</P>
186         */
187        public static final String SEEN = "seen";
188
189        /**
190         * {@code TP-Status} value for the message, or -1 if no status has been received.
191         * <P>Type: INTEGER</P>
192         */
193        public static final String STATUS = "status";
194
195        /** TP-Status: no status received. */
196        public static final int STATUS_NONE = -1;
197        /** TP-Status: complete. */
198        public static final int STATUS_COMPLETE = 0;
199        /** TP-Status: pending. */
200        public static final int STATUS_PENDING = 32;
201        /** TP-Status: failed. */
202        public static final int STATUS_FAILED = 64;
203
204        /**
205         * The subject of the message, if present.
206         * <P>Type: TEXT</P>
207         */
208        public static final String SUBJECT = "subject";
209
210        /**
211         * The body of the message.
212         * <P>Type: TEXT</P>
213         */
214        public static final String BODY = "body";
215
216        /**
217         * The ID of the sender of the conversation, if present.
218         * <P>Type: INTEGER (reference to item in {@code content://contacts/people})</P>
219         */
220        public static final String PERSON = "person";
221
222        /**
223         * The protocol identifier code.
224         * <P>Type: INTEGER</P>
225         */
226        public static final String PROTOCOL = "protocol";
227
228        /**
229         * Is the {@code TP-Reply-Path} flag set?
230         * <P>Type: BOOLEAN</P>
231         */
232        public static final String REPLY_PATH_PRESENT = "reply_path_present";
233
234        /**
235         * The service center (SC) through which to send the message, if present.
236         * <P>Type: TEXT</P>
237         */
238        public static final String SERVICE_CENTER = "service_center";
239
240        /**
241         * Is the message locked?
242         * <P>Type: INTEGER (boolean)</P>
243         */
244        public static final String LOCKED = "locked";
245
246        /**
247         * The subscription to which the message belongs to. Its value will be
248         * < 0 if the sub id cannot be determined.
249         * <p>Type: INTEGER (long) </p>
250         */
251        public static final String SUBSCRIPTION_ID = "sub_id";
252
253        /**
254         * The MTU size of the mobile interface to which the APN connected
255         * @hide
256         */
257        public static final String MTU = "mtu";
258
259        /**
260         * Error code associated with sending or receiving this message
261         * <P>Type: INTEGER</P>
262         */
263        public static final String ERROR_CODE = "error_code";
264
265        /**
266         * The identity of the sender of a sent message. It is
267         * usually the package name of the app which sends the message.
268         * <p class="note"><strong>Note:</strong>
269         * This column is read-only. It is set by the provider and can not be changed by apps.
270         * <p>Type: TEXT</p>
271         */
272        public static final String CREATOR = "creator";
273    }
274
275    /**
276     * Contains all text-based SMS messages.
277     */
278    public static final class Sms implements BaseColumns, TextBasedSmsColumns {
279
280        /**
281         * Not instantiable.
282         * @hide
283         */
284        private Sms() {
285        }
286
287        /**
288         * Used to determine the currently configured default SMS package.
289         * @param context context of the requesting application
290         * @return package name for the default SMS package or null
291         */
292        public static String getDefaultSmsPackage(Context context) {
293            ComponentName component = SmsApplication.getDefaultSmsApplication(context, false);
294            if (component != null) {
295                return component.getPackageName();
296            }
297            return null;
298        }
299
300        /**
301         * Return cursor for table query.
302         * @hide
303         */
304        public static Cursor query(ContentResolver cr, String[] projection) {
305            return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
306        }
307
308        /**
309         * Return cursor for table query.
310         * @hide
311         */
312        public static Cursor query(ContentResolver cr, String[] projection,
313                String where, String orderBy) {
314            return cr.query(CONTENT_URI, projection, where,
315                    null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
316        }
317
318        /**
319         * The {@code content://} style URL for this table.
320         */
321        public static final Uri CONTENT_URI = Uri.parse("content://sms");
322
323        /**
324         * The default sort order for this table.
325         */
326        public static final String DEFAULT_SORT_ORDER = "date DESC";
327
328        /**
329         * Add an SMS to the given URI.
330         *
331         * @param resolver the content resolver to use
332         * @param uri the URI to add the message to
333         * @param address the address of the sender
334         * @param body the body of the message
335         * @param subject the pseudo-subject of the message
336         * @param date the timestamp for the message
337         * @param read true if the message has been read, false if not
338         * @param deliveryReport true if a delivery report was requested, false if not
339         * @return the URI for the new message
340         * @hide
341         */
342        public static Uri addMessageToUri(ContentResolver resolver,
343                Uri uri, String address, String body, String subject,
344                Long date, boolean read, boolean deliveryReport) {
345            return addMessageToUri(SubscriptionManager.getDefaultSmsSubscriptionId(),
346                    resolver, uri, address, body, subject, date, read, deliveryReport, -1L);
347        }
348
349        /**
350         * Add an SMS to the given URI.
351         *
352         * @param resolver the content resolver to use
353         * @param uri the URI to add the message to
354         * @param address the address of the sender
355         * @param body the body of the message
356         * @param subject the psuedo-subject of the message
357         * @param date the timestamp for the message
358         * @param read true if the message has been read, false if not
359         * @param deliveryReport true if a delivery report was requested, false if not
360         * @param subId the subscription which the message belongs to
361         * @return the URI for the new message
362         * @hide
363         */
364        public static Uri addMessageToUri(int subId, ContentResolver resolver,
365                Uri uri, String address, String body, String subject,
366                Long date, boolean read, boolean deliveryReport) {
367            return addMessageToUri(subId, resolver, uri, address, body, subject,
368                    date, read, deliveryReport, -1L);
369        }
370
371        /**
372         * Add an SMS to the given URI with the specified thread ID.
373         *
374         * @param resolver the content resolver to use
375         * @param uri the URI to add the message to
376         * @param address the address of the sender
377         * @param body the body of the message
378         * @param subject the pseudo-subject of the message
379         * @param date the timestamp for the message
380         * @param read true if the message has been read, false if not
381         * @param deliveryReport true if a delivery report was requested, false if not
382         * @param threadId the thread_id of the message
383         * @return the URI for the new message
384         * @hide
385         */
386        public static Uri addMessageToUri(ContentResolver resolver,
387                Uri uri, String address, String body, String subject,
388                Long date, boolean read, boolean deliveryReport, long threadId) {
389            return addMessageToUri(SubscriptionManager.getDefaultSmsSubscriptionId(),
390                    resolver, uri, address, body, subject,
391                    date, read, deliveryReport, threadId);
392        }
393
394        /**
395         * Add an SMS to the given URI with thread_id specified.
396         *
397         * @param resolver the content resolver to use
398         * @param uri the URI to add the message to
399         * @param address the address of the sender
400         * @param body the body of the message
401         * @param subject the psuedo-subject of the message
402         * @param date the timestamp for the message
403         * @param read true if the message has been read, false if not
404         * @param deliveryReport true if a delivery report was requested, false if not
405         * @param threadId the thread_id of the message
406         * @param subId the subscription which the message belongs to
407         * @return the URI for the new message
408         * @hide
409         */
410        public static Uri addMessageToUri(int subId, ContentResolver resolver,
411                Uri uri, String address, String body, String subject,
412                Long date, boolean read, boolean deliveryReport, long threadId) {
413            ContentValues values = new ContentValues(8);
414            Rlog.v(TAG,"Telephony addMessageToUri sub id: " + subId);
415
416            values.put(SUBSCRIPTION_ID, subId);
417            values.put(ADDRESS, address);
418            if (date != null) {
419                values.put(DATE, date);
420            }
421            values.put(READ, read ? Integer.valueOf(1) : Integer.valueOf(0));
422            values.put(SUBJECT, subject);
423            values.put(BODY, body);
424            if (deliveryReport) {
425                values.put(STATUS, STATUS_PENDING);
426            }
427            if (threadId != -1L) {
428                values.put(THREAD_ID, threadId);
429            }
430            return resolver.insert(uri, values);
431        }
432
433        /**
434         * Move a message to the given folder.
435         *
436         * @param context the context to use
437         * @param uri the message to move
438         * @param folder the folder to move to
439         * @return true if the operation succeeded
440         * @hide
441         */
442        public static boolean moveMessageToFolder(Context context,
443                Uri uri, int folder, int error) {
444            if (uri == null) {
445                return false;
446            }
447
448            boolean markAsUnread = false;
449            boolean markAsRead = false;
450            switch(folder) {
451            case MESSAGE_TYPE_INBOX:
452            case MESSAGE_TYPE_DRAFT:
453                break;
454            case MESSAGE_TYPE_OUTBOX:
455            case MESSAGE_TYPE_SENT:
456                markAsRead = true;
457                break;
458            case MESSAGE_TYPE_FAILED:
459            case MESSAGE_TYPE_QUEUED:
460                markAsUnread = true;
461                break;
462            default:
463                return false;
464            }
465
466            ContentValues values = new ContentValues(3);
467
468            values.put(TYPE, folder);
469            if (markAsUnread) {
470                values.put(READ, 0);
471            } else if (markAsRead) {
472                values.put(READ, 1);
473            }
474            values.put(ERROR_CODE, error);
475
476            return 1 == SqliteWrapper.update(context, context.getContentResolver(),
477                            uri, values, null, null);
478        }
479
480        /**
481         * Returns true iff the folder (message type) identifies an
482         * outgoing message.
483         * @hide
484         */
485        public static boolean isOutgoingFolder(int messageType) {
486            return  (messageType == MESSAGE_TYPE_FAILED)
487                    || (messageType == MESSAGE_TYPE_OUTBOX)
488                    || (messageType == MESSAGE_TYPE_SENT)
489                    || (messageType == MESSAGE_TYPE_QUEUED);
490        }
491
492        /**
493         * Contains all text-based SMS messages in the SMS app inbox.
494         */
495        public static final class Inbox implements BaseColumns, TextBasedSmsColumns {
496
497            /**
498             * Not instantiable.
499             * @hide
500             */
501            private Inbox() {
502            }
503
504            /**
505             * The {@code content://} style URL for this table.
506             */
507            public static final Uri CONTENT_URI = Uri.parse("content://sms/inbox");
508
509            /**
510             * The default sort order for this table.
511             */
512            public static final String DEFAULT_SORT_ORDER = "date DESC";
513
514            /**
515             * Add an SMS to the Draft box.
516             *
517             * @param resolver the content resolver to use
518             * @param address the address of the sender
519             * @param body the body of the message
520             * @param subject the pseudo-subject of the message
521             * @param date the timestamp for the message
522             * @param read true if the message has been read, false if not
523             * @return the URI for the new message
524             * @hide
525             */
526            public static Uri addMessage(ContentResolver resolver,
527                    String address, String body, String subject, Long date,
528                    boolean read) {
529                return addMessageToUri(SubscriptionManager.getDefaultSmsSubscriptionId(),
530                        resolver, CONTENT_URI, address, body, subject, date, read, false);
531            }
532
533            /**
534             * Add an SMS to the Draft box.
535             *
536             * @param resolver the content resolver to use
537             * @param address the address of the sender
538             * @param body the body of the message
539             * @param subject the psuedo-subject of the message
540             * @param date the timestamp for the message
541             * @param read true if the message has been read, false if not
542             * @param subId the subscription which the message belongs to
543             * @return the URI for the new message
544             * @hide
545             */
546            public static Uri addMessage(int subId, ContentResolver resolver,
547                    String address, String body, String subject, Long date, boolean read) {
548                return addMessageToUri(subId, resolver, CONTENT_URI, address, body,
549                        subject, date, read, false);
550            }
551        }
552
553        /**
554         * Contains all sent text-based SMS messages in the SMS app.
555         */
556        public static final class Sent implements BaseColumns, TextBasedSmsColumns {
557
558            /**
559             * Not instantiable.
560             * @hide
561             */
562            private Sent() {
563            }
564
565            /**
566             * The {@code content://} style URL for this table.
567             */
568            public static final Uri CONTENT_URI = Uri.parse("content://sms/sent");
569
570            /**
571             * The default sort order for this table.
572             */
573            public static final String DEFAULT_SORT_ORDER = "date DESC";
574
575            /**
576             * Add an SMS to the Draft box.
577             *
578             * @param resolver the content resolver to use
579             * @param address the address of the sender
580             * @param body the body of the message
581             * @param subject the pseudo-subject of the message
582             * @param date the timestamp for the message
583             * @return the URI for the new message
584             * @hide
585             */
586            public static Uri addMessage(ContentResolver resolver,
587                    String address, String body, String subject, Long date) {
588                return addMessageToUri(SubscriptionManager.getDefaultSmsSubscriptionId(),
589                        resolver, CONTENT_URI, address, body, subject, date, true, false);
590            }
591
592            /**
593             * Add an SMS to the Draft box.
594             *
595             * @param resolver the content resolver to use
596             * @param address the address of the sender
597             * @param body the body of the message
598             * @param subject the psuedo-subject of the message
599             * @param date the timestamp for the message
600             * @param subId the subscription which the message belongs to
601             * @return the URI for the new message
602             * @hide
603             */
604            public static Uri addMessage(int subId, ContentResolver resolver,
605                    String address, String body, String subject, Long date) {
606                return addMessageToUri(subId, resolver, CONTENT_URI, address, body,
607                        subject, date, true, false);
608            }
609        }
610
611        /**
612         * Contains all sent text-based SMS messages in the SMS app.
613         */
614        public static final class Draft implements BaseColumns, TextBasedSmsColumns {
615
616            /**
617             * Not instantiable.
618             * @hide
619             */
620            private Draft() {
621            }
622
623            /**
624             * The {@code content://} style URL for this table.
625             */
626            public static final Uri CONTENT_URI = Uri.parse("content://sms/draft");
627
628           /**
629            * @hide
630            */
631            public static Uri addMessage(ContentResolver resolver,
632                    String address, String body, String subject, Long date) {
633                return addMessageToUri(SubscriptionManager.getDefaultSmsSubscriptionId(),
634                        resolver, CONTENT_URI, address, body, subject, date, true, false);
635            }
636
637            /**
638             * Add an SMS to the Draft box.
639             *
640             * @param resolver the content resolver to use
641             * @param address the address of the sender
642             * @param body the body of the message
643             * @param subject the psuedo-subject of the message
644             * @param date the timestamp for the message
645             * @param subId the subscription which the message belongs to
646             * @return the URI for the new message
647             * @hide
648             */
649            public static Uri addMessage(int subId, ContentResolver resolver,
650                    String address, String body, String subject, Long date) {
651                return addMessageToUri(subId, resolver, CONTENT_URI, address, body,
652                        subject, date, true, false);
653            }
654
655            /**
656             * The default sort order for this table.
657             */
658            public static final String DEFAULT_SORT_ORDER = "date DESC";
659        }
660
661        /**
662         * Contains all pending outgoing text-based SMS messages.
663         */
664        public static final class Outbox implements BaseColumns, TextBasedSmsColumns {
665
666            /**
667             * Not instantiable.
668             * @hide
669             */
670            private Outbox() {
671            }
672
673            /**
674             * The {@code content://} style URL for this table.
675             */
676            public static final Uri CONTENT_URI = Uri.parse("content://sms/outbox");
677
678            /**
679             * The default sort order for this table.
680             */
681            public static final String DEFAULT_SORT_ORDER = "date DESC";
682
683            /**
684             * Add an SMS to the outbox.
685             *
686             * @param resolver the content resolver to use
687             * @param address the address of the sender
688             * @param body the body of the message
689             * @param subject the pseudo-subject of the message
690             * @param date the timestamp for the message
691             * @param deliveryReport whether a delivery report was requested for the message
692             * @return the URI for the new message
693             * @hide
694             */
695            public static Uri addMessage(ContentResolver resolver,
696                    String address, String body, String subject, Long date,
697                    boolean deliveryReport, long threadId) {
698                return addMessageToUri(SubscriptionManager.getDefaultSmsSubscriptionId(),
699                        resolver, CONTENT_URI, address, body, subject, date,
700                        true, deliveryReport, threadId);
701            }
702
703            /**
704             * Add an SMS to the Out box.
705             *
706             * @param resolver the content resolver to use
707             * @param address the address of the sender
708             * @param body the body of the message
709             * @param subject the psuedo-subject of the message
710             * @param date the timestamp for the message
711             * @param deliveryReport whether a delivery report was requested for the message
712             * @param subId the subscription which the message belongs to
713             * @return the URI for the new message
714             * @hide
715             */
716            public static Uri addMessage(int subId, ContentResolver resolver,
717                    String address, String body, String subject, Long date,
718                    boolean deliveryReport, long threadId) {
719                return addMessageToUri(subId, resolver, CONTENT_URI, address, body,
720                        subject, date, true, deliveryReport, threadId);
721            }
722        }
723
724        /**
725         * Contains all sent text-based SMS messages in the SMS app.
726         */
727        public static final class Conversations
728                implements BaseColumns, TextBasedSmsColumns {
729
730            /**
731             * Not instantiable.
732             * @hide
733             */
734            private Conversations() {
735            }
736
737            /**
738             * The {@code content://} style URL for this table.
739             */
740            public static final Uri CONTENT_URI = Uri.parse("content://sms/conversations");
741
742            /**
743             * The default sort order for this table.
744             */
745            public static final String DEFAULT_SORT_ORDER = "date DESC";
746
747            /**
748             * The first 45 characters of the body of the message.
749             * <P>Type: TEXT</P>
750             */
751            public static final String SNIPPET = "snippet";
752
753            /**
754             * The number of messages in the conversation.
755             * <P>Type: INTEGER</P>
756             */
757            public static final String MESSAGE_COUNT = "msg_count";
758        }
759
760        /**
761         * Contains constants for SMS related Intents that are broadcast.
762         */
763        public static final class Intents {
764
765            /**
766             * Not instantiable.
767             * @hide
768             */
769            private Intents() {
770            }
771
772            /**
773             * Set by BroadcastReceiver to indicate that the message was handled
774             * successfully.
775             */
776            public static final int RESULT_SMS_HANDLED = 1;
777
778            /**
779             * Set by BroadcastReceiver to indicate a generic error while
780             * processing the message.
781             */
782            public static final int RESULT_SMS_GENERIC_ERROR = 2;
783
784            /**
785             * Set by BroadcastReceiver to indicate insufficient memory to store
786             * the message.
787             */
788            public static final int RESULT_SMS_OUT_OF_MEMORY = 3;
789
790            /**
791             * Set by BroadcastReceiver to indicate that the message, while
792             * possibly valid, is of a format or encoding that is not
793             * supported.
794             */
795            public static final int RESULT_SMS_UNSUPPORTED = 4;
796
797            /**
798             * Set by BroadcastReceiver to indicate a duplicate incoming message.
799             */
800            public static final int RESULT_SMS_DUPLICATED = 5;
801
802            /**
803             * Activity action: Ask the user to change the default
804             * SMS application. This will show a dialog that asks the
805             * user whether they want to replace the current default
806             * SMS application with the one specified in
807             * {@link #EXTRA_PACKAGE_NAME}.
808             */
809            @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
810            public static final String ACTION_CHANGE_DEFAULT =
811                    "android.provider.Telephony.ACTION_CHANGE_DEFAULT";
812
813            /**
814             * The PackageName string passed in as an
815             * extra for {@link #ACTION_CHANGE_DEFAULT}
816             *
817             * @see #ACTION_CHANGE_DEFAULT
818             */
819            public static final String EXTRA_PACKAGE_NAME = "package";
820
821            /**
822             * Broadcast Action: A new text-based SMS message has been received
823             * by the device. This intent will only be delivered to the default
824             * sms app. That app is responsible for writing the message and notifying
825             * the user. The intent will have the following extra values:</p>
826             *
827             * <ul>
828             *   <li><em>"pdus"</em> - An Object[] of byte[]s containing the PDUs
829             *   that make up the message.</li>
830             *   <li><em>"format"</em> - A String describing the format of the PDUs. It can
831             *   be either "3gpp" or "3gpp2".</li>
832             *   <li><em>"subscription"</em> - An optional long value of the subscription id which
833             *   received the message.</li>
834             *   <li><em>"slot"</em> - An optional int value of the SIM slot containing the
835             *   subscription.</li>
836             *   <li><em>"phone"</em> - An optional int value of the phone id associated with the
837             *   subscription.</li>
838             *   <li><em>"errorCode"</em> - An optional int error code associated with receiving
839             *   the message.</li>
840             * </ul>
841             *
842             * <p>The extra values can be extracted using
843             * {@link #getMessagesFromIntent(Intent)}.</p>
844             *
845             * <p>If a BroadcastReceiver encounters an error while processing
846             * this intent it should set the result code appropriately.</p>
847             *
848             * <p class="note"><strong>Note:</strong>
849             * The broadcast receiver that filters for this intent must declare
850             * {@link android.Manifest.permission#BROADCAST_SMS} as a required permission in
851             * the <a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code
852             * <receiver>}</a> tag.
853             *
854             * <p>Requires {@link android.Manifest.permission#RECEIVE_SMS} to receive.</p>
855             */
856            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
857            public static final String SMS_DELIVER_ACTION =
858                    "android.provider.Telephony.SMS_DELIVER";
859
860            /**
861             * Broadcast Action: A new text-based SMS message has been received
862             * by the device. This intent will be delivered to all registered
863             * receivers as a notification. These apps are not expected to write the
864             * message or notify the user. The intent will have the following extra
865             * values:</p>
866             *
867             * <ul>
868             *   <li><em>"pdus"</em> - An Object[] of byte[]s containing the PDUs
869             *   that make up the message.</li>
870             * </ul>
871             *
872             * <p>The extra values can be extracted using
873             * {@link #getMessagesFromIntent(Intent)}.</p>
874             *
875             * <p>If a BroadcastReceiver encounters an error while processing
876             * this intent it should set the result code appropriately.</p>
877             *
878             * <p>Requires {@link android.Manifest.permission#RECEIVE_SMS} to receive.</p>
879             */
880            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
881            public static final String SMS_RECEIVED_ACTION =
882                    "android.provider.Telephony.SMS_RECEIVED";
883
884            /**
885             * Broadcast Action: A new data based SMS message has been received
886             * by the device. This intent will be delivered to all registered
887             * receivers as a notification. The intent will have the following extra
888             * values:</p>
889             *
890             * <ul>
891             *   <li><em>"pdus"</em> - An Object[] of byte[]s containing the PDUs
892             *   that make up the message.</li>
893             * </ul>
894             *
895             * <p>The extra values can be extracted using
896             * {@link #getMessagesFromIntent(Intent)}.</p>
897             *
898             * <p>If a BroadcastReceiver encounters an error while processing
899             * this intent it should set the result code appropriately.</p>
900             *
901             * <p>Requires {@link android.Manifest.permission#RECEIVE_SMS} to receive.</p>
902             */
903            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
904            public static final String DATA_SMS_RECEIVED_ACTION =
905                    "android.intent.action.DATA_SMS_RECEIVED";
906
907            /**
908             * Broadcast Action: A new WAP PUSH message has been received by the
909             * device. This intent will only be delivered to the default
910             * sms app. That app is responsible for writing the message and notifying
911             * the user. The intent will have the following extra values:</p>
912             *
913             * <ul>
914             *   <li><em>"transactionId"</em> - (Integer) The WAP transaction ID</li>
915             *   <li><em>"pduType"</em> - (Integer) The WAP PDU type</li>
916             *   <li><em>"header"</em> - (byte[]) The header of the message</li>
917             *   <li><em>"data"</em> - (byte[]) The data payload of the message</li>
918             *   <li><em>"contentTypeParameters" </em>
919             *   -(HashMap&lt;String,String&gt;) Any parameters associated with the content type
920             *   (decoded from the WSP Content-Type header)</li>
921             *   <li><em>"subscription"</em> - An optional long value of the subscription id which
922             *   received the message.</li>
923             *   <li><em>"slot"</em> - An optional int value of the SIM slot containing the
924             *   subscription.</li>
925             *   <li><em>"phone"</em> - An optional int value of the phone id associated with the
926             *   subscription.</li>
927             * </ul>
928             *
929             * <p>If a BroadcastReceiver encounters an error while processing
930             * this intent it should set the result code appropriately.</p>
931             *
932             * <p>The contentTypeParameters extra value is map of content parameters keyed by
933             * their names.</p>
934             *
935             * <p>If any unassigned well-known parameters are encountered, the key of the map will
936             * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter.  If
937             * a parameter has No-Value the value in the map will be null.</p>
938             *
939             * <p>Requires {@link android.Manifest.permission#RECEIVE_MMS} or
940             * {@link android.Manifest.permission#RECEIVE_WAP_PUSH} (depending on WAP PUSH type) to
941             * receive.</p>
942             *
943             * <p class="note"><strong>Note:</strong>
944             * The broadcast receiver that filters for this intent must declare
945             * {@link android.Manifest.permission#BROADCAST_WAP_PUSH} as a required permission in
946             * the <a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code
947             * <receiver>}</a> tag.
948             */
949            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
950            public static final String WAP_PUSH_DELIVER_ACTION =
951                    "android.provider.Telephony.WAP_PUSH_DELIVER";
952
953            /**
954             * Broadcast Action: A new WAP PUSH message has been received by the
955             * device. This intent will be delivered to all registered
956             * receivers as a notification. These apps are not expected to write the
957             * message or notify the user. The intent will have the following extra
958             * values:</p>
959             *
960             * <ul>
961             *   <li><em>"transactionId"</em> - (Integer) The WAP transaction ID</li>
962             *   <li><em>"pduType"</em> - (Integer) The WAP PDU type</li>
963             *   <li><em>"header"</em> - (byte[]) The header of the message</li>
964             *   <li><em>"data"</em> - (byte[]) The data payload of the message</li>
965             *   <li><em>"contentTypeParameters"</em>
966             *   - (HashMap&lt;String,String&gt;) Any parameters associated with the content type
967             *   (decoded from the WSP Content-Type header)</li>
968             * </ul>
969             *
970             * <p>If a BroadcastReceiver encounters an error while processing
971             * this intent it should set the result code appropriately.</p>
972             *
973             * <p>The contentTypeParameters extra value is map of content parameters keyed by
974             * their names.</p>
975             *
976             * <p>If any unassigned well-known parameters are encountered, the key of the map will
977             * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter.  If
978             * a parameter has No-Value the value in the map will be null.</p>
979             *
980             * <p>Requires {@link android.Manifest.permission#RECEIVE_MMS} or
981             * {@link android.Manifest.permission#RECEIVE_WAP_PUSH} (depending on WAP PUSH type) to
982             * receive.</p>
983             */
984            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
985            public static final String WAP_PUSH_RECEIVED_ACTION =
986                    "android.provider.Telephony.WAP_PUSH_RECEIVED";
987
988            /**
989             * Broadcast Action: A new Cell Broadcast message has been received
990             * by the device. The intent will have the following extra
991             * values:</p>
992             *
993             * <ul>
994             *   <li><em>"message"</em> - An SmsCbMessage object containing the broadcast message
995             *   data. This is not an emergency alert, so ETWS and CMAS data will be null.</li>
996             * </ul>
997             *
998             * <p>The extra values can be extracted using
999             * {@link #getMessagesFromIntent(Intent)}.</p>
1000             *
1001             * <p>If a BroadcastReceiver encounters an error while processing
1002             * this intent it should set the result code appropriately.</p>
1003             *
1004             * <p>Requires {@link android.Manifest.permission#RECEIVE_SMS} to receive.</p>
1005             */
1006            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1007            public static final String SMS_CB_RECEIVED_ACTION =
1008                    "android.provider.Telephony.SMS_CB_RECEIVED";
1009
1010            /**
1011             * Action: A SMS based carrier provision intent. Used to identify default
1012             * carrier provisioning app on the device.
1013             * @hide
1014             */
1015            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1016            @TestApi
1017            public static final String SMS_CARRIER_PROVISION_ACTION =
1018                    "android.provider.Telephony.SMS_CARRIER_PROVISION";
1019
1020            /**
1021             * Broadcast Action: A new Emergency Broadcast message has been received
1022             * by the device. The intent will have the following extra
1023             * values:</p>
1024             *
1025             * <ul>
1026             *   <li><em>"message"</em> - An SmsCbMessage object containing the broadcast message
1027             *   data, including ETWS or CMAS warning notification info if present.</li>
1028             * </ul>
1029             *
1030             * <p>The extra values can be extracted using
1031             * {@link #getMessagesFromIntent(Intent)}.</p>
1032             *
1033             * <p>If a BroadcastReceiver encounters an error while processing
1034             * this intent it should set the result code appropriately.</p>
1035             *
1036             * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST} to
1037             * receive.</p>
1038             * @removed
1039             */
1040            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1041            public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION =
1042                    "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
1043
1044            /**
1045             * Broadcast Action: A new CDMA SMS has been received containing Service Category
1046             * Program Data (updates the list of enabled broadcast channels). The intent will
1047             * have the following extra values:</p>
1048             *
1049             * <ul>
1050             *   <li><em>"operations"</em> - An array of CdmaSmsCbProgramData objects containing
1051             *   the service category operations (add/delete/clear) to perform.</li>
1052             * </ul>
1053             *
1054             * <p>The extra values can be extracted using
1055             * {@link #getMessagesFromIntent(Intent)}.</p>
1056             *
1057             * <p>If a BroadcastReceiver encounters an error while processing
1058             * this intent it should set the result code appropriately.</p>
1059             *
1060             * <p>Requires {@link android.Manifest.permission#RECEIVE_SMS} to receive.</p>
1061             */
1062            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1063            public static final String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION =
1064                    "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED";
1065
1066            /**
1067             * Broadcast Action: The SIM storage for SMS messages is full.  If
1068             * space is not freed, messages targeted for the SIM (class 2) may
1069             * not be saved.
1070             *
1071             * <p>Requires {@link android.Manifest.permission#RECEIVE_SMS} to receive.</p>
1072             */
1073            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1074            public static final String SIM_FULL_ACTION =
1075                    "android.provider.Telephony.SIM_FULL";
1076
1077            /**
1078             * Broadcast Action: An incoming SMS has been rejected by the
1079             * telephony framework.  This intent is sent in lieu of any
1080             * of the RECEIVED_ACTION intents.  The intent will have the
1081             * following extra value:</p>
1082             *
1083             * <ul>
1084             *   <li><em>"result"</em> - An int result code, e.g. {@link #RESULT_SMS_OUT_OF_MEMORY}
1085             *   indicating the error returned to the network.</li>
1086             * </ul>
1087             *
1088             * <p>Requires {@link android.Manifest.permission#RECEIVE_SMS} to receive.</p>
1089             */
1090            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1091            public static final String SMS_REJECTED_ACTION =
1092                "android.provider.Telephony.SMS_REJECTED";
1093
1094            /**
1095             * Broadcast Action: An incoming MMS has been downloaded. The intent is sent to all
1096             * users, except for secondary users where SMS has been disabled and to managed
1097             * profiles.
1098             * @hide
1099             */
1100            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1101            public static final String MMS_DOWNLOADED_ACTION =
1102                "android.provider.Telephony.MMS_DOWNLOADED";
1103
1104            /**
1105             * Broadcast action: When the default SMS package changes,
1106             * the previous default SMS package and the new default SMS
1107             * package are sent this broadcast to notify them of the change.
1108             * A boolean is specified in {@link #EXTRA_IS_DEFAULT_SMS_APP} to
1109             * indicate whether the package is the new default SMS package.
1110            */
1111            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1112            public static final String ACTION_DEFAULT_SMS_PACKAGE_CHANGED =
1113                            "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED";
1114
1115            /**
1116             * The IsDefaultSmsApp boolean passed as an
1117             * extra for {@link #ACTION_DEFAULT_SMS_PACKAGE_CHANGED} to indicate whether the
1118             * SMS app is becoming the default SMS app or is no longer the default.
1119             *
1120             * @see #ACTION_DEFAULT_SMS_PACKAGE_CHANGED
1121             */
1122            public static final String EXTRA_IS_DEFAULT_SMS_APP =
1123                    "android.provider.extra.IS_DEFAULT_SMS_APP";
1124
1125            /**
1126             * Broadcast action: When a change is made to the SmsProvider or
1127             * MmsProvider by a process other than the default SMS application,
1128             * this intent is broadcast to the default SMS application so it can
1129             * re-sync or update the change. The uri that was used to call the provider
1130             * can be retrieved from the intent with getData(). The actual affected uris
1131             * (which would depend on the selection specified) are not included.
1132            */
1133            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1134            public static final String ACTION_EXTERNAL_PROVIDER_CHANGE =
1135                          "android.provider.action.EXTERNAL_PROVIDER_CHANGE";
1136
1137            /**
1138             * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
1139             * {@link #DATA_SMS_RECEIVED_ACTION} intent.
1140             *
1141             * @param intent the intent to read from
1142             * @return an array of SmsMessages for the PDUs
1143             */
1144            public static SmsMessage[] getMessagesFromIntent(Intent intent) {
1145                Object[] messages;
1146                try {
1147                    messages = (Object[]) intent.getSerializableExtra("pdus");
1148                }
1149                catch (ClassCastException e) {
1150                    Rlog.e(TAG, "getMessagesFromIntent: " + e);
1151                    return null;
1152                }
1153
1154                if (messages == null) {
1155                    Rlog.e(TAG, "pdus does not exist in the intent");
1156                    return null;
1157                }
1158
1159                String format = intent.getStringExtra("format");
1160                int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
1161                        SubscriptionManager.getDefaultSmsSubscriptionId());
1162
1163                Rlog.v(TAG, " getMessagesFromIntent sub_id : " + subId);
1164
1165                int pduCount = messages.length;
1166                SmsMessage[] msgs = new SmsMessage[pduCount];
1167
1168                for (int i = 0; i < pduCount; i++) {
1169                    byte[] pdu = (byte[]) messages[i];
1170                    msgs[i] = SmsMessage.createFromPdu(pdu, format);
1171                    if (msgs[i] != null) msgs[i].setSubId(subId);
1172                }
1173                return msgs;
1174            }
1175        }
1176    }
1177
1178    /**
1179     * Base columns for tables that contain MMSs.
1180     */
1181    public interface BaseMmsColumns extends BaseColumns {
1182
1183        /** Message box: all messages. */
1184        public static final int MESSAGE_BOX_ALL    = 0;
1185        /** Message box: inbox. */
1186        public static final int MESSAGE_BOX_INBOX  = 1;
1187        /** Message box: sent messages. */
1188        public static final int MESSAGE_BOX_SENT   = 2;
1189        /** Message box: drafts. */
1190        public static final int MESSAGE_BOX_DRAFTS = 3;
1191        /** Message box: outbox. */
1192        public static final int MESSAGE_BOX_OUTBOX = 4;
1193        /** Message box: failed. */
1194        public static final int MESSAGE_BOX_FAILED = 5;
1195
1196        /**
1197         * The thread ID of the message.
1198         * <P>Type: INTEGER (long)</P>
1199         */
1200        public static final String THREAD_ID = "thread_id";
1201
1202        /**
1203         * The date the message was received.
1204         * <P>Type: INTEGER (long)</P>
1205         */
1206        public static final String DATE = "date";
1207
1208        /**
1209         * The date the message was sent.
1210         * <P>Type: INTEGER (long)</P>
1211         */
1212        public static final String DATE_SENT = "date_sent";
1213
1214        /**
1215         * The box which the message belongs to, e.g. {@link #MESSAGE_BOX_INBOX}.
1216         * <P>Type: INTEGER</P>
1217         */
1218        public static final String MESSAGE_BOX = "msg_box";
1219
1220        /**
1221         * Has the message been read?
1222         * <P>Type: INTEGER (boolean)</P>
1223         */
1224        public static final String READ = "read";
1225
1226        /**
1227         * Has the message been seen by the user? The "seen" flag determines
1228         * whether we need to show a new message notification.
1229         * <P>Type: INTEGER (boolean)</P>
1230         */
1231        public static final String SEEN = "seen";
1232
1233        /**
1234         * Does the message have only a text part (can also have a subject) with
1235         * no picture, slideshow, sound, etc. parts?
1236         * <P>Type: INTEGER (boolean)</P>
1237         */
1238        public static final String TEXT_ONLY = "text_only";
1239
1240        /**
1241         * The {@code Message-ID} of the message.
1242         * <P>Type: TEXT</P>
1243         */
1244        public static final String MESSAGE_ID = "m_id";
1245
1246        /**
1247         * The subject of the message, if present.
1248         * <P>Type: TEXT</P>
1249         */
1250        public static final String SUBJECT = "sub";
1251
1252        /**
1253         * The character set of the subject, if present.
1254         * <P>Type: INTEGER</P>
1255         */
1256        public static final String SUBJECT_CHARSET = "sub_cs";
1257
1258        /**
1259         * The {@code Content-Type} of the message.
1260         * <P>Type: TEXT</P>
1261         */
1262        public static final String CONTENT_TYPE = "ct_t";
1263
1264        /**
1265         * The {@code Content-Location} of the message.
1266         * <P>Type: TEXT</P>
1267         */
1268        public static final String CONTENT_LOCATION = "ct_l";
1269
1270        /**
1271         * The expiry time of the message.
1272         * <P>Type: INTEGER (long)</P>
1273         */
1274        public static final String EXPIRY = "exp";
1275
1276        /**
1277         * The class of the message.
1278         * <P>Type: TEXT</P>
1279         */
1280        public static final String MESSAGE_CLASS = "m_cls";
1281
1282        /**
1283         * The type of the message defined by MMS spec.
1284         * <P>Type: INTEGER</P>
1285         */
1286        public static final String MESSAGE_TYPE = "m_type";
1287
1288        /**
1289         * The version of the specification that this message conforms to.
1290         * <P>Type: INTEGER</P>
1291         */
1292        public static final String MMS_VERSION = "v";
1293
1294        /**
1295         * The size of the message.
1296         * <P>Type: INTEGER</P>
1297         */
1298        public static final String MESSAGE_SIZE = "m_size";
1299
1300        /**
1301         * The priority of the message.
1302         * <P>Type: INTEGER</P>
1303         */
1304        public static final String PRIORITY = "pri";
1305
1306        /**
1307         * The {@code read-report} of the message.
1308         * <P>Type: INTEGER (boolean)</P>
1309         */
1310        public static final String READ_REPORT = "rr";
1311
1312        /**
1313         * Is read report allowed?
1314         * <P>Type: INTEGER (boolean)</P>
1315         */
1316        public static final String REPORT_ALLOWED = "rpt_a";
1317
1318        /**
1319         * The {@code response-status} of the message.
1320         * <P>Type: INTEGER</P>
1321         */
1322        public static final String RESPONSE_STATUS = "resp_st";
1323
1324        /**
1325         * The {@code status} of the message.
1326         * <P>Type: INTEGER</P>
1327         */
1328        public static final String STATUS = "st";
1329
1330        /**
1331         * The {@code transaction-id} of the message.
1332         * <P>Type: TEXT</P>
1333         */
1334        public static final String TRANSACTION_ID = "tr_id";
1335
1336        /**
1337         * The {@code retrieve-status} of the message.
1338         * <P>Type: INTEGER</P>
1339         */
1340        public static final String RETRIEVE_STATUS = "retr_st";
1341
1342        /**
1343         * The {@code retrieve-text} of the message.
1344         * <P>Type: TEXT</P>
1345         */
1346        public static final String RETRIEVE_TEXT = "retr_txt";
1347
1348        /**
1349         * The character set of the retrieve-text.
1350         * <P>Type: INTEGER</P>
1351         */
1352        public static final String RETRIEVE_TEXT_CHARSET = "retr_txt_cs";
1353
1354        /**
1355         * The {@code read-status} of the message.
1356         * <P>Type: INTEGER</P>
1357         */
1358        public static final String READ_STATUS = "read_status";
1359
1360        /**
1361         * The {@code content-class} of the message.
1362         * <P>Type: INTEGER</P>
1363         */
1364        public static final String CONTENT_CLASS = "ct_cls";
1365
1366        /**
1367         * The {@code delivery-report} of the message.
1368         * <P>Type: INTEGER</P>
1369         */
1370        public static final String DELIVERY_REPORT = "d_rpt";
1371
1372        /**
1373         * The {@code delivery-time-token} of the message.
1374         * <P>Type: INTEGER</P>
1375         * @deprecated this column is no longer supported.
1376         * @hide
1377         */
1378        @Deprecated
1379        public static final String DELIVERY_TIME_TOKEN = "d_tm_tok";
1380
1381        /**
1382         * The {@code delivery-time} of the message.
1383         * <P>Type: INTEGER</P>
1384         */
1385        public static final String DELIVERY_TIME = "d_tm";
1386
1387        /**
1388         * The {@code response-text} of the message.
1389         * <P>Type: TEXT</P>
1390         */
1391        public static final String RESPONSE_TEXT = "resp_txt";
1392
1393        /**
1394         * The {@code sender-visibility} of the message.
1395         * <P>Type: TEXT</P>
1396         * @deprecated this column is no longer supported.
1397         * @hide
1398         */
1399        @Deprecated
1400        public static final String SENDER_VISIBILITY = "s_vis";
1401
1402        /**
1403         * The {@code reply-charging} of the message.
1404         * <P>Type: INTEGER</P>
1405         * @deprecated this column is no longer supported.
1406         * @hide
1407         */
1408        @Deprecated
1409        public static final String REPLY_CHARGING = "r_chg";
1410
1411        /**
1412         * The {@code reply-charging-deadline-token} of the message.
1413         * <P>Type: INTEGER</P>
1414         * @deprecated this column is no longer supported.
1415         * @hide
1416         */
1417        @Deprecated
1418        public static final String REPLY_CHARGING_DEADLINE_TOKEN = "r_chg_dl_tok";
1419
1420        /**
1421         * The {@code reply-charging-deadline} of the message.
1422         * <P>Type: INTEGER</P>
1423         * @deprecated this column is no longer supported.
1424         * @hide
1425         */
1426        @Deprecated
1427        public static final String REPLY_CHARGING_DEADLINE = "r_chg_dl";
1428
1429        /**
1430         * The {@code reply-charging-id} of the message.
1431         * <P>Type: TEXT</P>
1432         * @deprecated this column is no longer supported.
1433         * @hide
1434         */
1435        @Deprecated
1436        public static final String REPLY_CHARGING_ID = "r_chg_id";
1437
1438        /**
1439         * The {@code reply-charging-size} of the message.
1440         * <P>Type: INTEGER</P>
1441         * @deprecated this column is no longer supported.
1442         * @hide
1443         */
1444        @Deprecated
1445        public static final String REPLY_CHARGING_SIZE = "r_chg_sz";
1446
1447        /**
1448         * The {@code previously-sent-by} of the message.
1449         * <P>Type: TEXT</P>
1450         * @deprecated this column is no longer supported.
1451         * @hide
1452         */
1453        @Deprecated
1454        public static final String PREVIOUSLY_SENT_BY = "p_s_by";
1455
1456        /**
1457         * The {@code previously-sent-date} of the message.
1458         * <P>Type: INTEGER</P>
1459         * @deprecated this column is no longer supported.
1460         * @hide
1461         */
1462        @Deprecated
1463        public static final String PREVIOUSLY_SENT_DATE = "p_s_d";
1464
1465        /**
1466         * The {@code store} of the message.
1467         * <P>Type: TEXT</P>
1468         * @deprecated this column is no longer supported.
1469         * @hide
1470         */
1471        @Deprecated
1472        public static final String STORE = "store";
1473
1474        /**
1475         * The {@code mm-state} of the message.
1476         * <P>Type: INTEGER</P>
1477         * @deprecated this column is no longer supported.
1478         * @hide
1479         */
1480        @Deprecated
1481        public static final String MM_STATE = "mm_st";
1482
1483        /**
1484         * The {@code mm-flags-token} of the message.
1485         * <P>Type: INTEGER</P>
1486         * @deprecated this column is no longer supported.
1487         * @hide
1488         */
1489        @Deprecated
1490        public static final String MM_FLAGS_TOKEN = "mm_flg_tok";
1491
1492        /**
1493         * The {@code mm-flags} of the message.
1494         * <P>Type: TEXT</P>
1495         * @deprecated this column is no longer supported.
1496         * @hide
1497         */
1498        @Deprecated
1499        public static final String MM_FLAGS = "mm_flg";
1500
1501        /**
1502         * The {@code store-status} of the message.
1503         * <P>Type: TEXT</P>
1504         * @deprecated this column is no longer supported.
1505         * @hide
1506         */
1507        @Deprecated
1508        public static final String STORE_STATUS = "store_st";
1509
1510        /**
1511         * The {@code store-status-text} of the message.
1512         * <P>Type: TEXT</P>
1513         * @deprecated this column is no longer supported.
1514         * @hide
1515         */
1516        @Deprecated
1517        public static final String STORE_STATUS_TEXT = "store_st_txt";
1518
1519        /**
1520         * The {@code stored} of the message.
1521         * <P>Type: TEXT</P>
1522         * @deprecated this column is no longer supported.
1523         * @hide
1524         */
1525        @Deprecated
1526        public static final String STORED = "stored";
1527
1528        /**
1529         * The {@code totals} of the message.
1530         * <P>Type: TEXT</P>
1531         * @deprecated this column is no longer supported.
1532         * @hide
1533         */
1534        @Deprecated
1535        public static final String TOTALS = "totals";
1536
1537        /**
1538         * The {@code mbox-totals} of the message.
1539         * <P>Type: TEXT</P>
1540         * @deprecated this column is no longer supported.
1541         * @hide
1542         */
1543        @Deprecated
1544        public static final String MBOX_TOTALS = "mb_t";
1545
1546        /**
1547         * The {@code mbox-totals-token} of the message.
1548         * <P>Type: INTEGER</P>
1549         * @deprecated this column is no longer supported.
1550         * @hide
1551         */
1552        @Deprecated
1553        public static final String MBOX_TOTALS_TOKEN = "mb_t_tok";
1554
1555        /**
1556         * The {@code quotas} of the message.
1557         * <P>Type: TEXT</P>
1558         * @deprecated this column is no longer supported.
1559         * @hide
1560         */
1561        @Deprecated
1562        public static final String QUOTAS = "qt";
1563
1564        /**
1565         * The {@code mbox-quotas} of the message.
1566         * <P>Type: TEXT</P>
1567         * @deprecated this column is no longer supported.
1568         * @hide
1569         */
1570        @Deprecated
1571        public static final String MBOX_QUOTAS = "mb_qt";
1572
1573        /**
1574         * The {@code mbox-quotas-token} of the message.
1575         * <P>Type: INTEGER</P>
1576         * @deprecated this column is no longer supported.
1577         * @hide
1578         */
1579        @Deprecated
1580        public static final String MBOX_QUOTAS_TOKEN = "mb_qt_tok";
1581
1582        /**
1583         * The {@code message-count} of the message.
1584         * <P>Type: INTEGER</P>
1585         * @deprecated this column is no longer supported.
1586         * @hide
1587         */
1588        @Deprecated
1589        public static final String MESSAGE_COUNT = "m_cnt";
1590
1591        /**
1592         * The {@code start} of the message.
1593         * <P>Type: INTEGER</P>
1594         * @deprecated this column is no longer supported.
1595         * @hide
1596         */
1597        @Deprecated
1598        public static final String START = "start";
1599
1600        /**
1601         * The {@code distribution-indicator} of the message.
1602         * <P>Type: TEXT</P>
1603         * @deprecated this column is no longer supported.
1604         * @hide
1605         */
1606        @Deprecated
1607        public static final String DISTRIBUTION_INDICATOR = "d_ind";
1608
1609        /**
1610         * The {@code element-descriptor} of the message.
1611         * <P>Type: TEXT</P>
1612         * @deprecated this column is no longer supported.
1613         * @hide
1614         */
1615        @Deprecated
1616        public static final String ELEMENT_DESCRIPTOR = "e_des";
1617
1618        /**
1619         * The {@code limit} of the message.
1620         * <P>Type: INTEGER</P>
1621         * @deprecated this column is no longer supported.
1622         * @hide
1623         */
1624        @Deprecated
1625        public static final String LIMIT = "limit";
1626
1627        /**
1628         * The {@code recommended-retrieval-mode} of the message.
1629         * <P>Type: INTEGER</P>
1630         * @deprecated this column is no longer supported.
1631         * @hide
1632         */
1633        @Deprecated
1634        public static final String RECOMMENDED_RETRIEVAL_MODE = "r_r_mod";
1635
1636        /**
1637         * The {@code recommended-retrieval-mode-text} of the message.
1638         * <P>Type: TEXT</P>
1639         * @deprecated this column is no longer supported.
1640         * @hide
1641         */
1642        @Deprecated
1643        public static final String RECOMMENDED_RETRIEVAL_MODE_TEXT = "r_r_mod_txt";
1644
1645        /**
1646         * The {@code status-text} of the message.
1647         * <P>Type: TEXT</P>
1648         * @deprecated this column is no longer supported.
1649         * @hide
1650         */
1651        @Deprecated
1652        public static final String STATUS_TEXT = "st_txt";
1653
1654        /**
1655         * The {@code applic-id} of the message.
1656         * <P>Type: TEXT</P>
1657         * @deprecated this column is no longer supported.
1658         * @hide
1659         */
1660        @Deprecated
1661        public static final String APPLIC_ID = "apl_id";
1662
1663        /**
1664         * The {@code reply-applic-id} of the message.
1665         * <P>Type: TEXT</P>
1666         * @deprecated this column is no longer supported.
1667         * @hide
1668         */
1669        @Deprecated
1670        public static final String REPLY_APPLIC_ID = "r_apl_id";
1671
1672        /**
1673         * The {@code aux-applic-id} of the message.
1674         * <P>Type: TEXT</P>
1675         * @deprecated this column is no longer supported.
1676         * @hide
1677         */
1678        @Deprecated
1679        public static final String AUX_APPLIC_ID = "aux_apl_id";
1680
1681        /**
1682         * The {@code drm-content} of the message.
1683         * <P>Type: TEXT</P>
1684         * @deprecated this column is no longer supported.
1685         * @hide
1686         */
1687        @Deprecated
1688        public static final String DRM_CONTENT = "drm_c";
1689
1690        /**
1691         * The {@code adaptation-allowed} of the message.
1692         * <P>Type: TEXT</P>
1693         * @deprecated this column is no longer supported.
1694         * @hide
1695         */
1696        @Deprecated
1697        public static final String ADAPTATION_ALLOWED = "adp_a";
1698
1699        /**
1700         * The {@code replace-id} of the message.
1701         * <P>Type: TEXT</P>
1702         * @deprecated this column is no longer supported.
1703         * @hide
1704         */
1705        @Deprecated
1706        public static final String REPLACE_ID = "repl_id";
1707
1708        /**
1709         * The {@code cancel-id} of the message.
1710         * <P>Type: TEXT</P>
1711         * @deprecated this column is no longer supported.
1712         * @hide
1713         */
1714        @Deprecated
1715        public static final String CANCEL_ID = "cl_id";
1716
1717        /**
1718         * The {@code cancel-status} of the message.
1719         * <P>Type: INTEGER</P>
1720         * @deprecated this column is no longer supported.
1721         * @hide
1722         */
1723        @Deprecated
1724        public static final String CANCEL_STATUS = "cl_st";
1725
1726        /**
1727         * Is the message locked?
1728         * <P>Type: INTEGER (boolean)</P>
1729         */
1730        public static final String LOCKED = "locked";
1731
1732        /**
1733         * The subscription to which the message belongs to. Its value will be
1734         * < 0 if the sub id cannot be determined.
1735         * <p>Type: INTEGER (long)</p>
1736         */
1737        public static final String SUBSCRIPTION_ID = "sub_id";
1738
1739        /**
1740         * The identity of the sender of a sent message. It is
1741         * usually the package name of the app which sends the message.
1742         * <p class="note"><strong>Note:</strong>
1743         * This column is read-only. It is set by the provider and can not be changed by apps.
1744         * <p>Type: TEXT</p>
1745         */
1746        public static final String CREATOR = "creator";
1747    }
1748
1749    /**
1750     * Columns for the "canonical_addresses" table used by MMS and SMS.
1751     */
1752    public interface CanonicalAddressesColumns extends BaseColumns {
1753        /**
1754         * An address used in MMS or SMS.  Email addresses are
1755         * converted to lower case and are compared by string
1756         * equality.  Other addresses are compared using
1757         * PHONE_NUMBERS_EQUAL.
1758         * <P>Type: TEXT</P>
1759         */
1760        public static final String ADDRESS = "address";
1761    }
1762
1763    /**
1764     * Columns for the "threads" table used by MMS and SMS.
1765     */
1766    public interface ThreadsColumns extends BaseColumns {
1767
1768        /**
1769         * The date at which the thread was created.
1770         * <P>Type: INTEGER (long)</P>
1771         */
1772        public static final String DATE = "date";
1773
1774        /**
1775         * A string encoding of the recipient IDs of the recipients of
1776         * the message, in numerical order and separated by spaces.
1777         * <P>Type: TEXT</P>
1778         */
1779        public static final String RECIPIENT_IDS = "recipient_ids";
1780
1781        /**
1782         * The message count of the thread.
1783         * <P>Type: INTEGER</P>
1784         */
1785        public static final String MESSAGE_COUNT = "message_count";
1786
1787        /**
1788         * Indicates whether all messages of the thread have been read.
1789         * <P>Type: INTEGER</P>
1790         */
1791        public static final String READ = "read";
1792
1793        /**
1794         * The snippet of the latest message in the thread.
1795         * <P>Type: TEXT</P>
1796         */
1797        public static final String SNIPPET = "snippet";
1798
1799        /**
1800         * The charset of the snippet.
1801         * <P>Type: INTEGER</P>
1802         */
1803        public static final String SNIPPET_CHARSET = "snippet_cs";
1804
1805        /**
1806         * Type of the thread, either {@link Threads#COMMON_THREAD} or
1807         * {@link Threads#BROADCAST_THREAD}.
1808         * <P>Type: INTEGER</P>
1809         */
1810        public static final String TYPE = "type";
1811
1812        /**
1813         * Indicates whether there is a transmission error in the thread.
1814         * <P>Type: INTEGER</P>
1815         */
1816        public static final String ERROR = "error";
1817
1818        /**
1819         * Indicates whether this thread contains any attachments.
1820         * <P>Type: INTEGER</P>
1821         */
1822        public static final String HAS_ATTACHMENT = "has_attachment";
1823
1824        /**
1825         * If the thread is archived
1826         * <P>Type: INTEGER (boolean)</P>
1827         */
1828        public static final String ARCHIVED = "archived";
1829    }
1830
1831    /**
1832     * Helper functions for the "threads" table used by MMS and SMS.
1833     */
1834    public static final class Threads implements ThreadsColumns {
1835
1836        private static final String[] ID_PROJECTION = { BaseColumns._ID };
1837
1838        /**
1839         * Private {@code content://} style URL for this table. Used by
1840         * {@link #getOrCreateThreadId(android.content.Context, java.util.Set)}.
1841         */
1842        private static final Uri THREAD_ID_CONTENT_URI = Uri.parse(
1843                "content://mms-sms/threadID");
1844
1845        /**
1846         * The {@code content://} style URL for this table, by conversation.
1847         */
1848        public static final Uri CONTENT_URI = Uri.withAppendedPath(
1849                MmsSms.CONTENT_URI, "conversations");
1850
1851        /**
1852         * The {@code content://} style URL for this table, for obsolete threads.
1853         */
1854        public static final Uri OBSOLETE_THREADS_URI = Uri.withAppendedPath(
1855                CONTENT_URI, "obsolete");
1856
1857        /** Thread type: common thread. */
1858        public static final int COMMON_THREAD    = 0;
1859
1860        /** Thread type: broadcast thread. */
1861        public static final int BROADCAST_THREAD = 1;
1862
1863        /**
1864         * Not instantiable.
1865         * @hide
1866         */
1867        private Threads() {
1868        }
1869
1870        /**
1871         * This is a single-recipient version of {@code getOrCreateThreadId}.
1872         * It's convenient for use with SMS messages.
1873         * @param context the context object to use.
1874         * @param recipient the recipient to send to.
1875         */
1876        public static long getOrCreateThreadId(Context context, String recipient) {
1877            Set<String> recipients = new HashSet<String>();
1878
1879            recipients.add(recipient);
1880            return getOrCreateThreadId(context, recipients);
1881        }
1882
1883        /**
1884         * Given the recipients list and subject of an unsaved message,
1885         * return its thread ID.  If the message starts a new thread,
1886         * allocate a new thread ID.  Otherwise, use the appropriate
1887         * existing thread ID.
1888         *
1889         * <p>Find the thread ID of the same set of recipients (in any order,
1890         * without any additions). If one is found, return it. Otherwise,
1891         * return a unique thread ID.</p>
1892         */
1893        public static long getOrCreateThreadId(
1894                Context context, Set<String> recipients) {
1895            Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon();
1896
1897            for (String recipient : recipients) {
1898                if (Mms.isEmailAddress(recipient)) {
1899                    recipient = Mms.extractAddrSpec(recipient);
1900                }
1901
1902                uriBuilder.appendQueryParameter("recipient", recipient);
1903            }
1904
1905            Uri uri = uriBuilder.build();
1906            //if (DEBUG) Rlog.v(TAG, "getOrCreateThreadId uri: " + uri);
1907
1908            Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
1909                    uri, ID_PROJECTION, null, null, null);
1910            if (cursor != null) {
1911                try {
1912                    if (cursor.moveToFirst()) {
1913                        return cursor.getLong(0);
1914                    } else {
1915                        Rlog.e(TAG, "getOrCreateThreadId returned no rows!");
1916                    }
1917                } finally {
1918                    cursor.close();
1919                }
1920            }
1921
1922            Rlog.e(TAG, "getOrCreateThreadId failed with " + recipients.size() + " recipients");
1923            throw new IllegalArgumentException("Unable to find or allocate a thread ID.");
1924        }
1925    }
1926
1927    /**
1928     * Contains all MMS messages.
1929     */
1930    public static final class Mms implements BaseMmsColumns {
1931
1932        /**
1933         * Not instantiable.
1934         * @hide
1935         */
1936        private Mms() {
1937        }
1938
1939        /**
1940         * The {@code content://} URI for this table.
1941         */
1942        public static final Uri CONTENT_URI = Uri.parse("content://mms");
1943
1944        /**
1945         * Content URI for getting MMS report requests.
1946         */
1947        public static final Uri REPORT_REQUEST_URI = Uri.withAppendedPath(
1948                                            CONTENT_URI, "report-request");
1949
1950        /**
1951         * Content URI for getting MMS report status.
1952         */
1953        public static final Uri REPORT_STATUS_URI = Uri.withAppendedPath(
1954                                            CONTENT_URI, "report-status");
1955
1956        /**
1957         * The default sort order for this table.
1958         */
1959        public static final String DEFAULT_SORT_ORDER = "date DESC";
1960
1961        /**
1962         * Regex pattern for names and email addresses.
1963         * <ul>
1964         *     <li><em>mailbox</em> = {@code name-addr}</li>
1965         *     <li><em>name-addr</em> = {@code [display-name] angle-addr}</li>
1966         *     <li><em>angle-addr</em> = {@code [CFWS] "<" addr-spec ">" [CFWS]}</li>
1967         * </ul>
1968         * @hide
1969         */
1970        public static final Pattern NAME_ADDR_EMAIL_PATTERN =
1971                Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*");
1972
1973        /**
1974         * Helper method to query this table.
1975         * @hide
1976         */
1977        public static Cursor query(
1978                ContentResolver cr, String[] projection) {
1979            return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
1980        }
1981
1982        /**
1983         * Helper method to query this table.
1984         * @hide
1985         */
1986        public static Cursor query(
1987                ContentResolver cr, String[] projection,
1988                String where, String orderBy) {
1989            return cr.query(CONTENT_URI, projection,
1990                    where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
1991        }
1992
1993        /**
1994         * Helper method to extract email address from address string.
1995         * @hide
1996         */
1997        public static String extractAddrSpec(String address) {
1998            Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address);
1999
2000            if (match.matches()) {
2001                return match.group(2);
2002            }
2003            return address;
2004        }
2005
2006        /**
2007         * Is the specified address an email address?
2008         *
2009         * @param address the input address to test
2010         * @return true if address is an email address; false otherwise.
2011         * @hide
2012         */
2013        public static boolean isEmailAddress(String address) {
2014            if (TextUtils.isEmpty(address)) {
2015                return false;
2016            }
2017
2018            String s = extractAddrSpec(address);
2019            Matcher match = Patterns.EMAIL_ADDRESS.matcher(s);
2020            return match.matches();
2021        }
2022
2023        /**
2024         * Is the specified number a phone number?
2025         *
2026         * @param number the input number to test
2027         * @return true if number is a phone number; false otherwise.
2028         * @hide
2029         */
2030        public static boolean isPhoneNumber(String number) {
2031            if (TextUtils.isEmpty(number)) {
2032                return false;
2033            }
2034
2035            Matcher match = Patterns.PHONE.matcher(number);
2036            return match.matches();
2037        }
2038
2039        /**
2040         * Contains all MMS messages in the MMS app inbox.
2041         */
2042        public static final class Inbox implements BaseMmsColumns {
2043
2044            /**
2045             * Not instantiable.
2046             * @hide
2047             */
2048            private Inbox() {
2049            }
2050
2051            /**
2052             * The {@code content://} style URL for this table.
2053             */
2054            public static final Uri
2055                    CONTENT_URI = Uri.parse("content://mms/inbox");
2056
2057            /**
2058             * The default sort order for this table.
2059             */
2060            public static final String DEFAULT_SORT_ORDER = "date DESC";
2061        }
2062
2063        /**
2064         * Contains all MMS messages in the MMS app sent folder.
2065         */
2066        public static final class Sent implements BaseMmsColumns {
2067
2068            /**
2069             * Not instantiable.
2070             * @hide
2071             */
2072            private Sent() {
2073            }
2074
2075            /**
2076             * The {@code content://} style URL for this table.
2077             */
2078            public static final Uri
2079                    CONTENT_URI = Uri.parse("content://mms/sent");
2080
2081            /**
2082             * The default sort order for this table.
2083             */
2084            public static final String DEFAULT_SORT_ORDER = "date DESC";
2085        }
2086
2087        /**
2088         * Contains all MMS messages in the MMS app drafts folder.
2089         */
2090        public static final class Draft implements BaseMmsColumns {
2091
2092            /**
2093             * Not instantiable.
2094             * @hide
2095             */
2096            private Draft() {
2097            }
2098
2099            /**
2100             * The {@code content://} style URL for this table.
2101             */
2102            public static final Uri
2103                    CONTENT_URI = Uri.parse("content://mms/drafts");
2104
2105            /**
2106             * The default sort order for this table.
2107             */
2108            public static final String DEFAULT_SORT_ORDER = "date DESC";
2109        }
2110
2111        /**
2112         * Contains all MMS messages in the MMS app outbox.
2113         */
2114        public static final class Outbox implements BaseMmsColumns {
2115
2116            /**
2117             * Not instantiable.
2118             * @hide
2119             */
2120            private Outbox() {
2121            }
2122
2123            /**
2124             * The {@code content://} style URL for this table.
2125             */
2126            public static final Uri
2127                    CONTENT_URI = Uri.parse("content://mms/outbox");
2128
2129            /**
2130             * The default sort order for this table.
2131             */
2132            public static final String DEFAULT_SORT_ORDER = "date DESC";
2133        }
2134
2135        /**
2136         * Contains address information for an MMS message.
2137         */
2138        public static final class Addr implements BaseColumns {
2139
2140            /**
2141             * Not instantiable.
2142             * @hide
2143             */
2144            private Addr() {
2145            }
2146
2147            /**
2148             * The ID of MM which this address entry belongs to.
2149             * <P>Type: INTEGER (long)</P>
2150             */
2151            public static final String MSG_ID = "msg_id";
2152
2153            /**
2154             * The ID of contact entry in Phone Book.
2155             * <P>Type: INTEGER (long)</P>
2156             */
2157            public static final String CONTACT_ID = "contact_id";
2158
2159            /**
2160             * The address text.
2161             * <P>Type: TEXT</P>
2162             */
2163            public static final String ADDRESS = "address";
2164
2165            /**
2166             * Type of address: must be one of {@code PduHeaders.BCC},
2167             * {@code PduHeaders.CC}, {@code PduHeaders.FROM}, {@code PduHeaders.TO}.
2168             * <P>Type: INTEGER</P>
2169             */
2170            public static final String TYPE = "type";
2171
2172            /**
2173             * Character set of this entry (MMS charset value).
2174             * <P>Type: INTEGER</P>
2175             */
2176            public static final String CHARSET = "charset";
2177        }
2178
2179        /**
2180         * Contains message parts.
2181         */
2182        public static final class Part implements BaseColumns {
2183
2184            /**
2185             * Not instantiable.
2186             * @hide
2187             */
2188            private Part() {
2189            }
2190
2191            /**
2192             * The identifier of the message which this part belongs to.
2193             * <P>Type: INTEGER</P>
2194             */
2195            public static final String MSG_ID = "mid";
2196
2197            /**
2198             * The order of the part.
2199             * <P>Type: INTEGER</P>
2200             */
2201            public static final String SEQ = "seq";
2202
2203            /**
2204             * The content type of the part.
2205             * <P>Type: TEXT</P>
2206             */
2207            public static final String CONTENT_TYPE = "ct";
2208
2209            /**
2210             * The name of the part.
2211             * <P>Type: TEXT</P>
2212             */
2213            public static final String NAME = "name";
2214
2215            /**
2216             * The charset of the part.
2217             * <P>Type: TEXT</P>
2218             */
2219            public static final String CHARSET = "chset";
2220
2221            /**
2222             * The file name of the part.
2223             * <P>Type: TEXT</P>
2224             */
2225            public static final String FILENAME = "fn";
2226
2227            /**
2228             * The content disposition of the part.
2229             * <P>Type: TEXT</P>
2230             */
2231            public static final String CONTENT_DISPOSITION = "cd";
2232
2233            /**
2234             * The content ID of the part.
2235             * <P>Type: INTEGER</P>
2236             */
2237            public static final String CONTENT_ID = "cid";
2238
2239            /**
2240             * The content location of the part.
2241             * <P>Type: INTEGER</P>
2242             */
2243            public static final String CONTENT_LOCATION = "cl";
2244
2245            /**
2246             * The start of content-type of the message.
2247             * <P>Type: INTEGER</P>
2248             */
2249            public static final String CT_START = "ctt_s";
2250
2251            /**
2252             * The type of content-type of the message.
2253             * <P>Type: TEXT</P>
2254             */
2255            public static final String CT_TYPE = "ctt_t";
2256
2257            /**
2258             * The location (on filesystem) of the binary data of the part.
2259             * <P>Type: INTEGER</P>
2260             */
2261            public static final String _DATA = "_data";
2262
2263            /**
2264             * The message text.
2265             * <P>Type: TEXT</P>
2266             */
2267            public static final String TEXT = "text";
2268        }
2269
2270        /**
2271         * Message send rate table.
2272         */
2273        public static final class Rate {
2274
2275            /**
2276             * Not instantiable.
2277             * @hide
2278             */
2279            private Rate() {
2280            }
2281
2282            /**
2283             * The {@code content://} style URL for this table.
2284             */
2285            public static final Uri CONTENT_URI = Uri.withAppendedPath(
2286                    Mms.CONTENT_URI, "rate");
2287
2288            /**
2289             * When a message was successfully sent.
2290             * <P>Type: INTEGER (long)</P>
2291             */
2292            public static final String SENT_TIME = "sent_time";
2293        }
2294
2295        /**
2296         * Intents class.
2297         */
2298        public static final class Intents {
2299
2300            /**
2301             * Not instantiable.
2302             * @hide
2303             */
2304            private Intents() {
2305            }
2306
2307            /**
2308             * Indicates that the contents of specified URIs were changed.
2309             * The application which is showing or caching these contents
2310             * should be updated.
2311             */
2312            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
2313            public static final String CONTENT_CHANGED_ACTION
2314                    = "android.intent.action.CONTENT_CHANGED";
2315
2316            /**
2317             * An extra field which stores the URI of deleted contents.
2318             */
2319            public static final String DELETED_CONTENTS = "deleted_contents";
2320        }
2321    }
2322
2323    /**
2324     * Contains all MMS and SMS messages.
2325     */
2326    public static final class MmsSms implements BaseColumns {
2327
2328        /**
2329         * Not instantiable.
2330         * @hide
2331         */
2332        private MmsSms() {
2333        }
2334
2335        /**
2336         * The column to distinguish SMS and MMS messages in query results.
2337         */
2338        public static final String TYPE_DISCRIMINATOR_COLUMN =
2339                "transport_type";
2340
2341        /**
2342         * The {@code content://} style URL for this table.
2343         */
2344        public static final Uri CONTENT_URI = Uri.parse("content://mms-sms/");
2345
2346        /**
2347         * The {@code content://} style URL for this table, by conversation.
2348         */
2349        public static final Uri CONTENT_CONVERSATIONS_URI = Uri.parse(
2350                "content://mms-sms/conversations");
2351
2352        /**
2353         * The {@code content://} style URL for this table, by phone number.
2354         */
2355        public static final Uri CONTENT_FILTER_BYPHONE_URI = Uri.parse(
2356                "content://mms-sms/messages/byphone");
2357
2358        /**
2359         * The {@code content://} style URL for undelivered messages in this table.
2360         */
2361        public static final Uri CONTENT_UNDELIVERED_URI = Uri.parse(
2362                "content://mms-sms/undelivered");
2363
2364        /**
2365         * The {@code content://} style URL for draft messages in this table.
2366         */
2367        public static final Uri CONTENT_DRAFT_URI = Uri.parse(
2368                "content://mms-sms/draft");
2369
2370        /**
2371         * The {@code content://} style URL for locked messages in this table.
2372         */
2373        public static final Uri CONTENT_LOCKED_URI = Uri.parse(
2374                "content://mms-sms/locked");
2375
2376        /**
2377         * Pass in a query parameter called "pattern" which is the text to search for.
2378         * The sort order is fixed to be: {@code thread_id ASC, date DESC}.
2379         */
2380        public static final Uri SEARCH_URI = Uri.parse(
2381                "content://mms-sms/search");
2382
2383        // Constants for message protocol types.
2384
2385        /** SMS protocol type. */
2386        public static final int SMS_PROTO = 0;
2387
2388        /** MMS protocol type. */
2389        public static final int MMS_PROTO = 1;
2390
2391        // Constants for error types of pending messages.
2392
2393        /** Error type: no error. */
2394        public static final int NO_ERROR                      = 0;
2395
2396        /** Error type: generic transient error. */
2397        public static final int ERR_TYPE_GENERIC              = 1;
2398
2399        /** Error type: SMS protocol transient error. */
2400        public static final int ERR_TYPE_SMS_PROTO_TRANSIENT  = 2;
2401
2402        /** Error type: MMS protocol transient error. */
2403        public static final int ERR_TYPE_MMS_PROTO_TRANSIENT  = 3;
2404
2405        /** Error type: transport failure. */
2406        public static final int ERR_TYPE_TRANSPORT_FAILURE    = 4;
2407
2408        /** Error type: permanent error (along with all higher error values). */
2409        public static final int ERR_TYPE_GENERIC_PERMANENT    = 10;
2410
2411        /** Error type: SMS protocol permanent error. */
2412        public static final int ERR_TYPE_SMS_PROTO_PERMANENT  = 11;
2413
2414        /** Error type: MMS protocol permanent error. */
2415        public static final int ERR_TYPE_MMS_PROTO_PERMANENT  = 12;
2416
2417        /**
2418         * Contains pending messages info.
2419         */
2420        public static final class PendingMessages implements BaseColumns {
2421
2422            /**
2423             * Not instantiable.
2424             * @hide
2425             */
2426            private PendingMessages() {
2427            }
2428
2429            public static final Uri CONTENT_URI = Uri.withAppendedPath(
2430                    MmsSms.CONTENT_URI, "pending");
2431
2432            /**
2433             * The type of transport protocol (MMS or SMS).
2434             * <P>Type: INTEGER</P>
2435             */
2436            public static final String PROTO_TYPE = "proto_type";
2437
2438            /**
2439             * The ID of the message to be sent or downloaded.
2440             * <P>Type: INTEGER (long)</P>
2441             */
2442            public static final String MSG_ID = "msg_id";
2443
2444            /**
2445             * The type of the message to be sent or downloaded.
2446             * This field is only valid for MM. For SM, its value is always set to 0.
2447             * <P>Type: INTEGER</P>
2448             */
2449            public static final String MSG_TYPE = "msg_type";
2450
2451            /**
2452             * The type of the error code.
2453             * <P>Type: INTEGER</P>
2454             */
2455            public static final String ERROR_TYPE = "err_type";
2456
2457            /**
2458             * The error code of sending/retrieving process.
2459             * <P>Type: INTEGER</P>
2460             */
2461            public static final String ERROR_CODE = "err_code";
2462
2463            /**
2464             * How many times we tried to send or download the message.
2465             * <P>Type: INTEGER</P>
2466             */
2467            public static final String RETRY_INDEX = "retry_index";
2468
2469            /**
2470             * The time to do next retry.
2471             * <P>Type: INTEGER (long)</P>
2472             */
2473            public static final String DUE_TIME = "due_time";
2474
2475            /**
2476             * The time we last tried to send or download the message.
2477             * <P>Type: INTEGER (long)</P>
2478             */
2479            public static final String LAST_TRY = "last_try";
2480
2481            /**
2482             * The subscription to which the message belongs to. Its value will be
2483             * < 0 if the sub id cannot be determined.
2484             * <p>Type: INTEGER (long) </p>
2485             */
2486            public static final String SUBSCRIPTION_ID = "pending_sub_id";
2487        }
2488
2489        /**
2490         * Words table used by provider for full-text searches.
2491         * @hide
2492         */
2493        public static final class WordsTable {
2494
2495            /**
2496             * Not instantiable.
2497             * @hide
2498             */
2499            private WordsTable() {}
2500
2501            /**
2502             * Primary key.
2503             * <P>Type: INTEGER (long)</P>
2504             */
2505            public static final String ID = "_id";
2506
2507            /**
2508             * Source row ID.
2509             * <P>Type: INTEGER (long)</P>
2510             */
2511            public static final String SOURCE_ROW_ID = "source_id";
2512
2513            /**
2514             * Table ID (either 1 or 2).
2515             * <P>Type: INTEGER</P>
2516             */
2517            public static final String TABLE_ID = "table_to_use";
2518
2519            /**
2520             * The words to index.
2521             * <P>Type: TEXT</P>
2522             */
2523            public static final String INDEXED_TEXT = "index_text";
2524        }
2525    }
2526
2527    /**
2528     * Carriers class contains information about APNs, including MMSC information.
2529     */
2530    public static final class Carriers implements BaseColumns {
2531
2532        /**
2533         * Not instantiable.
2534         * @hide
2535         */
2536        private Carriers() {}
2537
2538        /**
2539         * The {@code content://} style URL for this table.
2540         */
2541        public static final Uri CONTENT_URI = Uri.parse("content://telephony/carriers");
2542
2543        /**
2544         * The default sort order for this table.
2545         */
2546        public static final String DEFAULT_SORT_ORDER = "name ASC";
2547
2548        /**
2549         * Entry name.
2550         * <P>Type: TEXT</P>
2551         */
2552        public static final String NAME = "name";
2553
2554        /**
2555         * APN name.
2556         * <P>Type: TEXT</P>
2557         */
2558        public static final String APN = "apn";
2559
2560        /**
2561         * Proxy address.
2562         * <P>Type: TEXT</P>
2563         */
2564        public static final String PROXY = "proxy";
2565
2566        /**
2567         * Proxy port.
2568         * <P>Type: TEXT</P>
2569         */
2570        public static final String PORT = "port";
2571
2572        /**
2573         * MMS proxy address.
2574         * <P>Type: TEXT</P>
2575         */
2576        public static final String MMSPROXY = "mmsproxy";
2577
2578        /**
2579         * MMS proxy port.
2580         * <P>Type: TEXT</P>
2581         */
2582        public static final String MMSPORT = "mmsport";
2583
2584        /**
2585         * Server address.
2586         * <P>Type: TEXT</P>
2587         */
2588        public static final String SERVER = "server";
2589
2590        /**
2591         * APN username.
2592         * <P>Type: TEXT</P>
2593         */
2594        public static final String USER = "user";
2595
2596        /**
2597         * APN password.
2598         * <P>Type: TEXT</P>
2599         */
2600        public static final String PASSWORD = "password";
2601
2602        /**
2603         * MMSC URL.
2604         * <P>Type: TEXT</P>
2605         */
2606        public static final String MMSC = "mmsc";
2607
2608        /**
2609         * Mobile Country Code (MCC).
2610         * <P>Type: TEXT</P>
2611         */
2612        public static final String MCC = "mcc";
2613
2614        /**
2615         * Mobile Network Code (MNC).
2616         * <P>Type: TEXT</P>
2617         */
2618        public static final String MNC = "mnc";
2619
2620        /**
2621         * Numeric operator ID (as String). Usually {@code MCC + MNC}.
2622         * <P>Type: TEXT</P>
2623         */
2624        public static final String NUMERIC = "numeric";
2625
2626        /**
2627         * Authentication type.
2628         * <P>Type:  INTEGER</P>
2629         */
2630        public static final String AUTH_TYPE = "authtype";
2631
2632        /**
2633         * Comma-delimited list of APN types.
2634         * <P>Type: TEXT</P>
2635         */
2636        public static final String TYPE = "type";
2637
2638        /**
2639         * The protocol to use to connect to this APN.
2640         *
2641         * One of the {@code PDP_type} values in TS 27.007 section 10.1.1.
2642         * For example: {@code IP}, {@code IPV6}, {@code IPV4V6}, or {@code PPP}.
2643         * <P>Type: TEXT</P>
2644         */
2645        public static final String PROTOCOL = "protocol";
2646
2647        /**
2648         * The protocol to use to connect to this APN when roaming.
2649         * The syntax is the same as protocol.
2650         * <P>Type: TEXT</P>
2651         */
2652        public static final String ROAMING_PROTOCOL = "roaming_protocol";
2653
2654        /**
2655         * Is this the current APN?
2656         * <P>Type: INTEGER (boolean)</P>
2657         */
2658        public static final String CURRENT = "current";
2659
2660        /**
2661         * Is this APN enabled?
2662         * <P>Type: INTEGER (boolean)</P>
2663         */
2664        public static final String CARRIER_ENABLED = "carrier_enabled";
2665
2666        /**
2667         * Radio Access Technology info.
2668         * To check what values are allowed, refer to {@link android.telephony.ServiceState}.
2669         * This should be spread to other technologies,
2670         * but is currently only used for LTE (14) and eHRPD (13).
2671         * <P>Type: INTEGER</P>
2672         */
2673        public static final String BEARER = "bearer";
2674
2675        /**
2676         * Radio Access Technology bitmask.
2677         * To check what values can be contained, refer to {@link android.telephony.ServiceState}.
2678         * 0 indicates all techs otherwise first bit refers to RAT/bearer 1, second bit refers to
2679         * RAT/bearer 2 and so on.
2680         * Bitmask for a radio tech R is (1 << (R - 1))
2681         * <P>Type: INTEGER</P>
2682         * @hide
2683         */
2684        public static final String BEARER_BITMASK = "bearer_bitmask";
2685
2686        /**
2687         * MVNO type:
2688         * {@code SPN (Service Provider Name), IMSI, GID (Group Identifier Level 1)}.
2689         * <P>Type: TEXT</P>
2690         */
2691        public static final String MVNO_TYPE = "mvno_type";
2692
2693        /**
2694         * MVNO data.
2695         * Use the following examples.
2696         * <ul>
2697         *     <li>SPN: A MOBILE, BEN NL, ...</li>
2698         *     <li>IMSI: 302720x94, 2060188, ...</li>
2699         *     <li>GID: 4E, 33, ...</li>
2700         * </ul>
2701         * <P>Type: TEXT</P>
2702         */
2703        public static final String MVNO_MATCH_DATA = "mvno_match_data";
2704
2705        /**
2706         * The subscription to which the APN belongs to
2707         * <p>Type: INTEGER (long) </p>
2708         */
2709        public static final String SUBSCRIPTION_ID = "sub_id";
2710
2711        /**
2712         * The profile_id to which the APN saved in modem
2713         * <p>Type: INTEGER</p>
2714         *@hide
2715         */
2716        public static final String PROFILE_ID = "profile_id";
2717
2718        /**
2719         * Is the apn setting to be set in modem
2720         * <P>Type: INTEGER (boolean)</P>
2721         *@hide
2722         */
2723        public static final String MODEM_COGNITIVE = "modem_cognitive";
2724
2725        /**
2726         * The max connections of this apn
2727         * <p>Type: INTEGER</p>
2728         *@hide
2729         */
2730        public static final String MAX_CONNS = "max_conns";
2731
2732        /**
2733         * The wait time for retry of the apn
2734         * <p>Type: INTEGER</p>
2735         *@hide
2736         */
2737        public static final String WAIT_TIME = "wait_time";
2738
2739        /**
2740         * The time to limit max connection for the apn
2741         * <p>Type: INTEGER</p>
2742         *@hide
2743         */
2744        public static final String MAX_CONNS_TIME = "max_conns_time";
2745
2746        /**
2747         * The MTU size of the mobile interface to  which the APN connected
2748         * <p>Type: INTEGER </p>
2749         * @hide
2750         */
2751        public static final String MTU = "mtu";
2752
2753        /**
2754         * Is this APN added/edited/deleted by a user or carrier?
2755         * <p>Type: INTEGER </p>
2756         * @hide
2757         */
2758        public static final String EDITED = "edited";
2759
2760        /**
2761         * Is this APN visible to the user?
2762         * <p>Type: INTEGER (boolean) </p>
2763         * @hide
2764         */
2765        public static final String USER_VISIBLE = "user_visible";
2766
2767        /**
2768         * Following are possible values for the EDITED field
2769         * @hide
2770         */
2771        public static final int UNEDITED = 0;
2772        /**
2773         *  @hide
2774         */
2775        public static final int USER_EDITED = 1;
2776        /**
2777         *  @hide
2778         */
2779        public static final int USER_DELETED = 2;
2780        /**
2781         * DELETED_BUT_PRESENT is an intermediate value used to indicate that an entry deleted
2782         * by the user is still present in the new APN database and therefore must remain tagged
2783         * as user deleted rather than completely removed from the database
2784         * @hide
2785         */
2786        public static final int USER_DELETED_BUT_PRESENT_IN_XML = 3;
2787        /**
2788         *  @hide
2789         */
2790        public static final int CARRIER_EDITED = 4;
2791        /**
2792         * CARRIER_DELETED values are currently not used as there is no usecase. If they are used,
2793         * delete() will have to change accordingly. Currently it is hardcoded to USER_DELETED.
2794         * @hide
2795         */
2796        public static final int CARRIER_DELETED = 5;
2797        /**
2798         *  @hide
2799         */
2800        public static final int CARRIER_DELETED_BUT_PRESENT_IN_XML = 6;
2801    }
2802
2803    /**
2804     * Contains received SMS cell broadcast messages.
2805     * @hide
2806     */
2807    public static final class CellBroadcasts implements BaseColumns {
2808
2809        /**
2810         * Not instantiable.
2811         * @hide
2812         */
2813        private CellBroadcasts() {}
2814
2815        /**
2816         * The {@code content://} URI for this table.
2817         */
2818        public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts");
2819
2820        /**
2821         * Message geographical scope.
2822         * <P>Type: INTEGER</P>
2823         */
2824        public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
2825
2826        /**
2827         * Message serial number.
2828         * <P>Type: INTEGER</P>
2829         */
2830        public static final String SERIAL_NUMBER = "serial_number";
2831
2832        /**
2833         * PLMN of broadcast sender. {@code SERIAL_NUMBER + PLMN + LAC + CID} uniquely identifies
2834         * a broadcast for duplicate detection purposes.
2835         * <P>Type: TEXT</P>
2836         */
2837        public static final String PLMN = "plmn";
2838
2839        /**
2840         * Location Area (GSM) or Service Area (UMTS) of broadcast sender. Unused for CDMA.
2841         * Only included if Geographical Scope of message is not PLMN wide (01).
2842         * <P>Type: INTEGER</P>
2843         */
2844        public static final String LAC = "lac";
2845
2846        /**
2847         * Cell ID of message sender (GSM/UMTS). Unused for CDMA. Only included when the
2848         * Geographical Scope of message is cell wide (00 or 11).
2849         * <P>Type: INTEGER</P>
2850         */
2851        public static final String CID = "cid";
2852
2853        /**
2854         * Message code. <em>OBSOLETE: merged into SERIAL_NUMBER.</em>
2855         * <P>Type: INTEGER</P>
2856         */
2857        public static final String V1_MESSAGE_CODE = "message_code";
2858
2859        /**
2860         * Message identifier. <em>OBSOLETE: renamed to SERVICE_CATEGORY.</em>
2861         * <P>Type: INTEGER</P>
2862         */
2863        public static final String V1_MESSAGE_IDENTIFIER = "message_id";
2864
2865        /**
2866         * Service category (GSM/UMTS: message identifier; CDMA: service category).
2867         * <P>Type: INTEGER</P>
2868         */
2869        public static final String SERVICE_CATEGORY = "service_category";
2870
2871        /**
2872         * Message language code.
2873         * <P>Type: TEXT</P>
2874         */
2875        public static final String LANGUAGE_CODE = "language";
2876
2877        /**
2878         * Message body.
2879         * <P>Type: TEXT</P>
2880         */
2881        public static final String MESSAGE_BODY = "body";
2882
2883        /**
2884         * Message delivery time.
2885         * <P>Type: INTEGER (long)</P>
2886         */
2887        public static final String DELIVERY_TIME = "date";
2888
2889        /**
2890         * Has the message been viewed?
2891         * <P>Type: INTEGER (boolean)</P>
2892         */
2893        public static final String MESSAGE_READ = "read";
2894
2895        /**
2896         * Message format (3GPP or 3GPP2).
2897         * <P>Type: INTEGER</P>
2898         */
2899        public static final String MESSAGE_FORMAT = "format";
2900
2901        /**
2902         * Message priority (including emergency).
2903         * <P>Type: INTEGER</P>
2904         */
2905        public static final String MESSAGE_PRIORITY = "priority";
2906
2907        /**
2908         * ETWS warning type (ETWS alerts only).
2909         * <P>Type: INTEGER</P>
2910         */
2911        public static final String ETWS_WARNING_TYPE = "etws_warning_type";
2912
2913        /**
2914         * CMAS message class (CMAS alerts only).
2915         * <P>Type: INTEGER</P>
2916         */
2917        public static final String CMAS_MESSAGE_CLASS = "cmas_message_class";
2918
2919        /**
2920         * CMAS category (CMAS alerts only).
2921         * <P>Type: INTEGER</P>
2922         */
2923        public static final String CMAS_CATEGORY = "cmas_category";
2924
2925        /**
2926         * CMAS response type (CMAS alerts only).
2927         * <P>Type: INTEGER</P>
2928         */
2929        public static final String CMAS_RESPONSE_TYPE = "cmas_response_type";
2930
2931        /**
2932         * CMAS severity (CMAS alerts only).
2933         * <P>Type: INTEGER</P>
2934         */
2935        public static final String CMAS_SEVERITY = "cmas_severity";
2936
2937        /**
2938         * CMAS urgency (CMAS alerts only).
2939         * <P>Type: INTEGER</P>
2940         */
2941        public static final String CMAS_URGENCY = "cmas_urgency";
2942
2943        /**
2944         * CMAS certainty (CMAS alerts only).
2945         * <P>Type: INTEGER</P>
2946         */
2947        public static final String CMAS_CERTAINTY = "cmas_certainty";
2948
2949        /** The default sort order for this table. */
2950        public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";
2951
2952        /**
2953         * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
2954         */
2955        public static final String[] QUERY_COLUMNS = {
2956                _ID,
2957                GEOGRAPHICAL_SCOPE,
2958                PLMN,
2959                LAC,
2960                CID,
2961                SERIAL_NUMBER,
2962                SERVICE_CATEGORY,
2963                LANGUAGE_CODE,
2964                MESSAGE_BODY,
2965                DELIVERY_TIME,
2966                MESSAGE_READ,
2967                MESSAGE_FORMAT,
2968                MESSAGE_PRIORITY,
2969                ETWS_WARNING_TYPE,
2970                CMAS_MESSAGE_CLASS,
2971                CMAS_CATEGORY,
2972                CMAS_RESPONSE_TYPE,
2973                CMAS_SEVERITY,
2974                CMAS_URGENCY,
2975                CMAS_CERTAINTY
2976        };
2977    }
2978
2979    /**
2980     * Constants for interfacing with the ServiceStateProvider and the different fields of the
2981     * {@link ServiceState} class accessible through the provider.
2982     */
2983    public static final class ServiceStateTable {
2984
2985        /**
2986         * Not instantiable.
2987         * @hide
2988         */
2989        private ServiceStateTable() {}
2990
2991        /**
2992         * The authority string for the ServiceStateProvider
2993         */
2994        public static final String AUTHORITY = "service-state";
2995
2996        /**
2997         * The {@code content://} style URL for the ServiceStateProvider
2998         */
2999        public static final Uri CONTENT_URI = Uri.parse("content://service-state/");
3000
3001        /**
3002         * Generates a content {@link Uri} used to receive updates on a specific field in the
3003         * ServiceState provider.
3004         * <p>
3005         * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
3006         * {@link ServiceState} while your app is running.  You can also use a {@link JobService} to
3007         * ensure your app is notified of changes to the {@link Uri} even when it is not running.
3008         * Note, however, that using a {@link JobService} does not guarantee timely delivery of
3009         * updates to the {@link Uri}.
3010         *
3011         * @param subId the subId to receive updates on
3012         * @param field the ServiceState field to receive updates on
3013         * @return the Uri used to observe {@link ServiceState} changes
3014         */
3015        public static Uri getUriForSubIdAndField(int subId, String field) {
3016            return CONTENT_URI.buildUpon().appendEncodedPath(String.valueOf(subId))
3017                    .appendEncodedPath(field).build();
3018        }
3019
3020        /**
3021         * Generates a content {@link Uri} used to receive updates on every field in the
3022         * ServiceState provider.
3023         * <p>
3024         * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
3025         * {@link ServiceState} while your app is running.  You can also use a {@link JobService} to
3026         * ensure your app is notified of changes to the {@link Uri} even when it is not running.
3027         * Note, however, that using a {@link JobService} does not guarantee timely delivery of
3028         * updates to the {@link Uri}.
3029         *
3030         * @param subId the subId to receive updates on
3031         * @return the Uri used to observe {@link ServiceState} changes
3032         */
3033        public static Uri getUriForSubId(int subId) {
3034            return CONTENT_URI.buildUpon().appendEncodedPath(String.valueOf(subId)).build();
3035        }
3036
3037        /**
3038         * Used to insert a ServiceState into the ServiceStateProvider as a ContentValues instance.
3039         *
3040         * @param state the ServiceState to convert into ContentValues
3041         * @return the convertedContentValues instance
3042         * @hide
3043         */
3044        public static ContentValues getContentValuesForServiceState(ServiceState state) {
3045            ContentValues values = new ContentValues();
3046            values.put(VOICE_REG_STATE, state.getVoiceRegState());
3047            values.put(DATA_REG_STATE, state.getDataRegState());
3048            values.put(VOICE_ROAMING_TYPE, state.getVoiceRoamingType());
3049            values.put(DATA_ROAMING_TYPE, state.getDataRoamingType());
3050            values.put(VOICE_OPERATOR_ALPHA_LONG, state.getVoiceOperatorAlphaLong());
3051            values.put(VOICE_OPERATOR_ALPHA_SHORT, state.getVoiceOperatorAlphaShort());
3052            values.put(VOICE_OPERATOR_NUMERIC, state.getVoiceOperatorNumeric());
3053            values.put(DATA_OPERATOR_ALPHA_LONG, state.getDataOperatorAlphaLong());
3054            values.put(DATA_OPERATOR_ALPHA_SHORT, state.getDataOperatorAlphaShort());
3055            values.put(DATA_OPERATOR_NUMERIC, state.getDataOperatorNumeric());
3056            values.put(IS_MANUAL_NETWORK_SELECTION, state.getIsManualSelection());
3057            values.put(RIL_VOICE_RADIO_TECHNOLOGY, state.getRilVoiceRadioTechnology());
3058            values.put(RIL_DATA_RADIO_TECHNOLOGY, state.getRilDataRadioTechnology());
3059            values.put(CSS_INDICATOR, state.getCssIndicator());
3060            values.put(NETWORK_ID, state.getNetworkId());
3061            values.put(SYSTEM_ID, state.getSystemId());
3062            values.put(CDMA_ROAMING_INDICATOR, state.getCdmaRoamingIndicator());
3063            values.put(CDMA_DEFAULT_ROAMING_INDICATOR, state.getCdmaDefaultRoamingIndicator());
3064            values.put(CDMA_ERI_ICON_INDEX, state.getCdmaEriIconIndex());
3065            values.put(CDMA_ERI_ICON_MODE, state.getCdmaEriIconMode());
3066            values.put(IS_EMERGENCY_ONLY, state.isEmergencyOnly());
3067            values.put(IS_DATA_ROAMING_FROM_REGISTRATION, state.getDataRoamingFromRegistration());
3068            values.put(IS_USING_CARRIER_AGGREGATION, state.isUsingCarrierAggregation());
3069            return values;
3070        }
3071
3072        /**
3073         * An integer value indicating the current voice service state.
3074         * <p>
3075         * Valid values: {@link ServiceState#STATE_IN_SERVICE},
3076         * {@link ServiceState#STATE_OUT_OF_SERVICE}, {@link ServiceState#STATE_EMERGENCY_ONLY},
3077         * {@link ServiceState#STATE_POWER_OFF}.
3078         * <p>
3079         * This is the same as {@link ServiceState#getState()}.
3080         */
3081        public static final String VOICE_REG_STATE = "voice_reg_state";
3082
3083        /**
3084         * An integer value indicating the current data service state.
3085         * <p>
3086         * Valid values: {@link ServiceState#STATE_IN_SERVICE},
3087         * {@link ServiceState#STATE_OUT_OF_SERVICE}, {@link ServiceState#STATE_EMERGENCY_ONLY},
3088         * {@link ServiceState#STATE_POWER_OFF}.
3089         * <p>
3090         * This is the same as {@link ServiceState#getDataRegState()}.
3091         * @hide
3092         */
3093        public static final String DATA_REG_STATE = "data_reg_state";
3094
3095        /**
3096         * An integer value indicating the current voice roaming type.
3097         * <p>
3098         * This is the same as {@link ServiceState#getVoiceRoamingType()}.
3099         * @hide
3100         */
3101        public static final String VOICE_ROAMING_TYPE = "voice_roaming_type";
3102
3103        /**
3104         * An integer value indicating the current data roaming type.
3105         * <p>
3106         * This is the same as {@link ServiceState#getDataRoamingType()}.
3107         * @hide
3108         */
3109        public static final String DATA_ROAMING_TYPE = "data_roaming_type";
3110
3111        /**
3112         * The current registered voice network operator name in long alphanumeric format.
3113         * <p>
3114         * This is the same as {@link ServiceState#getVoiceOperatorAlphaLong()}.
3115         * @hide
3116         */
3117        public static final String VOICE_OPERATOR_ALPHA_LONG = "voice_operator_alpha_long";
3118
3119        /**
3120         * The current registered operator name in short alphanumeric format.
3121         * <p>
3122         * In GSM/UMTS, short format can be up to 8 characters long. The current registered voice
3123         * network operator name in long alphanumeric format.
3124         * <p>
3125         * This is the same as {@link ServiceState#getVoiceOperatorAlphaShort()}.
3126         * @hide
3127         */
3128        public static final String VOICE_OPERATOR_ALPHA_SHORT = "voice_operator_alpha_short";
3129
3130
3131        /**
3132         * The current registered operator numeric id.
3133         * <p>
3134         * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
3135         * network code.
3136         * <p>
3137         * This is the same as {@link ServiceState#getOperatorNumeric()}.
3138         */
3139        public static final String VOICE_OPERATOR_NUMERIC = "voice_operator_numeric";
3140
3141        /**
3142         * The current registered data network operator name in long alphanumeric format.
3143         * <p>
3144         * This is the same as {@link ServiceState#getDataOperatorAlphaLong()}.
3145         * @hide
3146         */
3147        public static final String DATA_OPERATOR_ALPHA_LONG = "data_operator_alpha_long";
3148
3149        /**
3150         * The current registered data network operator name in short alphanumeric format.
3151         * <p>
3152         * This is the same as {@link ServiceState#getDataOperatorAlphaShort()}.
3153         * @hide
3154         */
3155        public static final String DATA_OPERATOR_ALPHA_SHORT = "data_operator_alpha_short";
3156
3157        /**
3158         * The current registered data network operator numeric id.
3159         * <p>
3160         * This is the same as {@link ServiceState#getDataOperatorNumeric()}.
3161         * @hide
3162         */
3163        public static final String DATA_OPERATOR_NUMERIC = "data_operator_numeric";
3164
3165        /**
3166         * The current network selection mode.
3167         * <p>
3168         * This is the same as {@link ServiceState#getIsManualSelection()}.
3169         */
3170        public static final String IS_MANUAL_NETWORK_SELECTION = "is_manual_network_selection";
3171
3172        /**
3173         * This is the same as {@link ServiceState#getRilVoiceRadioTechnology()}.
3174         * @hide
3175         */
3176        public static final String RIL_VOICE_RADIO_TECHNOLOGY = "ril_voice_radio_technology";
3177
3178        /**
3179         * This is the same as {@link ServiceState#getRilDataRadioTechnology()}.
3180         * @hide
3181         */
3182        public static final String RIL_DATA_RADIO_TECHNOLOGY = "ril_data_radio_technology";
3183
3184        /**
3185         * This is the same as {@link ServiceState#getCssIndicator()}.
3186         * @hide
3187         */
3188        public static final String CSS_INDICATOR = "css_indicator";
3189
3190        /**
3191         * This is the same as {@link ServiceState#getNetworkId()}.
3192         * @hide
3193         */
3194        public static final String NETWORK_ID = "network_id";
3195
3196        /**
3197         * This is the same as {@link ServiceState#getSystemId()}.
3198         * @hide
3199         */
3200        public static final String SYSTEM_ID = "system_id";
3201
3202        /**
3203         * This is the same as {@link ServiceState#getCdmaRoamingIndicator()}.
3204         * @hide
3205         */
3206        public static final String CDMA_ROAMING_INDICATOR = "cdma_roaming_indicator";
3207
3208        /**
3209         * This is the same as {@link ServiceState#getCdmaDefaultRoamingIndicator()}.
3210         * @hide
3211         */
3212        public static final String CDMA_DEFAULT_ROAMING_INDICATOR =
3213                "cdma_default_roaming_indicator";
3214
3215        /**
3216         * This is the same as {@link ServiceState#getCdmaEriIconIndex()}.
3217         * @hide
3218         */
3219        public static final String CDMA_ERI_ICON_INDEX = "cdma_eri_icon_index";
3220
3221        /**
3222         * This is the same as {@link ServiceState#getCdmaEriIconMode()}.
3223         * @hide
3224         */
3225        public static final String CDMA_ERI_ICON_MODE = "cdma_eri_icon_mode";
3226
3227        /**
3228         * This is the same as {@link ServiceState#isEmergencyOnly()}.
3229         * @hide
3230         */
3231        public static final String IS_EMERGENCY_ONLY = "is_emergency_only";
3232
3233        /**
3234         * This is the same as {@link ServiceState#getDataRoamingFromRegistration()}.
3235         * @hide
3236         */
3237        public static final String IS_DATA_ROAMING_FROM_REGISTRATION =
3238                "is_data_roaming_from_registration";
3239
3240        /**
3241         * This is the same as {@link ServiceState#isUsingCarrierAggregation()}.
3242         * @hide
3243         */
3244        public static final String IS_USING_CARRIER_AGGREGATION = "is_using_carrier_aggregation";
3245    }
3246}
3247