TelecomManager.java revision ef9f6f957d897ea0ed82114185b8fa3fefd4917b
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
15package android.telecom;
16
17import android.annotation.SystemApi;
18import android.content.ComponentName;
19import android.content.Context;
20import android.os.Bundle;
21import android.os.RemoteException;
22import android.os.ServiceManager;
23import android.util.Log;
24
25import com.android.internal.telecom.ITelecomService;
26
27import java.util.ArrayList;
28import java.util.Collections;
29import java.util.List;
30
31/**
32 * Provides access to Telecom-related functionality.
33 * TODO: Move this all into PhoneManager.
34 */
35public class TelecomManager {
36
37    /**
38     * Activity action: Starts the UI for handing an incoming call. This intent starts the in-call
39     * UI by notifying the Telecom system that an incoming call exists for a specific call service
40     * (see {@link android.telecom.ConnectionService}). Telecom reads the Intent extras to find
41     * and bind to the appropriate {@link android.telecom.ConnectionService} which Telecom will
42     * ultimately use to control and get information about the call.
43     * <p>
44     * Input: get*Extra field {@link #EXTRA_PHONE_ACCOUNT_HANDLE} contains the component name of the
45     * {@link android.telecom.ConnectionService} that Telecom should bind to. Telecom will then
46     * ask the connection service for more information about the call prior to showing any UI.
47     *
48     * @hide
49     */
50    public static final String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
51
52    /**
53     * The {@link android.content.Intent} action used to configure a
54     * {@link android.telecom.ConnectionService}.
55     */
56    public static final String ACTION_CONNECTION_SERVICE_CONFIGURE =
57            "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
58
59    /**
60     * The {@link android.content.Intent} action used to show the call settings page.
61     */
62    public static final String ACTION_SHOW_CALL_SETTINGS =
63            "android.telecom.action.SHOW_CALL_SETTINGS";
64
65    /**
66     * The {@link android.content.Intent} action used to show the settings page used to configure
67     * {@link PhoneAccount} preferences.
68     */
69    public static final String ACTION_CHANGE_PHONE_ACCOUNTS =
70            "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
71
72    /**
73     * The {@link android.content.Intent} action used to inform a
74     * {@link android.telecom.ConnectionService} that one of its {@link PhoneAccount}s has been
75     * enabled.  The {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE} extra is used to indicate
76     * which {@link PhoneAccount} has been enabled.
77     */
78    public static final String ACTION_PHONE_ACCOUNT_ENABLED =
79            "android.telecom.action.PHONE_ACCOUNT_ENABLED";
80
81    /**
82     * The {@link android.content.Intent} action used to inform a
83     * {@link android.telecom.ConnectionService} that one of its {@link PhoneAccount}s has been
84     * disabled.  The {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE} extra is used to indicate
85     * which {@link PhoneAccount} has been disabled.
86     */
87    public static final String ACTION_PHONE_ACCOUNT_DISABLED =
88            "android.telecom.action.PHONE_ACCOUNT_DISABLED";
89
90    /**
91     * Optional extra for {@link android.content.Intent#ACTION_CALL} containing a boolean that
92     * determines whether the speakerphone should be automatically turned on for an outgoing call.
93     */
94    public static final String EXTRA_START_CALL_WITH_SPEAKERPHONE =
95            "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
96
97    /**
98     * Optional extra for {@link android.content.Intent#ACTION_CALL} containing an integer that
99     * determines the desired video state for an outgoing call.
100     * Valid options:
101     * {@link VideoProfile.VideoState#AUDIO_ONLY},
102     * {@link VideoProfile.VideoState#BIDIRECTIONAL},
103     * {@link VideoProfile.VideoState#RX_ENABLED},
104     * {@link VideoProfile.VideoState#TX_ENABLED}.
105     * @hide
106     */
107    public static final String EXTRA_START_CALL_WITH_VIDEO_STATE =
108            "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
109
110    /**
111     * The extra used with an {@link android.content.Intent#ACTION_CALL} and
112     * {@link android.content.Intent#ACTION_DIAL} {@code Intent} to specify a
113     * {@link PhoneAccountHandle} to use when making the call.
114     * <p class="note">
115     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
116     */
117    public static final String EXTRA_PHONE_ACCOUNT_HANDLE =
118            "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
119
120    /**
121     * Optional extra for {@link #ACTION_INCOMING_CALL} containing a {@link Bundle} which contains
122     * metadata about the call. This {@link Bundle} will be returned to the
123     * {@link ConnectionService}.
124     *
125     * @hide
126     */
127    public static final String EXTRA_INCOMING_CALL_EXTRAS =
128            "android.telecom.extra.INCOMING_CALL_EXTRAS";
129
130    /**
131     * Optional extra for {@link android.content.Intent#ACTION_CALL} and
132     * {@link android.content.Intent#ACTION_DIAL} {@code Intent} containing a {@link Bundle}
133     * which contains metadata about the call. This {@link Bundle} will be saved into
134     * {@code Call.Details}.
135     *
136     * @hide
137     */
138    public static final String EXTRA_OUTGOING_CALL_EXTRAS =
139            "android.telecom.extra.OUTGOING_CALL_EXTRAS";
140
141    /**
142     * Optional extra for {@link android.telephony.TelephonyManager#ACTION_PHONE_STATE_CHANGED}
143     * containing the disconnect code.
144     */
145    public static final String EXTRA_CALL_DISCONNECT_CAUSE =
146            "android.telecom.extra.CALL_DISCONNECT_CAUSE";
147
148    /**
149     * Optional extra for {@link android.telephony.TelephonyManager#ACTION_PHONE_STATE_CHANGED}
150     * containing the disconnect message.
151     */
152    public static final String EXTRA_CALL_DISCONNECT_MESSAGE =
153            "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
154
155    /**
156     * Optional extra for {@link android.telephony.TelephonyManager#ACTION_PHONE_STATE_CHANGED}
157     * containing the component name of the associated connection service.
158     */
159    public static final String EXTRA_CONNECTION_SERVICE =
160            "android.telecom.extra.CONNECTION_SERVICE";
161
162    /**
163     * An optional {@link android.content.Intent#ACTION_CALL} intent extra denoting the
164     * package name of the app specifying an alternative gateway for the call.
165     * The value is a string.
166     *
167     * (The following comment corresponds to the all GATEWAY_* extras)
168     * An app which sends the {@link android.content.Intent#ACTION_CALL} intent can specify an
169     * alternative address to dial which is different from the one specified and displayed to
170     * the user. This alternative address is referred to as the gateway address.
171     */
172    public static final String GATEWAY_PROVIDER_PACKAGE =
173            "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
174
175    /**
176     * An optional {@link android.content.Intent#ACTION_CALL} intent extra corresponding to the
177     * original address to dial for the call. This is used when an alternative gateway address is
178     * provided to recall the original address.
179     * The value is a {@link android.net.Uri}.
180     *
181     * (See {@link #GATEWAY_PROVIDER_PACKAGE} for details)
182     */
183    public static final String GATEWAY_ORIGINAL_ADDRESS =
184            "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
185
186    /**
187     * The number which the party on the other side of the line will see (and use to return the
188     * call).
189     * <p>
190     * {@link ConnectionService}s which interact with {@link RemoteConnection}s should only populate
191     * this if the {@link android.telephony.TelephonyManager#getLine1Number()} value, as that is the
192     * user's expected caller ID.
193     */
194    public static final String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
195
196    /**
197     * The dual tone multi-frequency signaling character sent to indicate the dialing system should
198     * pause for a predefined period.
199     */
200    public static final char DTMF_CHARACTER_PAUSE = ',';
201
202    /**
203     * The dual-tone multi-frequency signaling character sent to indicate the dialing system should
204     * wait for user confirmation before proceeding.
205     */
206    public static final char DTMF_CHARACTER_WAIT = ';';
207
208    /**
209     * TTY (teletypewriter) mode is off.
210     *
211     * @hide
212     */
213    public static final int TTY_MODE_OFF = 0;
214
215    /**
216     * TTY (teletypewriter) mode is on. The speaker is off and the microphone is muted. The user
217     * will communicate with the remote party by sending and receiving text messages.
218     *
219     * @hide
220     */
221    public static final int TTY_MODE_FULL = 1;
222
223    /**
224     * TTY (teletypewriter) mode is in hearing carryover mode (HCO). The microphone is muted but the
225     * speaker is on. The user will communicate with the remote party by sending text messages and
226     * hearing an audible reply.
227     *
228     * @hide
229     */
230    public static final int TTY_MODE_HCO = 2;
231
232    /**
233     * TTY (teletypewriter) mode is in voice carryover mode (VCO). The speaker is off but the
234     * microphone is still on. User will communicate with the remote party by speaking and receiving
235     * text message replies.
236     *
237     * @hide
238     */
239    public static final int TTY_MODE_VCO = 3;
240
241    /**
242     * Broadcast intent action indicating that the current TTY mode has changed. An intent extra
243     * provides this state as an int.
244     *
245     * @see #EXTRA_CURRENT_TTY_MODE
246     * @hide
247     */
248    public static final String ACTION_CURRENT_TTY_MODE_CHANGED =
249            "android.telecom.action.CURRENT_TTY_MODE_CHANGED";
250
251    /**
252     * The lookup key for an int that indicates the current TTY mode.
253     * Valid modes are:
254     * - {@link #TTY_MODE_OFF}
255     * - {@link #TTY_MODE_FULL}
256     * - {@link #TTY_MODE_HCO}
257     * - {@link #TTY_MODE_VCO}
258     *
259     * @hide
260     */
261    public static final String EXTRA_CURRENT_TTY_MODE =
262            "android.telecom.intent.extra.CURRENT_TTY_MODE";
263
264    /**
265     * Broadcast intent action indicating that the TTY preferred operating mode has changed. An
266     * intent extra provides the new mode as an int.
267     *
268     * @see #EXTRA_TTY_PREFERRED_MODE
269     * @hide
270     */
271    public static final String ACTION_TTY_PREFERRED_MODE_CHANGED =
272            "android.telecom.action.TTY_PREFERRED_MODE_CHANGED";
273
274    /**
275     * The lookup key for an int that indicates preferred TTY mode. Valid modes are: -
276     * {@link #TTY_MODE_OFF} - {@link #TTY_MODE_FULL} - {@link #TTY_MODE_HCO} -
277     * {@link #TTY_MODE_VCO}
278     *
279     * @hide
280     */
281    public static final String EXTRA_TTY_PREFERRED_MODE =
282            "android.telecom.intent.extra.TTY_PREFERRED";
283
284    /**
285     * The following 4 constants define how properties such as phone numbers and names are
286     * displayed to the user.
287     */
288
289    /** Property is displayed normally. */
290    public static final int PRESENTATION_ALLOWED = 1;
291
292    /** Property was blocked. */
293    public static final int PRESENTATION_RESTRICTED = 2;
294
295    /** Presentation was not specified or is unknown. */
296    public static final int PRESENTATION_UNKNOWN = 3;
297
298    /** Property should be displayed as a pay phone. */
299    public static final int PRESENTATION_PAYPHONE = 4;
300
301    private static final String TAG = "TelecomManager";
302
303    private final Context mContext;
304
305    /**
306     * @hide
307     */
308    public static TelecomManager from(Context context) {
309        return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
310    }
311
312    /**
313     * @hide
314     */
315    public TelecomManager(Context context) {
316        Context appContext = context.getApplicationContext();
317        if (appContext != null) {
318            mContext = appContext;
319        } else {
320            mContext = context;
321        }
322    }
323
324    /**
325     * Return the {@link PhoneAccount} which is the user-chosen default for making outgoing phone
326     * calls with a specified URI scheme. This {@code PhoneAccount} will always be a member of the
327     * list which is returned from calling {@link #getEnabledPhoneAccounts()}.
328     * <p>
329     * Apps must be prepared for this method to return {@code null}, indicating that there currently
330     * exists no user-chosen default {@code PhoneAccount}. In this case, apps wishing to initiate a
331     * phone call must either create their {@link android.content.Intent#ACTION_CALL} or
332     * {@link android.content.Intent#ACTION_DIAL} {@code Intent} with no
333     * {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE}, or present the user with an affordance to
334     * select one of the elements of {@link #getEnabledPhoneAccounts()}.
335     * <p>
336     * An {@link android.content.Intent#ACTION_CALL} or {@link android.content.Intent#ACTION_DIAL}
337     * {@code Intent} with no {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE} is valid, and
338     * subsequent steps in the phone call flow are responsible for presenting the user with an
339     * affordance, if necessary, to choose a {@code PhoneAccount}.
340     *
341     * @param uriScheme The URI scheme.
342     */
343    public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
344        try {
345            if (isServiceConnected()) {
346                return getTelecomService().getDefaultOutgoingPhoneAccount(uriScheme);
347            }
348        } catch (RemoteException e) {
349            Log.e(TAG, "Error calling ITelecomService#getDefaultOutgoingPhoneAccount", e);
350        }
351        return null;
352    }
353
354    /**
355     * Return the {@link PhoneAccount} which is the user-chosen default for making outgoing phone
356     * calls. This {@code PhoneAccount} will always be a member of the list which is returned from
357     * calling {@link #getEnabledPhoneAccounts()}
358     *
359     * Apps must be prepared for this method to return {@code null}, indicating that there currently
360     * exists no user-chosen default {@code PhoneAccount}.
361     *
362     * @return The user outgoing phone account selected by the user.
363     * @hide
364     */
365    public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
366        try {
367            if (isServiceConnected()) {
368                return getTelecomService().getUserSelectedOutgoingPhoneAccount();
369            }
370        } catch (RemoteException e) {
371            Log.e(TAG, "Error calling ITelecomService#getUserSelectedOutgoingPhoneAccount", e);
372        }
373        return null;
374    }
375
376    /**
377     * Sets the default account for making outgoing phone calls.
378     * @hide
379     */
380    public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
381        try {
382            if (isServiceConnected()) {
383                getTelecomService().setUserSelectedOutgoingPhoneAccount(accountHandle);
384            }
385        } catch (RemoteException e) {
386            Log.e(TAG, "Error calling ITelecomService#setUserSelectedOutgoingPhoneAccount");
387        }
388    }
389
390    /**
391     * Return a list of enabled {@link PhoneAccountHandle}s which can be used to make and receive
392     * phone calls.
393     *
394     * @see #EXTRA_PHONE_ACCOUNT_HANDLE
395     * @return A list of {@code PhoneAccountHandle} objects.
396     */
397    public List<PhoneAccountHandle> getEnabledPhoneAccounts() {
398        try {
399            if (isServiceConnected()) {
400                return getTelecomService().getEnabledPhoneAccounts();
401            }
402        } catch (RemoteException e) {
403            Log.e(TAG, "Error calling ITelecomService#getEnabledPhoneAccounts", e);
404        }
405        return new ArrayList<>();
406    }
407
408    /**
409     * Returns the current SIM call manager. Apps must be prepared for this method to return
410     * {@code null}, indicating that there currently exists no user-chosen default
411     * {@code PhoneAccount}.
412     * @return The phone account handle of the current sim call manager.
413     * @hide
414     */
415    public PhoneAccountHandle getSimCallManager() {
416        try {
417            if (isServiceConnected()) {
418                return getTelecomService().getSimCallManager();
419            }
420        } catch (RemoteException e) {
421            Log.e(TAG, "Error calling ITelecomService#getSimCallManager");
422        }
423        return null;
424    }
425
426    /**
427     * Sets the SIM call manager to the specified phone account.
428     * @param accountHandle The phone account handle of the account to set as the sim call manager.
429     * @hide
430     */
431    public void setSimCallManager(PhoneAccountHandle accountHandle) {
432        try {
433            if (isServiceConnected()) {
434                getTelecomService().setSimCallManager(accountHandle);
435            }
436        } catch (RemoteException e) {
437            Log.e(TAG, "Error calling ITelecomService#setSimCallManager");
438        }
439    }
440
441    /**
442     * Returns the list of registered SIM call managers.
443     * @return List of registered SIM call managers.
444     * @hide
445     */
446    public List<PhoneAccountHandle> getSimCallManagers() {
447        try {
448            if (isServiceConnected()) {
449                return getTelecomService().getSimCallManagers();
450            }
451        } catch (RemoteException e) {
452            Log.e(TAG, "Error calling ITelecomService#getSimCallManagers");
453        }
454        return new ArrayList<>();
455    }
456
457    /**
458     * Returns the current connection manager. Apps must be prepared for this method to return
459     * {@code null}, indicating that there currently exists no user-chosen default
460     * {@code PhoneAccount}.
461     *
462     * @return The phone account handle of the current connection manager.
463     */
464    public PhoneAccountHandle getConnectionManager() {
465        return getSimCallManager();
466    }
467
468    /**
469     * Returns a list of the enabled {@link PhoneAccountHandle}s which can be used to make and
470     * receive phone calls which support the specified URI scheme.
471     * <P>
472     * For example, invoking with {@code "tel"} will find all {@link PhoneAccountHandle}s which
473     * support telephone calls (e.g. URIs such as {@code tel:555-555-1212}).  Invoking with
474     * {@code "sip"} will find all {@link PhoneAccountHandle}s which support SIP calls (e.g. URIs
475     * such as {@code sip:example@sipexample.com}).
476     *
477     * @param uriScheme The URI scheme.
478     * @return A list of {@code PhoneAccountHandle} objects supporting the URI scheme.
479     */
480    public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) {
481        try {
482            if (isServiceConnected()) {
483                return getTelecomService().getPhoneAccountsSupportingScheme(uriScheme);
484            }
485        } catch (RemoteException e) {
486            Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsSupportingScheme", e);
487        }
488        return new ArrayList<>();
489    }
490
491    /**
492     * Determine whether the device has more than one account registered and enabled.
493     *
494     * @return {@code true} if the device has more than one account registered and enabled and
495     * {@code false} otherwise.
496     */
497    public boolean hasMultipleEnabledAccounts() {
498        return getEnabledPhoneAccounts().size() > 1;
499    }
500
501    /**
502     * Return the {@link PhoneAccount} for a specified {@link PhoneAccountHandle}. Object includes
503     * resources which can be used in a user interface.
504     *
505     * @param account The {@link PhoneAccountHandle}.
506     * @return The {@link PhoneAccount} object.
507     */
508    public PhoneAccount getPhoneAccount(PhoneAccountHandle account) {
509        try {
510            if (isServiceConnected()) {
511                return getTelecomService().getPhoneAccount(account);
512            }
513        } catch (RemoteException e) {
514            Log.e(TAG, "Error calling ITelecomService#getPhoneAccount", e);
515        }
516        return null;
517    }
518
519    /**
520     * Returns a count of enabled and disabled {@link PhoneAccount}s.
521     *
522     * @return The count of enabled and disabled {@link PhoneAccount}s.
523     * @hide
524     */
525    @SystemApi
526    public int getAllPhoneAccountsCount() {
527        try {
528            if (isServiceConnected()) {
529                return getTelecomService().getAllPhoneAccountsCount();
530            }
531        } catch (RemoteException e) {
532            Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccountsCount", e);
533        }
534        return 0;
535    }
536
537    /**
538     * Returns a list of all {@link PhoneAccount}s.
539     *
540     * @return All {@link PhoneAccount}s.
541     * @hide
542     */
543    @SystemApi
544    public List<PhoneAccount> getAllPhoneAccounts() {
545        try {
546            if (isServiceConnected()) {
547                return getTelecomService().getAllPhoneAccounts();
548            }
549        } catch (RemoteException e) {
550            Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccounts", e);
551        }
552        return Collections.EMPTY_LIST;
553    }
554
555    /**
556     * Returns a list of all {@link PhoneAccountHandle}s.
557     *
558     * @return All {@link PhoneAccountHandle}s.
559     * @hide
560     */
561    @SystemApi
562    public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
563        try {
564            if (isServiceConnected()) {
565                return getTelecomService().getAllPhoneAccountHandles();
566            }
567        } catch (RemoteException e) {
568            Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccountHandles", e);
569        }
570        return Collections.EMPTY_LIST;
571    }
572
573    /**
574     * Enables or disables a {@link PhoneAccount}.
575     *
576     * @param account The {@link PhoneAccountHandle} to enable or disable.
577     * @param isEnabled {@code True} if the phone account should be enabled.
578     * @hide
579     */
580    @SystemApi
581    public void setPhoneAccountEnabled(PhoneAccountHandle account, boolean isEnabled) {
582        try {
583            if (isServiceConnected()) {
584                getTelecomService().setPhoneAccountEnabled(account, isEnabled);
585            }
586        } catch (RemoteException e) {
587            Log.e(TAG, "Error calling ITelecomService#setPhoneAccountEnabled", e);
588        }
589    }
590
591    /**
592     * Register a {@link PhoneAccount} for use by the system.
593     *
594     * @param account The complete {@link PhoneAccount}.
595     */
596    public void registerPhoneAccount(PhoneAccount account) {
597        try {
598            if (isServiceConnected()) {
599                getTelecomService().registerPhoneAccount(account);
600            }
601        } catch (RemoteException e) {
602            Log.e(TAG, "Error calling ITelecomService#registerPhoneAccount", e);
603        }
604    }
605
606    /**
607     * Remove a {@link PhoneAccount} registration from the system.
608     *
609     * @param accountHandle A {@link PhoneAccountHandle} for the {@link PhoneAccount} to unregister.
610     */
611    public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
612        try {
613            if (isServiceConnected()) {
614                getTelecomService().unregisterPhoneAccount(accountHandle);
615            }
616        } catch (RemoteException e) {
617            Log.e(TAG, "Error calling ITelecomService#unregisterPhoneAccount", e);
618        }
619    }
620
621    /**
622     * Remove all Accounts that belong to the calling package from the system.
623     */
624    @SystemApi
625    public void clearAccounts() {
626        try {
627            if (isServiceConnected()) {
628                getTelecomService().clearAccounts(mContext.getPackageName());
629            }
630        } catch (RemoteException e) {
631            Log.e(TAG, "Error calling ITelecomService#clearAccounts", e);
632        }
633    }
634
635    /**
636     * @hide
637     */
638    @SystemApi
639    public ComponentName getDefaultPhoneApp() {
640        try {
641            if (isServiceConnected()) {
642                return getTelecomService().getDefaultPhoneApp();
643            }
644        } catch (RemoteException e) {
645            Log.e(TAG, "RemoteException attempting to get the default phone app.", e);
646        }
647        return null;
648    }
649
650    /**
651     * Returns whether there is an ongoing phone call (can be in dialing, ringing, active or holding
652     * states).
653     * <p>
654     * Requires permission: {@link android.Manifest.permission#READ_PHONE_STATE}
655     * </p>
656     */
657    @SystemApi
658    public boolean isInCall() {
659        try {
660            if (isServiceConnected()) {
661                return getTelecomService().isInCall();
662            }
663        } catch (RemoteException e) {
664            Log.e(TAG, "RemoteException attempting to get default phone app.", e);
665        }
666        return false;
667    }
668
669    /**
670     * Returns whether there currently exists is a ringing incoming-call.
671     *
672     * @hide
673     */
674    @SystemApi
675    public boolean isRinging() {
676        try {
677            if (isServiceConnected()) {
678                return getTelecomService().isRinging();
679            }
680        } catch (RemoteException e) {
681            Log.e(TAG, "RemoteException attempting to get ringing state of phone app.", e);
682        }
683        return false;
684    }
685
686    /**
687     * Ends an ongoing call.
688     * TODO: L-release - need to convert all invocations of ITelecomService#endCall to use this
689     * method (clockwork & gearhead).
690     * @hide
691     */
692    @SystemApi
693    public boolean endCall() {
694        try {
695            if (isServiceConnected()) {
696                return getTelecomService().endCall();
697            }
698        } catch (RemoteException e) {
699            Log.e(TAG, "Error calling ITelecomService#endCall", e);
700        }
701        return false;
702    }
703
704    /**
705     * If there is a ringing incoming call, this method accepts the call on behalf of the user.
706     * TODO: L-release - need to convert all invocation of ITelecmmService#answerRingingCall to use
707     * this method (clockwork & gearhead).
708     *
709     * @hide
710     */
711    @SystemApi
712    public void acceptRingingCall() {
713        try {
714            if (isServiceConnected()) {
715                getTelecomService().acceptRingingCall();
716            }
717        } catch (RemoteException e) {
718            Log.e(TAG, "Error calling ITelecomService#acceptRingingCall", e);
719        }
720    }
721
722    /**
723     * Silences the ringer if a ringing call exists.
724     *
725     * @hide
726     */
727    @SystemApi
728    public void silenceRinger() {
729        try {
730            if (isServiceConnected()) {
731                getTelecomService().silenceRinger();
732            }
733        } catch (RemoteException e) {
734            Log.e(TAG, "Error calling ITelecomService#silenceRinger", e);
735        }
736    }
737
738    /**
739     * Returns whether TTY is supported on this device.
740     *
741     * @hide
742     */
743    @SystemApi
744    public boolean isTtySupported() {
745        try {
746            if (isServiceConnected()) {
747                return getTelecomService().isTtySupported();
748            }
749        } catch (RemoteException e) {
750            Log.e(TAG, "RemoteException attempting to get TTY supported state.", e);
751        }
752        return false;
753    }
754
755    /**
756     * Returns the current TTY mode of the device. For TTY to be on the user must enable it in
757     * settings and have a wired headset plugged in.
758     * Valid modes are:
759     * - {@link TelecomManager#TTY_MODE_OFF}
760     * - {@link TelecomManager#TTY_MODE_FULL}
761     * - {@link TelecomManager#TTY_MODE_HCO}
762     * - {@link TelecomManager#TTY_MODE_VCO}
763     * @hide
764     */
765    public int getCurrentTtyMode() {
766        try {
767            if (isServiceConnected()) {
768                return getTelecomService().getCurrentTtyMode();
769            }
770        } catch (RemoteException e) {
771            Log.e(TAG, "RemoteException attempting to get the current TTY mode.", e);
772        }
773        return TTY_MODE_OFF;
774    }
775
776    /**
777     * Registers a new incoming call. A {@link ConnectionService} should invoke this method when it
778     * has an incoming call. The specified {@link PhoneAccountHandle} must have been registered
779     * with {@link #registerPhoneAccount} and subsequently enabled by the user within the phone's
780     * settings. Once invoked, this method will cause the system to bind to the
781     * {@link ConnectionService} associated with the {@link PhoneAccountHandle} and request
782     * additional information about the call (See
783     * {@link ConnectionService#onCreateIncomingConnection}) before starting the incoming call UI.
784     *
785     * @param phoneAccount A {@link PhoneAccountHandle} registered with
786     *            {@link #registerPhoneAccount}.
787     * @param extras A bundle that will be passed through to
788     *            {@link ConnectionService#onCreateIncomingConnection}.
789     */
790    public void addNewIncomingCall(PhoneAccountHandle phoneAccount, Bundle extras) {
791        try {
792            if (isServiceConnected()) {
793                getTelecomService().addNewIncomingCall(
794                        phoneAccount, extras == null ? new Bundle() : extras);
795            }
796        } catch (RemoteException e) {
797            Log.e(TAG, "RemoteException adding a new incoming call: " + phoneAccount, e);
798        }
799    }
800
801    /**
802     * Processes the specified dial string as an MMI code.
803     * MMI codes are any sequence of characters entered into the dialpad that contain a "*" or "#".
804     * Some of these sequences launch special behavior through handled by Telephony.
805     * <p>
806     * Requires that the method-caller be set as the system dialer app.
807     * </p>
808     *
809     * @param dialString The digits to dial.
810     * @return True if the digits were processed as an MMI code, false otherwise.
811     */
812    public boolean handleMmi(String dialString) {
813        ITelecomService service = getTelecomService();
814        if (service != null) {
815            try {
816                return service.handlePinMmi(dialString);
817            } catch (RemoteException e) {
818                Log.e(TAG, "Error calling ITelecomService#handlePinMmi", e);
819            }
820        }
821        return false;
822    }
823
824    /**
825     * Removes the missed-call notification if one is present.
826     * <p>
827     * Requires that the method-caller be set as the system dialer app.
828     * </p>
829     */
830    public void cancelMissedCallsNotification() {
831        ITelecomService service = getTelecomService();
832        if (service != null) {
833            try {
834                service.cancelMissedCallsNotification();
835            } catch (RemoteException e) {
836                Log.e(TAG, "Error calling ITelecomService#cancelMissedCallsNotification", e);
837            }
838        }
839    }
840
841    /**
842     * Brings the in-call screen to the foreground if there is an ongoing call. If there is
843     * currently no ongoing call, then this method does nothing.
844     * <p>
845     * Requires that the method-caller be set as the system dialer app or have the
846     * {@link android.Manifest.permission#READ_PHONE_STATE} permission.
847     * </p>
848     *
849     * @param showDialpad Brings up the in-call dialpad as part of showing the in-call screen.
850     */
851    public void showInCallScreen(boolean showDialpad) {
852        ITelecomService service = getTelecomService();
853        if (service != null) {
854            try {
855                service.showInCallScreen(showDialpad);
856            } catch (RemoteException e) {
857                Log.e(TAG, "Error calling ITelecomService#showCallScreen", e);
858            }
859        }
860    }
861
862    private ITelecomService getTelecomService() {
863        return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
864    }
865
866    private boolean isServiceConnected() {
867        boolean isConnected = getTelecomService() != null;
868        if (!isConnected) {
869            Log.w(TAG, "Telecom Service not found.");
870        }
871        return isConnected;
872    }
873}
874