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