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