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 
17 package android.provider;
18 
19 import android.annotation.SdkConstant;
20 import android.annotation.SdkConstant.SdkConstantType;
21 import android.annotation.TestApi;
22 import android.app.job.JobService;
23 import android.content.ComponentName;
24 import android.content.ContentResolver;
25 import android.content.ContentValues;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.database.Cursor;
29 import android.database.ContentObserver;
30 import android.database.sqlite.SqliteWrapper;
31 import android.net.Uri;
32 import android.telephony.Rlog;
33 import android.telephony.ServiceState;
34 import android.telephony.SmsMessage;
35 import android.telephony.SubscriptionManager;
36 import android.text.TextUtils;
37 import android.util.Patterns;
38 
39 import com.android.internal.telephony.PhoneConstants;
40 import com.android.internal.telephony.SmsApplication;
41 
42 
43 import java.util.HashSet;
44 import java.util.Set;
45 import java.util.regex.Matcher;
46 import 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  */
110 public final class Telephony {
111     private static final String TAG = "Telephony";
112 
113     /**
114      * Not instantiable.
115      * @hide
116      */
Telephony()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          */
Sms()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          */
getDefaultSmsPackage(Context context)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          */
query(ContentResolver cr, String[] projection)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          */
query(ContentResolver cr, String[] projection, String where, String orderBy)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          */
addMessageToUri(ContentResolver resolver, Uri uri, String address, String body, String subject, Long date, boolean read, boolean deliveryReport)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          */
addMessageToUri(int subId, ContentResolver resolver, Uri uri, String address, String body, String subject, Long date, boolean read, boolean deliveryReport)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          */
addMessageToUri(ContentResolver resolver, Uri uri, String address, String body, String subject, Long date, boolean read, boolean deliveryReport, long threadId)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          */
addMessageToUri(int subId, ContentResolver resolver, Uri uri, String address, String body, String subject, Long date, boolean read, boolean deliveryReport, long threadId)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          */
moveMessageToFolder(Context context, Uri uri, int folder, int error)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          */
isOutgoingFolder(int messageType)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              */
Inbox()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              */
addMessage(ContentResolver resolver, String address, String body, String subject, Long date, boolean read)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              */
addMessage(int subId, ContentResolver resolver, String address, String body, String subject, Long date, boolean read)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              */
Sent()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              */
addMessage(ContentResolver resolver, String address, String body, String subject, Long date)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              */
addMessage(int subId, ContentResolver resolver, String address, String body, String subject, Long date)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              */
Draft()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             */
addMessage(ContentResolver resolver, String address, String body, String subject, Long date)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              */
addMessage(int subId, ContentResolver resolver, String address, String body, String subject, Long date)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              */
Outbox()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              */
addMessage(ContentResolver resolver, String address, String body, String subject, Long date, boolean deliveryReport, long threadId)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              */
addMessage(int subId, ContentResolver resolver, String address, String body, String subject, Long date, boolean deliveryReport, long threadId)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              */
Conversations()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              */
Intents()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              */
getMessagesFromIntent(Intent intent)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          */
Threads()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          */
getOrCreateThreadId(Context context, String recipient)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          */
getOrCreateThreadId( Context context, Set<String> recipients)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          */
Mms()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          */
query( ContentResolver cr, String[] projection)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          */
query( ContentResolver cr, String[] projection, String where, String orderBy)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          */
extractAddrSpec(String address)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          */
isEmailAddress(String address)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          */
isPhoneNumber(String number)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              */
Inbox()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              */
Sent()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              */
Draft()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              */
Outbox()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              */
Addr()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              */
Part()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              */
Rate()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              */
Intents()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          */
MmsSms()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              */
PendingMessages()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              */
WordsTable()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          */
Carriers()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          */
CellBroadcasts()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          */
ServiceStateTable()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 subscriptionId the subscriptionId 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          */
getUriForSubscriptionIdAndField(int subscriptionId, String field)3015         public static Uri getUriForSubscriptionIdAndField(int subscriptionId, String field) {
3016             return CONTENT_URI.buildUpon().appendEncodedPath(String.valueOf(subscriptionId))
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 subscriptionId the subscriptionId to receive updates on
3031          * @return the Uri used to observe {@link ServiceState} changes
3032          */
getUriForSubscriptionId(int subscriptionId)3033         public static Uri getUriForSubscriptionId(int subscriptionId) {
3034             return CONTENT_URI.buildUpon().appendEncodedPath(String.valueOf(subscriptionId)).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          */
getContentValuesForServiceState(ServiceState state)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