Home | History | Annotate | Download | only in telecom
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
      5  * in compliance with the License. You may obtain a copy of the License at
      6  *
      7  * http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software distributed under the License
     10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
     11  * or implied. See the License for the specific language governing permissions and limitations under
     12  * the License.
     13  */
     14 
     15 package android.telecom;
     16 
     17 import android.annotation.SystemApi;
     18 import android.content.ComponentName;
     19 import android.content.Context;
     20 import android.net.Uri;
     21 import android.os.Bundle;
     22 import android.os.RemoteException;
     23 import android.os.ServiceManager;
     24 import android.telephony.TelephonyManager;
     25 import android.text.TextUtils;
     26 import android.util.Log;
     27 
     28 import com.android.internal.telecom.ITelecomService;
     29 
     30 import java.util.ArrayList;
     31 import java.util.Collections;
     32 import java.util.List;
     33 
     34 /**
     35  * Provides access to information about active calls and registration/call-management functionality.
     36  * Apps can use methods in this class to determine the current call state.
     37  * <p>
     38  * Apps do not instantiate this class directly; instead, they retrieve a reference to an instance
     39  * through {@link Context#getSystemService Context.getSystemService(Context.TELECOM_SERVICE)}.
     40  * <p>
     41  * Note that access to some telecom information is permission-protected. Your app cannot access the
     42  * protected information or gain access to protected functionality unless it has the appropriate
     43  * permissions declared in its manifest file. Where permissions apply, they are noted in the method
     44  * descriptions.
     45  */
     46 public class TelecomManager {
     47 
     48     /**
     49      * Activity action: Starts the UI for handing an incoming call. This intent starts the in-call
     50      * UI by notifying the Telecom system that an incoming call exists for a specific call service
     51      * (see {@link android.telecom.ConnectionService}). Telecom reads the Intent extras to find
     52      * and bind to the appropriate {@link android.telecom.ConnectionService} which Telecom will
     53      * ultimately use to control and get information about the call.
     54      * <p>
     55      * Input: get*Extra field {@link #EXTRA_PHONE_ACCOUNT_HANDLE} contains the component name of the
     56      * {@link android.telecom.ConnectionService} that Telecom should bind to. Telecom will then
     57      * ask the connection service for more information about the call prior to showing any UI.
     58      *
     59      * @hide
     60      */
     61     public static final String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
     62 
     63     /**
     64      * Similar to {@link #ACTION_INCOMING_CALL}, but is used only by Telephony to add a new
     65      * sim-initiated MO call for carrier testing.
     66      * @hide
     67      */
     68     public static final String ACTION_NEW_UNKNOWN_CALL = "android.telecom.action.NEW_UNKNOWN_CALL";
     69 
     70     /**
     71      * The {@link android.content.Intent} action used to configure a
     72      * {@link android.telecom.ConnectionService}.
     73      * @hide
     74      */
     75     @SystemApi
     76     public static final String ACTION_CONNECTION_SERVICE_CONFIGURE =
     77             "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
     78 
     79     /**
     80      * The {@link android.content.Intent} action used to show the call settings page.
     81      */
     82     public static final String ACTION_SHOW_CALL_SETTINGS =
     83             "android.telecom.action.SHOW_CALL_SETTINGS";
     84 
     85     /**
     86      * The {@link android.content.Intent} action used to show the settings page used to configure
     87      * {@link PhoneAccount} preferences.
     88      * @hide
     89      */
     90     @SystemApi
     91     public static final String ACTION_CHANGE_PHONE_ACCOUNTS =
     92             "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
     93 
     94     /**
     95      * Optional extra for {@link android.content.Intent#ACTION_CALL} containing a boolean that
     96      * determines whether the speakerphone should be automatically turned on for an outgoing call.
     97      */
     98     public static final String EXTRA_START_CALL_WITH_SPEAKERPHONE =
     99             "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
    100 
    101     /**
    102      * Optional extra for {@link android.content.Intent#ACTION_CALL} containing an integer that
    103      * determines the desired video state for an outgoing call.
    104      * Valid options:
    105      * {@link VideoProfile.VideoState#AUDIO_ONLY},
    106      * {@link VideoProfile.VideoState#BIDIRECTIONAL},
    107      * {@link VideoProfile.VideoState#RX_ENABLED},
    108      * {@link VideoProfile.VideoState#TX_ENABLED}.
    109      * @hide
    110      */
    111     public static final String EXTRA_START_CALL_WITH_VIDEO_STATE =
    112             "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
    113 
    114     /**
    115      * The extra used with an {@link android.content.Intent#ACTION_CALL} and
    116      * {@link android.content.Intent#ACTION_DIAL} {@code Intent} to specify a
    117      * {@link PhoneAccountHandle} to use when making the call.
    118      * <p class="note">
    119      * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
    120      * @hide
    121      */
    122     @SystemApi
    123     public static final String EXTRA_PHONE_ACCOUNT_HANDLE =
    124             "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
    125 
    126     /**
    127      * Optional extra for {@link #ACTION_INCOMING_CALL} containing a {@link Bundle} which contains
    128      * metadata about the call. This {@link Bundle} will be returned to the
    129      * {@link ConnectionService}.
    130      *
    131      * @hide
    132      */
    133     @SystemApi
    134     public static final String EXTRA_INCOMING_CALL_EXTRAS =
    135             "android.telecom.extra.INCOMING_CALL_EXTRAS";
    136 
    137     /**
    138      * Optional extra for {@link android.content.Intent#ACTION_CALL} and
    139      * {@link android.content.Intent#ACTION_DIAL} {@code Intent} containing a {@link Bundle}
    140      * which contains metadata about the call. This {@link Bundle} will be saved into
    141      * {@code Call.Details}.
    142      *
    143      * @hide
    144      */
    145     @SystemApi
    146     public static final String EXTRA_OUTGOING_CALL_EXTRAS =
    147             "android.telecom.extra.OUTGOING_CALL_EXTRAS";
    148 
    149     /**
    150      * @hide
    151      */
    152     public static final String EXTRA_UNKNOWN_CALL_HANDLE =
    153             "android.telecom.extra.UNKNOWN_CALL_HANDLE";
    154 
    155     /**
    156      * Optional extra for {@link android.telephony.TelephonyManager#ACTION_PHONE_STATE_CHANGED}
    157      * containing the disconnect code.
    158      */
    159     public static final String EXTRA_CALL_DISCONNECT_CAUSE =
    160             "android.telecom.extra.CALL_DISCONNECT_CAUSE";
    161 
    162     /**
    163      * Optional extra for {@link android.telephony.TelephonyManager#ACTION_PHONE_STATE_CHANGED}
    164      * containing the disconnect message.
    165      */
    166     public static final String EXTRA_CALL_DISCONNECT_MESSAGE =
    167             "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
    168 
    169     /**
    170      * Optional extra for {@link android.telephony.TelephonyManager#ACTION_PHONE_STATE_CHANGED}
    171      * containing the component name of the associated connection service.
    172      * @hide
    173      */
    174     @SystemApi
    175     public static final String EXTRA_CONNECTION_SERVICE =
    176             "android.telecom.extra.CONNECTION_SERVICE";
    177 
    178     /**
    179      * An optional {@link android.content.Intent#ACTION_CALL} intent extra denoting the
    180      * package name of the app specifying an alternative gateway for the call.
    181      * The value is a string.
    182      *
    183      * (The following comment corresponds to the all GATEWAY_* extras)
    184      * An app which sends the {@link android.content.Intent#ACTION_CALL} intent can specify an
    185      * alternative address to dial which is different from the one specified and displayed to
    186      * the user. This alternative address is referred to as the gateway address.
    187      */
    188     public static final String GATEWAY_PROVIDER_PACKAGE =
    189             "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
    190 
    191     /**
    192      * An optional {@link android.content.Intent#ACTION_CALL} intent extra corresponding to the
    193      * original address to dial for the call. This is used when an alternative gateway address is
    194      * provided to recall the original address.
    195      * The value is a {@link android.net.Uri}.
    196      *
    197      * (See {@link #GATEWAY_PROVIDER_PACKAGE} for details)
    198      */
    199     public static final String GATEWAY_ORIGINAL_ADDRESS =
    200             "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
    201 
    202     /**
    203      * The number which the party on the other side of the line will see (and use to return the
    204      * call).
    205      * <p>
    206      * {@link ConnectionService}s which interact with {@link RemoteConnection}s should only populate
    207      * this if the {@link android.telephony.TelephonyManager#getLine1Number()} value, as that is the
    208      * user's expected caller ID.
    209      * @hide
    210      */
    211     @SystemApi
    212     public static final String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
    213 
    214     /**
    215      * The dual tone multi-frequency signaling character sent to indicate the dialing system should
    216      * pause for a predefined period.
    217      */
    218     public static final char DTMF_CHARACTER_PAUSE = ',';
    219 
    220     /**
    221      * The dual-tone multi-frequency signaling character sent to indicate the dialing system should
    222      * wait for user confirmation before proceeding.
    223      */
    224     public static final char DTMF_CHARACTER_WAIT = ';';
    225 
    226     /**
    227      * TTY (teletypewriter) mode is off.
    228      *
    229      * @hide
    230      */
    231     public static final int TTY_MODE_OFF = 0;
    232 
    233     /**
    234      * TTY (teletypewriter) mode is on. The speaker is off and the microphone is muted. The user
    235      * will communicate with the remote party by sending and receiving text messages.
    236      *
    237      * @hide
    238      */
    239     public static final int TTY_MODE_FULL = 1;
    240 
    241     /**
    242      * TTY (teletypewriter) mode is in hearing carryover mode (HCO). The microphone is muted but the
    243      * speaker is on. The user will communicate with the remote party by sending text messages and
    244      * hearing an audible reply.
    245      *
    246      * @hide
    247      */
    248     public static final int TTY_MODE_HCO = 2;
    249 
    250     /**
    251      * TTY (teletypewriter) mode is in voice carryover mode (VCO). The speaker is off but the
    252      * microphone is still on. User will communicate with the remote party by speaking and receiving
    253      * text message replies.
    254      *
    255      * @hide
    256      */
    257     public static final int TTY_MODE_VCO = 3;
    258 
    259     /**
    260      * Broadcast intent action indicating that the current TTY mode has changed. An intent extra
    261      * provides this state as an int.
    262      *
    263      * @see #EXTRA_CURRENT_TTY_MODE
    264      * @hide
    265      */
    266     public static final String ACTION_CURRENT_TTY_MODE_CHANGED =
    267             "android.telecom.action.CURRENT_TTY_MODE_CHANGED";
    268 
    269     /**
    270      * The lookup key for an int that indicates the current TTY mode.
    271      * Valid modes are:
    272      * - {@link #TTY_MODE_OFF}
    273      * - {@link #TTY_MODE_FULL}
    274      * - {@link #TTY_MODE_HCO}
    275      * - {@link #TTY_MODE_VCO}
    276      *
    277      * @hide
    278      */
    279     public static final String EXTRA_CURRENT_TTY_MODE =
    280             "android.telecom.intent.extra.CURRENT_TTY_MODE";
    281 
    282     /**
    283      * Broadcast intent action indicating that the TTY preferred operating mode has changed. An
    284      * intent extra provides the new mode as an int.
    285      *
    286      * @see #EXTRA_TTY_PREFERRED_MODE
    287      * @hide
    288      */
    289     public static final String ACTION_TTY_PREFERRED_MODE_CHANGED =
    290             "android.telecom.action.TTY_PREFERRED_MODE_CHANGED";
    291 
    292     /**
    293      * The lookup key for an int that indicates preferred TTY mode. Valid modes are: -
    294      * {@link #TTY_MODE_OFF} - {@link #TTY_MODE_FULL} - {@link #TTY_MODE_HCO} -
    295      * {@link #TTY_MODE_VCO}
    296      *
    297      * @hide
    298      */
    299     public static final String EXTRA_TTY_PREFERRED_MODE =
    300             "android.telecom.intent.extra.TTY_PREFERRED";
    301 
    302     /**
    303      * The following 4 constants define how properties such as phone numbers and names are
    304      * displayed to the user.
    305      */
    306 
    307     /** Property is displayed normally. */
    308     public static final int PRESENTATION_ALLOWED = 1;
    309 
    310     /** Property was blocked. */
    311     public static final int PRESENTATION_RESTRICTED = 2;
    312 
    313     /** Presentation was not specified or is unknown. */
    314     public static final int PRESENTATION_UNKNOWN = 3;
    315 
    316     /** Property should be displayed as a pay phone. */
    317     public static final int PRESENTATION_PAYPHONE = 4;
    318 
    319     private static final String TAG = "TelecomManager";
    320 
    321     private final Context mContext;
    322 
    323     /**
    324      * @hide
    325      */
    326     public static TelecomManager from(Context context) {
    327         return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
    328     }
    329 
    330     /**
    331      * @hide
    332      */
    333     public TelecomManager(Context context) {
    334         Context appContext = context.getApplicationContext();
    335         if (appContext != null) {
    336             mContext = appContext;
    337         } else {
    338             mContext = context;
    339         }
    340     }
    341 
    342     /**
    343      * Return the {@link PhoneAccount} which is the user-chosen default for making outgoing phone
    344      * calls with a specified URI scheme.
    345      * <p>
    346      * Apps must be prepared for this method to return {@code null}, indicating that there currently
    347      * exists no user-chosen default {@code PhoneAccount}.
    348      * <p>
    349      * @param uriScheme The URI scheme.
    350      * @return The {@link PhoneAccountHandle} corresponding to the user-chosen default for outgoing
    351      * phone calls for a specified URI scheme.
    352      * @hide
    353      */
    354     @SystemApi
    355     public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
    356         try {
    357             if (isServiceConnected()) {
    358                 return getTelecomService().getDefaultOutgoingPhoneAccount(uriScheme);
    359             }
    360         } catch (RemoteException e) {
    361             Log.e(TAG, "Error calling ITelecomService#getDefaultOutgoingPhoneAccount", e);
    362         }
    363         return null;
    364     }
    365 
    366     /**
    367      * Return the {@link PhoneAccount} which is the user-chosen default for making outgoing phone
    368      * calls. This {@code PhoneAccount} will always be a member of the list which is returned from
    369      * calling {@link #getCallCapablePhoneAccounts()}
    370      *
    371      * Apps must be prepared for this method to return {@code null}, indicating that there currently
    372      * exists no user-chosen default {@code PhoneAccount}.
    373      *
    374      * @return The user outgoing phone account selected by the user.
    375      * @hide
    376      */
    377     public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
    378         try {
    379             if (isServiceConnected()) {
    380                 return getTelecomService().getUserSelectedOutgoingPhoneAccount();
    381             }
    382         } catch (RemoteException e) {
    383             Log.e(TAG, "Error calling ITelecomService#getUserSelectedOutgoingPhoneAccount", e);
    384         }
    385         return null;
    386     }
    387 
    388     /**
    389      * Sets the default account for making outgoing phone calls.
    390      * @hide
    391      */
    392     public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
    393         try {
    394             if (isServiceConnected()) {
    395                 getTelecomService().setUserSelectedOutgoingPhoneAccount(accountHandle);
    396             }
    397         } catch (RemoteException e) {
    398             Log.e(TAG, "Error calling ITelecomService#setUserSelectedOutgoingPhoneAccount");
    399         }
    400     }
    401 
    402     /**
    403      * Returns the current SIM call manager. Apps must be prepared for this method to return
    404      * {@code null}, indicating that there currently exists no user-chosen default
    405      * {@code PhoneAccount}.
    406      * @return The phone account handle of the current sim call manager.
    407      * @hide
    408      */
    409     public PhoneAccountHandle getSimCallManager() {
    410         try {
    411             if (isServiceConnected()) {
    412                 return getTelecomService().getSimCallManager();
    413             }
    414         } catch (RemoteException e) {
    415             Log.e(TAG, "Error calling ITelecomService#getSimCallManager");
    416         }
    417         return null;
    418     }
    419 
    420     /**
    421      * Sets the SIM call manager to the specified phone account.
    422      * @param accountHandle The phone account handle of the account to set as the sim call manager.
    423      * @hide
    424      */
    425     public void setSimCallManager(PhoneAccountHandle accountHandle) {
    426         try {
    427             if (isServiceConnected()) {
    428                 getTelecomService().setSimCallManager(accountHandle);
    429             }
    430         } catch (RemoteException e) {
    431             Log.e(TAG, "Error calling ITelecomService#setSimCallManager");
    432         }
    433     }
    434 
    435     /**
    436      * Returns the list of registered SIM call managers.
    437      * @return List of registered SIM call managers.
    438      * @hide
    439      */
    440     public List<PhoneAccountHandle> getSimCallManagers() {
    441         try {
    442             if (isServiceConnected()) {
    443                 return getTelecomService().getSimCallManagers();
    444             }
    445         } catch (RemoteException e) {
    446             Log.e(TAG, "Error calling ITelecomService#getSimCallManagers");
    447         }
    448         return new ArrayList<>();
    449     }
    450 
    451     /**
    452      * Returns the current connection manager. Apps must be prepared for this method to return
    453      * {@code null}, indicating that there currently exists no user-chosen default
    454      * {@code PhoneAccount}.
    455      *
    456      * @return The phone account handle of the current connection manager.
    457      * @hide
    458      */
    459     @SystemApi
    460     public PhoneAccountHandle getConnectionManager() {
    461         return getSimCallManager();
    462     }
    463 
    464     /**
    465      * Returns the list of registered SIM call managers.
    466      * @return List of registered SIM call managers.
    467      * @hide
    468      */
    469     @SystemApi
    470     public List<PhoneAccountHandle> getRegisteredConnectionManagers() {
    471         return getSimCallManagers();
    472     }
    473 
    474     /**
    475      * Returns a list of the {@link PhoneAccountHandle}s which can be used to make and receive phone
    476      * calls which support the specified URI scheme.
    477      * <P>
    478      * For example, invoking with {@code "tel"} will find all {@link PhoneAccountHandle}s which
    479      * support telephone calls (e.g. URIs such as {@code tel:555-555-1212}).  Invoking with
    480      * {@code "sip"} will find all {@link PhoneAccountHandle}s which support SIP calls (e.g. URIs
    481      * such as {@code sip:example (at) sipexample.com}).
    482      *
    483      * @param uriScheme The URI scheme.
    484      * @return A list of {@code PhoneAccountHandle} objects supporting the URI scheme.
    485      * @hide
    486      */
    487     @SystemApi
    488     public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) {
    489         try {
    490             if (isServiceConnected()) {
    491                 return getTelecomService().getPhoneAccountsSupportingScheme(uriScheme);
    492             }
    493         } catch (RemoteException e) {
    494             Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsSupportingScheme", e);
    495         }
    496         return new ArrayList<>();
    497     }
    498 
    499 
    500     /**
    501      * Return a list of {@link PhoneAccountHandle}s which can be used to make and receive phone
    502      * calls.
    503      *
    504      * @see #EXTRA_PHONE_ACCOUNT_HANDLE
    505      * @return A list of {@code PhoneAccountHandle} objects.
    506      *
    507      * @hide
    508      */
    509     public List<PhoneAccountHandle> getCallCapablePhoneAccounts() {
    510         try {
    511             if (isServiceConnected()) {
    512                 return getTelecomService().getCallCapablePhoneAccounts();
    513             }
    514         } catch (RemoteException e) {
    515             Log.e(TAG, "Error calling ITelecomService#getCallCapablePhoneAccounts", e);
    516         }
    517         return new ArrayList<>();
    518     }
    519 
    520     /**
    521      * Determine whether the device has more than one account registered that can make and receive
    522      * phone calls.
    523      *
    524      * @return {@code true} if the device has more than one account registered and {@code false}
    525      * otherwise.
    526      * @hide
    527      */
    528     @SystemApi
    529     public boolean hasMultipleCallCapableAccounts() {
    530         return getCallCapablePhoneAccounts().size() > 1;
    531     }
    532 
    533     /**
    534      *  Returns a list of all {@link PhoneAccount}s registered for the calling package.
    535      *
    536      * @return A list of {@code PhoneAccountHandle} objects.
    537      * @hide
    538      */
    539     @SystemApi
    540     public List<PhoneAccountHandle> getPhoneAccountsForPackage() {
    541         try {
    542             if (isServiceConnected()) {
    543                 return getTelecomService().getPhoneAccountsForPackage(mContext.getPackageName());
    544             }
    545         } catch (RemoteException e) {
    546             Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsForPackage", e);
    547         }
    548         return null;
    549     }
    550 
    551     /**
    552      * Return the {@link PhoneAccount} for a specified {@link PhoneAccountHandle}. Object includes
    553      * resources which can be used in a user interface.
    554      *
    555      * @param account The {@link PhoneAccountHandle}.
    556      * @return The {@link PhoneAccount} object.
    557      * @hide
    558      */
    559     @SystemApi
    560     public PhoneAccount getPhoneAccount(PhoneAccountHandle account) {
    561         try {
    562             if (isServiceConnected()) {
    563                 return getTelecomService().getPhoneAccount(account);
    564             }
    565         } catch (RemoteException e) {
    566             Log.e(TAG, "Error calling ITelecomService#getPhoneAccount", e);
    567         }
    568         return null;
    569     }
    570 
    571     /**
    572      * Returns a count of all {@link PhoneAccount}s.
    573      *
    574      * @return The count of {@link PhoneAccount}s.
    575      * @hide
    576      */
    577     @SystemApi
    578     public int getAllPhoneAccountsCount() {
    579         try {
    580             if (isServiceConnected()) {
    581                 return getTelecomService().getAllPhoneAccountsCount();
    582             }
    583         } catch (RemoteException e) {
    584             Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccountsCount", e);
    585         }
    586         return 0;
    587     }
    588 
    589     /**
    590      * Returns a list of all {@link PhoneAccount}s.
    591      *
    592      * @return All {@link PhoneAccount}s.
    593      * @hide
    594      */
    595     @SystemApi
    596     public List<PhoneAccount> getAllPhoneAccounts() {
    597         try {
    598             if (isServiceConnected()) {
    599                 return getTelecomService().getAllPhoneAccounts();
    600             }
    601         } catch (RemoteException e) {
    602             Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccounts", e);
    603         }
    604         return Collections.EMPTY_LIST;
    605     }
    606 
    607     /**
    608      * Returns a list of all {@link PhoneAccountHandle}s.
    609      *
    610      * @return All {@link PhoneAccountHandle}s.
    611      * @hide
    612      */
    613     @SystemApi
    614     public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
    615         try {
    616             if (isServiceConnected()) {
    617                 return getTelecomService().getAllPhoneAccountHandles();
    618             }
    619         } catch (RemoteException e) {
    620             Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccountHandles", e);
    621         }
    622         return Collections.EMPTY_LIST;
    623     }
    624 
    625     /**
    626      * Register a {@link PhoneAccount} for use by the system. When registering
    627      * {@link PhoneAccount}s, existing registrations will be overwritten if the
    628      * {@link PhoneAccountHandle} matches that of a {@link PhoneAccount} which is already
    629      * registered. Once registered, the {@link PhoneAccount} is listed to the user as an option
    630      * when placing calls. The user may still need to enable the {@link PhoneAccount} within
    631      * the phone app settings before the account is usable.
    632      * <p>
    633      * A {@link SecurityException} will be thrown if an app tries to register a
    634      * {@link PhoneAccountHandle} where the package name specified within
    635      * {@link PhoneAccountHandle#getComponentName()} does not match the package name of the app.
    636      *
    637      * @param account The complete {@link PhoneAccount}.
    638      *
    639      * @hide
    640      */
    641     @SystemApi
    642     public void registerPhoneAccount(PhoneAccount account) {
    643         try {
    644             if (isServiceConnected()) {
    645                 getTelecomService().registerPhoneAccount(account);
    646             }
    647         } catch (RemoteException e) {
    648             Log.e(TAG, "Error calling ITelecomService#registerPhoneAccount", e);
    649         }
    650     }
    651 
    652     /**
    653      * Remove a {@link PhoneAccount} registration from the system.
    654      *
    655      * @param accountHandle A {@link PhoneAccountHandle} for the {@link PhoneAccount} to unregister.
    656      * @hide
    657      */
    658     @SystemApi
    659     public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
    660         try {
    661             if (isServiceConnected()) {
    662                 getTelecomService().unregisterPhoneAccount(accountHandle);
    663             }
    664         } catch (RemoteException e) {
    665             Log.e(TAG, "Error calling ITelecomService#unregisterPhoneAccount", e);
    666         }
    667     }
    668 
    669     /**
    670      * Remove all Accounts that belong to the calling package from the system.
    671      * @hide
    672      */
    673     @SystemApi
    674     public void clearAccounts() {
    675         try {
    676             if (isServiceConnected()) {
    677                 getTelecomService().clearAccounts(mContext.getPackageName());
    678             }
    679         } catch (RemoteException e) {
    680             Log.e(TAG, "Error calling ITelecomService#clearAccounts", e);
    681         }
    682     }
    683 
    684     /**
    685      * Remove all Accounts that belong to the specified package from the system.
    686      * @hide
    687      */
    688     public void clearAccountsForPackage(String packageName) {
    689         try {
    690             if (isServiceConnected() && !TextUtils.isEmpty(packageName)) {
    691                 getTelecomService().clearAccounts(packageName);
    692             }
    693         } catch (RemoteException e) {
    694             Log.e(TAG, "Error calling ITelecomService#clearAccountsForPackage", e);
    695         }
    696     }
    697 
    698     /**
    699      * @hide
    700      */
    701     @SystemApi
    702     public ComponentName getDefaultPhoneApp() {
    703         try {
    704             if (isServiceConnected()) {
    705                 return getTelecomService().getDefaultPhoneApp();
    706             }
    707         } catch (RemoteException e) {
    708             Log.e(TAG, "RemoteException attempting to get the default phone app.", e);
    709         }
    710         return null;
    711     }
    712 
    713     /**
    714      * Return whether a given phone number is the configured voicemail number for a
    715      * particular phone account.
    716      *
    717      * @param accountHandle The handle for the account to check the voicemail number against
    718      * @param number The number to look up.
    719      *
    720      * @hide
    721      */
    722     @SystemApi
    723     public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
    724         try {
    725             if (isServiceConnected()) {
    726                 return getTelecomService().isVoiceMailNumber(accountHandle, number);
    727             }
    728         } catch (RemoteException e) {
    729             Log.e(TAG, "RemoteException calling ITelecomService#isVoiceMailNumber.", e);
    730         }
    731         return false;
    732     }
    733 
    734     /**
    735      * Return whether a given phone account has a voicemail number configured.
    736      *
    737      * @param accountHandle The handle for the account to check for a voicemail number.
    738      * @return {@code true} If the given phone account has a voicemail number.
    739      *
    740      * @hide
    741      */
    742     @SystemApi
    743     public boolean hasVoiceMailNumber(PhoneAccountHandle accountHandle) {
    744         try {
    745             if (isServiceConnected()) {
    746                 return getTelecomService().hasVoiceMailNumber(accountHandle);
    747             }
    748         } catch (RemoteException e) {
    749             Log.e(TAG, "RemoteException calling ITelecomService#hasVoiceMailNumber.", e);
    750         }
    751         return false;
    752     }
    753 
    754     /**
    755      * Return the line 1 phone number for given phone account.
    756      *
    757      * @param accountHandle The handle for the account retrieve a number for.
    758      * @return A string representation of the line 1 phone number.
    759      *
    760      * @hide
    761      */
    762     @SystemApi
    763     public String getLine1Number(PhoneAccountHandle accountHandle) {
    764         try {
    765             if (isServiceConnected()) {
    766                 return getTelecomService().getLine1Number(accountHandle);
    767             }
    768         } catch (RemoteException e) {
    769             Log.e(TAG, "RemoteException calling ITelecomService#getLine1Number.", e);
    770         }
    771         return null;
    772     }
    773 
    774     /**
    775      * Returns whether there is an ongoing phone call (can be in dialing, ringing, active or holding
    776      * states).
    777      * <p>
    778      * Requires permission: {@link android.Manifest.permission#READ_PHONE_STATE}
    779      * </p>
    780      */
    781     public boolean isInCall() {
    782         try {
    783             if (isServiceConnected()) {
    784                 return getTelecomService().isInCall();
    785             }
    786         } catch (RemoteException e) {
    787             Log.e(TAG, "RemoteException calling isInCall().", e);
    788         }
    789         return false;
    790     }
    791 
    792     /**
    793      * Returns one of the following constants that represents the current state of Telecom:
    794      *
    795      * {@link TelephonyManager#CALL_STATE_RINGING}
    796      * {@link TelephonyManager#CALL_STATE_OFFHOOK}
    797      * {@link TelephonyManager#CALL_STATE_IDLE}
    798      *
    799      * Note that this API does not require the
    800      * {@link android.Manifest.permission#READ_PHONE_STATE} permission. This is intentional, to
    801      * preserve the behavior of {@link TelephonyManager#getCallState()}, which also did not require
    802      * the permission.
    803      * @hide
    804      */
    805     @SystemApi
    806     public int getCallState() {
    807         try {
    808             if (isServiceConnected()) {
    809                 return getTelecomService().getCallState();
    810             }
    811         } catch (RemoteException e) {
    812             Log.d(TAG, "RemoteException calling getCallState().", e);
    813         }
    814         return TelephonyManager.CALL_STATE_IDLE;
    815     }
    816 
    817     /**
    818      * Returns whether there currently exists is a ringing incoming-call.
    819      *
    820      * @hide
    821      */
    822     @SystemApi
    823     public boolean isRinging() {
    824         try {
    825             if (isServiceConnected()) {
    826                 return getTelecomService().isRinging();
    827             }
    828         } catch (RemoteException e) {
    829             Log.e(TAG, "RemoteException attempting to get ringing state of phone app.", e);
    830         }
    831         return false;
    832     }
    833 
    834     /**
    835      * Ends an ongoing call.
    836      * TODO: L-release - need to convert all invocations of ITelecomService#endCall to use this
    837      * method (clockwork & gearhead).
    838      * @hide
    839      */
    840     @SystemApi
    841     public boolean endCall() {
    842         try {
    843             if (isServiceConnected()) {
    844                 return getTelecomService().endCall();
    845             }
    846         } catch (RemoteException e) {
    847             Log.e(TAG, "Error calling ITelecomService#endCall", e);
    848         }
    849         return false;
    850     }
    851 
    852     /**
    853      * If there is a ringing incoming call, this method accepts the call on behalf of the user.
    854      * TODO: L-release - need to convert all invocation of ITelecmmService#answerRingingCall to use
    855      * this method (clockwork & gearhead).
    856      *
    857      * @hide
    858      */
    859     @SystemApi
    860     public void acceptRingingCall() {
    861         try {
    862             if (isServiceConnected()) {
    863                 getTelecomService().acceptRingingCall();
    864             }
    865         } catch (RemoteException e) {
    866             Log.e(TAG, "Error calling ITelecomService#acceptRingingCall", e);
    867         }
    868     }
    869 
    870     /**
    871      * Silences the ringer if a ringing call exists.
    872      *
    873      * @hide
    874      */
    875     @SystemApi
    876     public void silenceRinger() {
    877         try {
    878             if (isServiceConnected()) {
    879                 getTelecomService().silenceRinger();
    880             }
    881         } catch (RemoteException e) {
    882             Log.e(TAG, "Error calling ITelecomService#silenceRinger", e);
    883         }
    884     }
    885 
    886     /**
    887      * Returns whether TTY is supported on this device.
    888      *
    889      * @hide
    890      */
    891     @SystemApi
    892     public boolean isTtySupported() {
    893         try {
    894             if (isServiceConnected()) {
    895                 return getTelecomService().isTtySupported();
    896             }
    897         } catch (RemoteException e) {
    898             Log.e(TAG, "RemoteException attempting to get TTY supported state.", e);
    899         }
    900         return false;
    901     }
    902 
    903     /**
    904      * Returns the current TTY mode of the device. For TTY to be on the user must enable it in
    905      * settings and have a wired headset plugged in.
    906      * Valid modes are:
    907      * - {@link TelecomManager#TTY_MODE_OFF}
    908      * - {@link TelecomManager#TTY_MODE_FULL}
    909      * - {@link TelecomManager#TTY_MODE_HCO}
    910      * - {@link TelecomManager#TTY_MODE_VCO}
    911      * @hide
    912      */
    913     public int getCurrentTtyMode() {
    914         try {
    915             if (isServiceConnected()) {
    916                 return getTelecomService().getCurrentTtyMode();
    917             }
    918         } catch (RemoteException e) {
    919             Log.e(TAG, "RemoteException attempting to get the current TTY mode.", e);
    920         }
    921         return TTY_MODE_OFF;
    922     }
    923 
    924     /**
    925      * Registers a new incoming call. A {@link ConnectionService} should invoke this method when it
    926      * has an incoming call. The specified {@link PhoneAccountHandle} must have been registered
    927      * with {@link #registerPhoneAccount}. Once invoked, this method will cause the system to bind
    928      * to the {@link ConnectionService} associated with the {@link PhoneAccountHandle} and request
    929      * additional information about the call (See
    930      * {@link ConnectionService#onCreateIncomingConnection}) before starting the incoming call UI.
    931      *
    932      * @param phoneAccount A {@link PhoneAccountHandle} registered with
    933      *            {@link #registerPhoneAccount}.
    934      * @param extras A bundle that will be passed through to
    935      *            {@link ConnectionService#onCreateIncomingConnection}.
    936      * @hide
    937      */
    938     @SystemApi
    939     public void addNewIncomingCall(PhoneAccountHandle phoneAccount, Bundle extras) {
    940         try {
    941             if (isServiceConnected()) {
    942                 getTelecomService().addNewIncomingCall(
    943                         phoneAccount, extras == null ? new Bundle() : extras);
    944             }
    945         } catch (RemoteException e) {
    946             Log.e(TAG, "RemoteException adding a new incoming call: " + phoneAccount, e);
    947         }
    948     }
    949 
    950     /**
    951      * Registers a new unknown call with Telecom. This can only be called by the system Telephony
    952      * service. This is invoked when Telephony detects a new unknown connection that was neither
    953      * a new incoming call, nor an user-initiated outgoing call.
    954      *
    955      * @param phoneAccount A {@link PhoneAccountHandle} registered with
    956      *            {@link #registerPhoneAccount}.
    957      * @param extras A bundle that will be passed through to
    958      *            {@link ConnectionService#onCreateIncomingConnection}.
    959      * @hide
    960      */
    961     @SystemApi
    962     public void addNewUnknownCall(PhoneAccountHandle phoneAccount, Bundle extras) {
    963         try {
    964             if (isServiceConnected()) {
    965                 getTelecomService().addNewUnknownCall(
    966                         phoneAccount, extras == null ? new Bundle() : extras);
    967             }
    968         } catch (RemoteException e) {
    969             Log.e(TAG, "RemoteException adding a new unknown call: " + phoneAccount, e);
    970         }
    971     }
    972 
    973     /**
    974      * Processes the specified dial string as an MMI code.
    975      * MMI codes are any sequence of characters entered into the dialpad that contain a "*" or "#".
    976      * Some of these sequences launch special behavior through handled by Telephony.
    977      * This method uses the default subscription.
    978      * <p>
    979      * Requires that the method-caller be set as the system dialer app.
    980      * </p>
    981      *
    982      * @param dialString The digits to dial.
    983      * @return True if the digits were processed as an MMI code, false otherwise.
    984      */
    985     public boolean handleMmi(String dialString) {
    986         ITelecomService service = getTelecomService();
    987         if (service != null) {
    988             try {
    989                 return service.handlePinMmi(dialString);
    990             } catch (RemoteException e) {
    991                 Log.e(TAG, "Error calling ITelecomService#handlePinMmi", e);
    992             }
    993         }
    994         return false;
    995     }
    996 
    997     /**
    998      * Processes the specified dial string as an MMI code.
    999      * MMI codes are any sequence of characters entered into the dialpad that contain a "*" or "#".
   1000      * Some of these sequences launch special behavior through handled by Telephony.
   1001      * <p>
   1002      * Requires that the method-caller be set as the system dialer app.
   1003      * </p>
   1004      *
   1005      * @param accountHandle The handle for the account the MMI code should apply to.
   1006      * @param dialString The digits to dial.
   1007      * @return True if the digits were processed as an MMI code, false otherwise.
   1008      * @hide
   1009      */
   1010     @SystemApi
   1011     public boolean handleMmi(PhoneAccountHandle accountHandle, String dialString) {
   1012         ITelecomService service = getTelecomService();
   1013         if (service != null) {
   1014             try {
   1015                 return service.handlePinMmiForPhoneAccount(accountHandle, dialString);
   1016             } catch (RemoteException e) {
   1017                 Log.e(TAG, "Error calling ITelecomService#handlePinMmi", e);
   1018             }
   1019         }
   1020         return false;
   1021     }
   1022 
   1023     /**
   1024      * @param accountHandle The handle for the account to derive an adn query URI for or
   1025      * {@code null} to return a URI which will use the default account.
   1026      * @return The URI (with the content:// scheme) specific to the specified {@link PhoneAccount}
   1027      * for the the content retrieve.
   1028      * @hide
   1029      */
   1030     @SystemApi
   1031     public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
   1032         ITelecomService service = getTelecomService();
   1033         if (service != null && accountHandle != null) {
   1034             try {
   1035                 return service.getAdnUriForPhoneAccount(accountHandle);
   1036             } catch (RemoteException e) {
   1037                 Log.e(TAG, "Error calling ITelecomService#getAdnUriForPhoneAccount", e);
   1038             }
   1039         }
   1040         return Uri.parse("content://icc/adn");
   1041     }
   1042 
   1043     /**
   1044      * Removes the missed-call notification if one is present.
   1045      * <p>
   1046      * Requires that the method-caller be set as the system dialer app.
   1047      * </p>
   1048      */
   1049     public void cancelMissedCallsNotification() {
   1050         ITelecomService service = getTelecomService();
   1051         if (service != null) {
   1052             try {
   1053                 service.cancelMissedCallsNotification();
   1054             } catch (RemoteException e) {
   1055                 Log.e(TAG, "Error calling ITelecomService#cancelMissedCallsNotification", e);
   1056             }
   1057         }
   1058     }
   1059 
   1060     /**
   1061      * Brings the in-call screen to the foreground if there is an ongoing call. If there is
   1062      * currently no ongoing call, then this method does nothing.
   1063      * <p>
   1064      * Requires that the method-caller be set as the system dialer app or have the
   1065      * {@link android.Manifest.permission#READ_PHONE_STATE} permission.
   1066      * </p>
   1067      *
   1068      * @param showDialpad Brings up the in-call dialpad as part of showing the in-call screen.
   1069      */
   1070     public void showInCallScreen(boolean showDialpad) {
   1071         ITelecomService service = getTelecomService();
   1072         if (service != null) {
   1073             try {
   1074                 service.showInCallScreen(showDialpad);
   1075             } catch (RemoteException e) {
   1076                 Log.e(TAG, "Error calling ITelecomService#showCallScreen", e);
   1077             }
   1078         }
   1079     }
   1080 
   1081     private ITelecomService getTelecomService() {
   1082         return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
   1083     }
   1084 
   1085     private boolean isServiceConnected() {
   1086         boolean isConnected = getTelecomService() != null;
   1087         if (!isConnected) {
   1088             Log.w(TAG, "Telecom Service not found.");
   1089         }
   1090         return isConnected;
   1091     }
   1092 }
   1093