Home | History | Annotate | Download | only in provider
      1 /*
      2  * Copyright (C) 2011 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.Manifest;
     20 import android.annotation.SdkConstant;
     21 import android.annotation.SdkConstant.SdkConstantType;
     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.ContentObserver;
     28 import android.net.Uri;
     29 import android.provider.CallLog.Calls;
     30 import android.telecom.PhoneAccount;
     31 import android.telecom.PhoneAccountHandle;
     32 import android.telecom.Voicemail;
     33 import java.util.List;
     34 
     35 /**
     36  * The contract between the voicemail provider and applications. Contains
     37  * definitions for the supported URIs and columns.
     38  *
     39  * <P>The content providers exposes two tables through this interface:
     40  * <ul>
     41  *   <li> Voicemails table: This stores the actual voicemail records. The
     42  *   columns and URIs for accessing this table are defined by the
     43  *   {@link Voicemails} class.
     44  *   </li>
     45  *   <li> Status table: This provides a way for the voicemail source application
     46  *   to convey its current state to the system. The columns and URIS for
     47  *   accessing this table are defined by the {@link Status} class.
     48  *   </li>
     49  * </ul>
     50  *
     51  * <P> The minimum permission needed to access this content provider is
     52  * {@link Manifest.permission#ADD_VOICEMAIL}
     53  *
     54  * <P>Voicemails are inserted by what is called as a "voicemail source"
     55  * application, which is responsible for syncing voicemail data between a remote
     56  * server and the local voicemail content provider. "voicemail source"
     57  * application should always set the {@link #PARAM_KEY_SOURCE_PACKAGE} in the
     58  * URI to identify its package.
     59  *
     60  * <P>In addition to the {@link ContentObserver} notifications the voicemail
     61  * provider also generates broadcast intents to notify change for applications
     62  * that are not active and therefore cannot listen to ContentObserver
     63  * notifications. Broadcast intents with following actions are generated:
     64  * <ul>
     65  *   <li> {@link #ACTION_NEW_VOICEMAIL} is generated for each new voicemail
     66  *   inserted.
     67  *   </li>
     68  *   <li> {@link Intent#ACTION_PROVIDER_CHANGED} is generated for any change
     69  *    made into the database, including new voicemail.
     70  *   </li>
     71  * </ul>
     72  */
     73 public class VoicemailContract {
     74     /** Not instantiable. */
     75     private VoicemailContract() {
     76     }
     77 
     78     /** The authority used by the voicemail provider. */
     79     public static final String AUTHORITY = "com.android.voicemail";
     80     /**
     81      * Parameter key used in the URI to specify the voicemail source package name.
     82      * <p> This field must be set in all requests that originate from a voicemail source.
     83      */
     84     public static final String PARAM_KEY_SOURCE_PACKAGE = "source_package";
     85 
     86     /** Broadcast intent when a new voicemail record is inserted. */
     87     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     88     public static final String ACTION_NEW_VOICEMAIL = "android.intent.action.NEW_VOICEMAIL";
     89 
     90     /**
     91      * Broadcast intent to request a voicemail source to fetch voicemail content of a specific
     92      * voicemail from the remote server. The voicemail to fetch is specified by the data uri
     93      * of the intent.
     94      * <p>
     95      * All voicemail sources are expected to handle this event. After storing the content
     96      * the application should also set {@link Voicemails#HAS_CONTENT} to 1;
     97      */
     98     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     99     public static final String ACTION_FETCH_VOICEMAIL = "android.intent.action.FETCH_VOICEMAIL";
    100 
    101     /**
    102      * Broadcast intent to request all voicemail sources to perform a sync with the remote server.
    103      */
    104     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    105     public static final String ACTION_SYNC_VOICEMAIL = "android.provider.action.SYNC_VOICEMAIL";
    106 
    107     /**
    108      * Broadcast intent to inform a new visual voicemail SMS has been received. This intent will
    109      * only be delivered to the voicemail client. The intent will have the following extra values:
    110      *
    111      * <ul>
    112      *   <li><em>{@link #EXTRA_VOICEMAIL_SMS_TYPE}</em> - (String) The event type of the SMS. Common
    113      *   values are "SYNC" or "STATUS"</li>
    114      *   <li><em>{@link #EXTRA_VOICEMAIL_SMS_DATA}</em> - (Bundle) The fields sent by the SMS</li>
    115      *   <li><em>{@link #EXTRA_VOICEMAIL_SMS_SUBID}</em> - (Integer) The subscription ID of the
    116      *   phone account that received the SMS</li>
    117      * </ul>
    118      */
    119     /** @hide */
    120     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    121     public static final String ACTION_VOICEMAIL_SMS_RECEIVED =
    122             "android.intent.action.VOICEMAIL_SMS_RECEIVED";
    123 
    124     /**
    125      * Optional extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to
    126      * indicate the event type of the SMS. Common values are "SYNC" or "STATUS". The extra will not
    127      * exist if the framework cannot parse the SMS as voicemail but the carrier pattern indicates
    128      * it is.
    129      */
    130     /** @hide */
    131     public static final String EXTRA_VOICEMAIL_SMS_PREFIX =
    132             "com.android.voicemail.extra.VOICEMAIL_SMS_PREFIX";
    133 
    134     /**
    135      * Optional extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to
    136      * indicate the fields sent by the SMS. The extra will not exist if the framework cannot
    137      * parse the SMS as voicemail but the carrier pattern indicates it is.
    138      */
    139     /** @hide */
    140     public static final String EXTRA_VOICEMAIL_SMS_FIELDS =
    141             "com.android.voicemail.extra.VOICEMAIL_SMS_FIELDS";
    142 
    143     /**
    144      * Extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to indicate the
    145      * message body of the SMS. This extra is included if the framework cannot
    146      * parse the SMS as voicemail but the carrier pattern indicates it is.
    147      */
    148     /**
    149      * @hide
    150      */
    151     public static final String EXTRA_VOICEMAIL_SMS_MESSAGE_BODY =
    152         "com.android.voicemail.extra.VOICEMAIL_SMS_MESSAGE_BODY";
    153 
    154     /**
    155      * Extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to indicate he
    156      * subscription ID of the phone account that received the SMS.
    157      */
    158     /** @hide */
    159     public static final String EXTRA_VOICEMAIL_SMS_SUBID =
    160             "com.android.voicemail.extra.VOICEMAIL_SMS_SUBID";
    161 
    162     /**
    163      * Extra included in {@link Intent#ACTION_PROVIDER_CHANGED} broadcast intents to indicate if the
    164      * receiving package made this change.
    165      */
    166     public static final String EXTRA_SELF_CHANGE = "com.android.voicemail.extra.SELF_CHANGE";
    167 
    168     /**
    169      * Extra included in {@link #ACTION_SYNC_VOICEMAIL} broadcast intents to indicate which {@link
    170      * PhoneAccountHandle} to sync.
    171      */
    172     public static final String EXTRA_PHONE_ACCOUNT_HANDLE =
    173             "android.provider.extra.PHONE_ACCOUNT_HANDLE";
    174 
    175     /**
    176      * Name of the source package field, which must be same across all voicemail related tables.
    177      * This is an internal field.
    178      * @hide
    179      */
    180     public static final String SOURCE_PACKAGE_FIELD = "source_package";
    181 
    182     /** Defines fields exposed through the /voicemail path of this content provider. */
    183     public static final class Voicemails implements BaseColumns, OpenableColumns {
    184         /** Not instantiable. */
    185         private Voicemails() {
    186         }
    187 
    188         /** URI to insert/retrieve voicemails. */
    189         public static final Uri CONTENT_URI =
    190             Uri.parse("content://" + AUTHORITY + "/voicemail");
    191 
    192         /** The MIME type for a collection of voicemails. */
    193         public static final String DIR_TYPE = "vnd.android.cursor.dir/voicemails";
    194 
    195         /** The MIME type for a single voicemail. */
    196         public static final String ITEM_TYPE = "vnd.android.cursor.item/voicemail";
    197 
    198         /**
    199          * Phone number of the voicemail sender.
    200          * <P>Type: TEXT</P>
    201          */
    202         public static final String NUMBER = Calls.NUMBER;
    203         /**
    204          * The date the voicemail was sent, in milliseconds since the epoch
    205          * <P>Type: INTEGER (long)</P>
    206          */
    207         public static final String DATE = Calls.DATE;
    208         /**
    209          * The duration of the voicemail in seconds.
    210          * <P>Type: INTEGER (long)</P>
    211          */
    212         public static final String DURATION = Calls.DURATION;
    213         /**
    214          * Whether this item has been read or otherwise consumed by the user.
    215          * <P>Type: INTEGER (boolean)</P>
    216          */
    217         public static final String IS_READ = Calls.IS_READ;
    218         /**
    219          * The mail box state of the voicemail. This field is currently not used by the system.
    220          * <P> Possible values: {@link #STATE_INBOX}, {@link #STATE_DELETED},
    221          * {@link #STATE_UNDELETED}.
    222          * <P>Type: INTEGER</P>
    223          * @hide
    224          */
    225         public static final String STATE = "state";
    226         /**
    227          * Value of {@link #STATE} when the voicemail is in inbox.
    228          * @hide
    229          */
    230         public static int STATE_INBOX = 0;
    231         /**
    232          * Value of {@link #STATE} when the voicemail has been marked as deleted.
    233          * @hide
    234          */
    235         public static int STATE_DELETED = 1;
    236         /**
    237          * Value of {@link #STATE} when the voicemail has marked as undeleted.
    238          * @hide
    239          */
    240         public static int STATE_UNDELETED = 2;
    241         /**
    242          * Package name of the source application that inserted the voicemail.
    243          * <P>Type: TEXT</P>
    244          */
    245         public static final String SOURCE_PACKAGE = SOURCE_PACKAGE_FIELD;
    246         /**
    247          * Application-specific data available to the source application that
    248          * inserted the voicemail. This is typically used to store the source
    249          * specific message id to identify this voicemail on the remote
    250          * voicemail server.
    251          * <P>Type: TEXT</P>
    252          * <P> Note that this is NOT the voicemail media content data.
    253          */
    254         public static final String SOURCE_DATA = "source_data";
    255         /**
    256          * Whether the media content for this voicemail is available for
    257          * consumption.
    258          * <P>Type: INTEGER (boolean)</P>
    259          */
    260         public static final String HAS_CONTENT = "has_content";
    261         /**
    262          * MIME type of the media content for the voicemail.
    263          * <P>Type: TEXT</P>
    264          */
    265         public static final String MIME_TYPE = "mime_type";
    266         /**
    267          * The transcription of the voicemail entry. This will only be populated if the voicemail
    268          * entry has a valid transcription.
    269          * <P>Type: TEXT</P>
    270          */
    271         public static final String TRANSCRIPTION = "transcription";
    272         /**
    273          * Path to the media content file. Internal only field.
    274          * @hide
    275          */
    276         public static final String _DATA = "_data";
    277 
    278         // Note: PHONE_ACCOUNT_* constant values are "subscription_*" due to a historic naming
    279         // that was encoded into call log databases.
    280 
    281         /**
    282          * The {@link ComponentName} of the {@link PhoneAccount} in string form. The
    283          * {@link PhoneAccount} of the voicemail is used to differentiate voicemails from different
    284          * sources.
    285          * <P>Type: TEXT</P>
    286          */
    287         public static final String PHONE_ACCOUNT_COMPONENT_NAME = "subscription_component_name";
    288 
    289         /**
    290          * The identifier of a {@link PhoneAccount} that is unique to a specified
    291          * {@link ComponentName}. The {@link PhoneAccount} of the voicemail is used to differentiate
    292          * voicemails from different sources.
    293          * <P>Type: TEXT</P>
    294          */
    295         public static final String PHONE_ACCOUNT_ID = "subscription_id";
    296 
    297         /**
    298          * Flag used to indicate that local, unsynced changes are present.
    299          * Currently, this is used to indicate that the voicemail was read or deleted.
    300          * The value will be 1 if dirty is true, 0 if false.
    301          * <P>Type: INTEGER (boolean)</P>
    302          */
    303         public static final String DIRTY = "dirty";
    304 
    305         /**
    306          * Flag used to indicate that the voicemail was deleted but not synced to the server.
    307          * A deleted row should be ignored.
    308          * The value will be 1 if deleted is true, 0 if false.
    309          * <P>Type: INTEGER (boolean)</P>
    310          */
    311         public static final String DELETED = "deleted";
    312 
    313         /**
    314          * The date the row is last inserted, updated, or marked as deleted, in milliseconds
    315          * since the epoch. Read only.
    316          * <P>Type: INTEGER (long)</P>
    317          */
    318         public static final String LAST_MODIFIED = "last_modified";
    319 
    320         /**
    321          * A convenience method to build voicemail URI specific to a source package by appending
    322          * {@link VoicemailContract#PARAM_KEY_SOURCE_PACKAGE} param to the base URI.
    323          */
    324         public static Uri buildSourceUri(String packageName) {
    325             return Voicemails.CONTENT_URI.buildUpon()
    326                     .appendQueryParameter(PARAM_KEY_SOURCE_PACKAGE, packageName)
    327                     .build();
    328         }
    329 
    330         /**
    331          * Inserts a new voicemail into the voicemail content provider.
    332          *
    333          * @param context The context of the app doing the inserting
    334          * @param voicemail Data to be inserted
    335          * @return {@link Uri} of the newly inserted {@link Voicemail}
    336          *
    337          * @hide
    338          */
    339         public static Uri insert(Context context, Voicemail voicemail) {
    340             ContentResolver contentResolver = context.getContentResolver();
    341             ContentValues contentValues = getContentValues(voicemail);
    342             return contentResolver.insert(buildSourceUri(context.getPackageName()), contentValues);
    343         }
    344 
    345         /**
    346          * Inserts a list of voicemails into the voicemail content provider.
    347          *
    348          * @param context The context of the app doing the inserting
    349          * @param voicemails Data to be inserted
    350          * @return the number of voicemails inserted
    351          *
    352          * @hide
    353          */
    354         public static int insert(Context context, List<Voicemail> voicemails) {
    355             ContentResolver contentResolver = context.getContentResolver();
    356             int count = voicemails.size();
    357             for (int i = 0; i < count; i++) {
    358                 ContentValues contentValues = getContentValues(voicemails.get(i));
    359                 contentResolver.insert(buildSourceUri(context.getPackageName()), contentValues);
    360             }
    361             return count;
    362         }
    363 
    364         /**
    365          * Clears all voicemails accessible to this voicemail content provider for the calling
    366          * package. By default, a package only has permission to delete voicemails it inserted.
    367          *
    368          * @return the number of voicemails deleted
    369          *
    370          * @hide
    371          */
    372         public static int deleteAll(Context context) {
    373             return context.getContentResolver().delete(
    374                     buildSourceUri(context.getPackageName()), "", new String[0]);
    375         }
    376 
    377         /**
    378          * Maps structured {@link Voicemail} to {@link ContentValues} in content provider.
    379          */
    380         private static ContentValues getContentValues(Voicemail voicemail) {
    381             ContentValues contentValues = new ContentValues();
    382             contentValues.put(Voicemails.DATE, String.valueOf(voicemail.getTimestampMillis()));
    383             contentValues.put(Voicemails.NUMBER, voicemail.getNumber());
    384             contentValues.put(Voicemails.DURATION, String.valueOf(voicemail.getDuration()));
    385             contentValues.put(Voicemails.SOURCE_PACKAGE, voicemail.getSourcePackage());
    386             contentValues.put(Voicemails.SOURCE_DATA, voicemail.getSourceData());
    387             contentValues.put(Voicemails.IS_READ, voicemail.isRead() ? 1 : 0);
    388 
    389             PhoneAccountHandle phoneAccount = voicemail.getPhoneAccount();
    390             if (phoneAccount != null) {
    391                 contentValues.put(Voicemails.PHONE_ACCOUNT_COMPONENT_NAME,
    392                         phoneAccount.getComponentName().flattenToString());
    393                 contentValues.put(Voicemails.PHONE_ACCOUNT_ID, phoneAccount.getId());
    394             }
    395 
    396             if (voicemail.getTranscription() != null) {
    397                 contentValues.put(Voicemails.TRANSCRIPTION, voicemail.getTranscription());
    398             }
    399 
    400             return contentValues;
    401         }
    402     }
    403 
    404     /** Defines fields exposed through the /status path of this content provider. */
    405     public static final class Status implements BaseColumns {
    406         /** URI to insert/retrieve status of voicemail source. */
    407         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/status");
    408         /** The MIME type for a collection of voicemail source statuses. */
    409         public static final String DIR_TYPE = "vnd.android.cursor.dir/voicemail.source.status";
    410         /** The MIME type for a single voicemail source status entry. */
    411         public static final String ITEM_TYPE = "vnd.android.cursor.item/voicemail.source.status";
    412 
    413         /** Not instantiable. */
    414         private Status() {
    415         }
    416         /**
    417          * The package name of the voicemail source. There can only be a one entry per account
    418          * per source.
    419          * <P>Type: TEXT</P>
    420          */
    421         public static final String SOURCE_PACKAGE = SOURCE_PACKAGE_FIELD;
    422 
    423         /**
    424          * The type of the source, which determines how to interpret source-specific states.
    425          * Typically this will be set to the same string as
    426          * {@link android.telephony.CarrierConfigManager#KEY_VVM_TYPE_STRING}. For example,
    427          * "vvm_type_omtp".
    428          *
    429          * <P>Type: TEXT</P>
    430          *
    431          * @see #CONFIGURATION_STATE
    432          * @see #DATA_CHANNEL_STATE
    433          * @see #NOTIFICATION_CHANNEL_STATE
    434          */
    435         public static final String SOURCE_TYPE = "source_type";
    436 
    437         // Note: Multiple entries may exist for a single source if they are differentiated by the
    438         // PHONE_ACCOUNT_* fields.
    439 
    440         /**
    441          * The {@link ComponentName} of the {@link PhoneAccount} in string form. The
    442          * {@link PhoneAccount} differentiates voicemail sources from the same package.
    443          * <P>Type: TEXT</P>
    444          */
    445         public static final String PHONE_ACCOUNT_COMPONENT_NAME = "phone_account_component_name";
    446 
    447         /**
    448          * The identifier of a {@link PhoneAccount} that is unique to a specified component. The
    449          * {@link PhoneAccount} differentiates voicemail sources from the same package.
    450          * <P>Type: TEXT</P>
    451          */
    452         public static final String PHONE_ACCOUNT_ID = "phone_account_id";
    453 
    454         /**
    455          * The URI to call to invoke source specific voicemail settings screen. On a user request
    456          * to setup voicemail an intent with action VIEW with this URI will be fired by the system.
    457          * <P>Type: TEXT</P>
    458          */
    459         public static final String SETTINGS_URI = "settings_uri";
    460         /**
    461          * The URI to call when the user requests to directly access the voicemail from the remote
    462          * server. In case of an IVR voicemail system this is typically set to the the voicemail
    463          * number specified using a tel:/ URI.
    464          * <P>Type: TEXT</P>
    465          */
    466         public static final String VOICEMAIL_ACCESS_URI = "voicemail_access_uri";
    467         /**
    468          * The configuration state of the voicemail source.
    469          *
    470          * <P>Negative values are reserved to the source for source-specific states, see
    471          * {@link #SOURCE_TYPE}
    472          *
    473          * <P> Possible values:
    474          * {@link #CONFIGURATION_STATE_OK},
    475          * {@link #CONFIGURATION_STATE_NOT_CONFIGURED},
    476          * {@link #CONFIGURATION_STATE_CAN_BE_CONFIGURED}
    477          * {@link #CONFIGURATION_STATE_CONFIGURING}
    478          * {@link #CONFIGURATION_STATE_FAILED}
    479          * {@link #CONFIGURATION_STATE_DISABLED}
    480          * <P>Type: INTEGER</P>
    481          */
    482         public static final String CONFIGURATION_STATE = "configuration_state";
    483 
    484         /** Value of {@link #CONFIGURATION_STATE} to indicate an all OK configuration status. */
    485         public static final int CONFIGURATION_STATE_OK = 0;
    486         /**
    487          * Value of {@link #CONFIGURATION_STATE} to indicate the visual voicemail is not
    488          * yet configured on this device.
    489          */
    490         public static final int CONFIGURATION_STATE_NOT_CONFIGURED = 1;
    491         /**
    492          * Value of {@link #CONFIGURATION_STATE} to indicate the visual voicemail is not
    493          * yet configured on this device but can be configured by the user.
    494          * <p> This state must be used when the source has verified that the current user can be
    495          * upgraded to visual voicemail and would like to show a set up invitation message.
    496          */
    497         public static final int CONFIGURATION_STATE_CAN_BE_CONFIGURED = 2;
    498         /**
    499          * Value of {@link #CONFIGURATION_STATE} to indicate that visual voicemail still is being
    500          * configured.
    501          */
    502         public static final int CONFIGURATION_STATE_CONFIGURING = 3;
    503         /**
    504          * Value of {@link #CONFIGURATION_STATE} to indicate that visual voicemail has failed to
    505          * be configured.
    506          */
    507         public static final int CONFIGURATION_STATE_FAILED = 4;
    508         /**
    509          * Value of {@link #CONFIGURATION_STATE} to indicate that visual voicemail is disabled by
    510          * the user.
    511          */
    512         public static final int CONFIGURATION_STATE_DISABLED = 5;
    513         /**
    514          * The data channel state of the voicemail source. This the channel through which the source
    515          * pulls voicemail data from a remote server.
    516          *
    517          * <P>Negative values are reserved to the source for source-specific states, see
    518          * {@link #SOURCE_TYPE}
    519          *
    520          * <P> Possible values:
    521          * {@link #DATA_CHANNEL_STATE_OK},
    522          * {@link #DATA_CHANNEL_STATE_NO_CONNECTION}
    523          * </P>
    524          * <P>Type: INTEGER</P>
    525          */
    526         public static final String DATA_CHANNEL_STATE = "data_channel_state";
    527 
    528         /**
    529          *  Value of {@link #DATA_CHANNEL_STATE} to indicate that data channel is working fine.
    530          */
    531         public static final int DATA_CHANNEL_STATE_OK = 0;
    532         /**
    533          *  Value of {@link #DATA_CHANNEL_STATE} to indicate that data channel failed to find a
    534          *  suitable network to connect to the server.
    535          */
    536         public static final int DATA_CHANNEL_STATE_NO_CONNECTION = 1;
    537         /**
    538          *  Value of {@link #DATA_CHANNEL_STATE} to indicate that data channel failed to find a
    539          *  suitable network to connect to the server, and the carrier requires using cellular
    540          *  data network to connect to the server.
    541          */
    542         public static final int DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED = 2;
    543         /**
    544          *  Value of {@link #DATA_CHANNEL_STATE} to indicate that data channel received incorrect
    545          *  settings or credentials to connect to the server
    546          */
    547         public static final int DATA_CHANNEL_STATE_BAD_CONFIGURATION = 3;
    548         /**
    549          *  Value of {@link #DATA_CHANNEL_STATE} to indicate that a error has occurred in the data
    550          *  channel while communicating with the server
    551          */
    552         public static final int DATA_CHANNEL_STATE_COMMUNICATION_ERROR = 4;
    553         /**
    554          *  Value of {@link #DATA_CHANNEL_STATE} to indicate that the server reported an internal
    555          *  error to the data channel.
    556          */
    557         public static final int DATA_CHANNEL_STATE_SERVER_ERROR = 5;
    558         /**
    559          *  Value of {@link #DATA_CHANNEL_STATE} to indicate that while there is a suitable network,
    560          *  the data channel is unable to establish a connection with the server.
    561          */
    562         public static final int DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR = 6;
    563 
    564         /**
    565          * The notification channel state of the voicemail source. This is the channel through which
    566          * the source gets notified of new voicemails on the remote server.
    567          *
    568          * <P>Negative values are reserved to the source for source-specific states, see
    569          * {@link #SOURCE_TYPE}
    570          *
    571          * <P> Possible values:
    572          * {@link #NOTIFICATION_CHANNEL_STATE_OK},
    573          * {@link #NOTIFICATION_CHANNEL_STATE_NO_CONNECTION},
    574          * {@link #NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING}
    575          * </P>
    576          * <P>Type: INTEGER</P>
    577          */
    578         public static final String NOTIFICATION_CHANNEL_STATE = "notification_channel_state";
    579 
    580         /**
    581          * Value of {@link #NOTIFICATION_CHANNEL_STATE} to indicate that the notification channel is
    582          * working fine.
    583          */
    584         public static final int NOTIFICATION_CHANNEL_STATE_OK = 0;
    585         /**
    586          * Value of {@link #NOTIFICATION_CHANNEL_STATE} to indicate that the notification channel
    587          * connection is not working.
    588          */
    589         public static final int NOTIFICATION_CHANNEL_STATE_NO_CONNECTION = 1;
    590         /**
    591          * Value of {@link #NOTIFICATION_CHANNEL_STATE} to indicate that there are messages waiting
    592          * on the server but the details are not known.
    593          * <p> Use this state when the notification can only tell that there are pending messages on
    594          * the server but no details of the sender/time etc are known.
    595          */
    596         public static final int NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING = 2;
    597 
    598         /**
    599          * Amount of resource that is used by existing voicemail in the visual voicemail inbox,
    600          * or {@link #QUOTA_UNAVAILABLE} if the quota has never been updated before. This value is
    601          * used to inform the client the situation on the remote server. Unit is not specified.
    602          * <P>Type: INTEGER</P>
    603          */
    604         public static final String QUOTA_OCCUPIED = "quota_occupied";
    605 
    606         /**
    607          * Total resource in the visual voicemail inbox that can be used, or
    608          * {@link #QUOTA_UNAVAILABLE} if server either has unlimited quota or does not provide quota
    609          * information. This value is used to inform the client the situation on the remote server.
    610          * Unit is not specified.
    611          * <P>Type: INTEGER</P>
    612          */
    613         public static final String QUOTA_TOTAL = "quota_total";
    614 
    615         /**
    616          * Value for {@link #QUOTA_OCCUPIED} and {@link #QUOTA_TOTAL} to indicate that no
    617          * information is available.
    618          */
    619         public static final int QUOTA_UNAVAILABLE = -1;
    620 
    621         /**
    622          * A convenience method to build status URI specific to a source package by appending
    623          * {@link VoicemailContract#PARAM_KEY_SOURCE_PACKAGE} param to the base URI.
    624          */
    625         public static Uri buildSourceUri(String packageName) {
    626             return Status.CONTENT_URI.buildUpon()
    627                     .appendQueryParameter(PARAM_KEY_SOURCE_PACKAGE, packageName).build();
    628         }
    629     }
    630 }
    631