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