TelecomManager.java revision c66f3baa42b8a732952abf1967c68f77d3e26131
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     * @hide
523     */
524    public List<PhoneAccountHandle> getCallCapablePhoneAccounts() {
525        try {
526            if (isServiceConnected()) {
527                return getTelecomService().getCallCapablePhoneAccounts();
528            }
529        } catch (RemoteException e) {
530            Log.e(TAG, "Error calling ITelecomService#getCallCapablePhoneAccounts", e);
531        }
532        return new ArrayList<>();
533    }
534
535    /**
536     * Determine whether the device has more than one account registered that can make and receive
537     * phone calls.
538     *
539     * @return {@code true} if the device has more than one account registered and {@code false}
540     * otherwise.
541     * @hide
542     */
543    @SystemApi
544    public boolean hasMultipleCallCapableAccounts() {
545        return getCallCapablePhoneAccounts().size() > 1;
546    }
547
548    /**
549     *  Returns a list of all {@link PhoneAccount}s registered for the calling package.
550     *
551     * @return A list of {@code PhoneAccountHandle} objects.
552     * @hide
553     */
554    @SystemApi
555    public List<PhoneAccountHandle> getPhoneAccountsForPackage() {
556        try {
557            if (isServiceConnected()) {
558                return getTelecomService().getPhoneAccountsForPackage(mContext.getPackageName());
559            }
560        } catch (RemoteException e) {
561            Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsForPackage", e);
562        }
563        return null;
564    }
565
566    /**
567     * Return the {@link PhoneAccount} for a specified {@link PhoneAccountHandle}. Object includes
568     * resources which can be used in a user interface.
569     *
570     * @param account The {@link PhoneAccountHandle}.
571     * @return The {@link PhoneAccount} object.
572     */
573    public PhoneAccount getPhoneAccount(PhoneAccountHandle account) {
574        try {
575            if (isServiceConnected()) {
576                return getTelecomService().getPhoneAccount(account);
577            }
578        } catch (RemoteException e) {
579            Log.e(TAG, "Error calling ITelecomService#getPhoneAccount", e);
580        }
581        return null;
582    }
583
584    /**
585     * Returns a count of all {@link PhoneAccount}s.
586     *
587     * @return The count of {@link PhoneAccount}s.
588     * @hide
589     */
590    @SystemApi
591    public int getAllPhoneAccountsCount() {
592        try {
593            if (isServiceConnected()) {
594                return getTelecomService().getAllPhoneAccountsCount();
595            }
596        } catch (RemoteException e) {
597            Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccountsCount", e);
598        }
599        return 0;
600    }
601
602    /**
603     * Returns a list of all {@link PhoneAccount}s.
604     *
605     * @return All {@link PhoneAccount}s.
606     * @hide
607     */
608    @SystemApi
609    public List<PhoneAccount> getAllPhoneAccounts() {
610        try {
611            if (isServiceConnected()) {
612                return getTelecomService().getAllPhoneAccounts();
613            }
614        } catch (RemoteException e) {
615            Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccounts", e);
616        }
617        return Collections.EMPTY_LIST;
618    }
619
620    /**
621     * Returns a list of all {@link PhoneAccountHandle}s.
622     *
623     * @return All {@link PhoneAccountHandle}s.
624     * @hide
625     */
626    @SystemApi
627    public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
628        try {
629            if (isServiceConnected()) {
630                return getTelecomService().getAllPhoneAccountHandles();
631            }
632        } catch (RemoteException e) {
633            Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccountHandles", e);
634        }
635        return Collections.EMPTY_LIST;
636    }
637
638    /**
639     * Register a {@link PhoneAccount} for use by the system. When registering
640     * {@link PhoneAccount}s, existing registrations will be overwritten if the
641     * {@link PhoneAccountHandle} matches that of a {@link PhoneAccount} which is already
642     * registered. Once registered, the {@link PhoneAccount} is listed to the user as an option
643     * when placing calls. The user may still need to enable the {@link PhoneAccount} within
644     * the phone app settings before the account is usable.
645     * <p>
646     * A {@link SecurityException} will be thrown if an app tries to register a
647     * {@link PhoneAccountHandle} where the package name specified within
648     * {@link PhoneAccountHandle#getComponentName()} does not match the package name of the app.
649     *
650     * @param account The complete {@link PhoneAccount}.
651     *
652     * @hide
653     */
654    @SystemApi
655    public void registerPhoneAccount(PhoneAccount account) {
656        try {
657            if (isServiceConnected()) {
658                getTelecomService().registerPhoneAccount(account);
659            }
660        } catch (RemoteException e) {
661            Log.e(TAG, "Error calling ITelecomService#registerPhoneAccount", e);
662        }
663    }
664
665    /**
666     * Remove a {@link PhoneAccount} registration from the system.
667     *
668     * @param accountHandle A {@link PhoneAccountHandle} for the {@link PhoneAccount} to unregister.
669     * @hide
670     */
671    @SystemApi
672    public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
673        try {
674            if (isServiceConnected()) {
675                getTelecomService().unregisterPhoneAccount(accountHandle);
676            }
677        } catch (RemoteException e) {
678            Log.e(TAG, "Error calling ITelecomService#unregisterPhoneAccount", e);
679        }
680    }
681
682    /**
683     * Remove all Accounts that belong to the calling package from the system.
684     * @hide
685     */
686    @SystemApi
687    public void clearAccounts() {
688        try {
689            if (isServiceConnected()) {
690                getTelecomService().clearAccounts(mContext.getPackageName());
691            }
692        } catch (RemoteException e) {
693            Log.e(TAG, "Error calling ITelecomService#clearAccounts", e);
694        }
695    }
696
697    /**
698     * Remove all Accounts that belong to the specified package from the system.
699     * @hide
700     */
701    public void clearAccountsForPackage(String packageName) {
702        try {
703            if (isServiceConnected() && !TextUtils.isEmpty(packageName)) {
704                getTelecomService().clearAccounts(packageName);
705            }
706        } catch (RemoteException e) {
707            Log.e(TAG, "Error calling ITelecomService#clearAccountsForPackage", e);
708        }
709    }
710
711    /**
712     * @hide
713     */
714    @SystemApi
715    public ComponentName getDefaultPhoneApp() {
716        try {
717            if (isServiceConnected()) {
718                return getTelecomService().getDefaultPhoneApp();
719            }
720        } catch (RemoteException e) {
721            Log.e(TAG, "RemoteException attempting to get the default phone app.", e);
722        }
723        return null;
724    }
725
726    /**
727     * Return whether a given phone number is the configured voicemail number for a
728     * particular phone account.
729     *
730     * @param accountHandle The handle for the account to check the voicemail number against
731     * @param number The number to look up.
732     *
733     * @hide
734     */
735    @SystemApi
736    public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
737        try {
738            if (isServiceConnected()) {
739                return getTelecomService().isVoiceMailNumber(accountHandle, number);
740            }
741        } catch (RemoteException e) {
742            Log.e(TAG, "RemoteException calling ITelecomService#isVoiceMailNumber.", e);
743        }
744        return false;
745    }
746
747    /**
748     * Return whether a given phone account has a voicemail number configured.
749     *
750     * @param accountHandle The handle for the account to check for a voicemail number.
751     * @return {@code true} If the given phone account has a voicemail number.
752     *
753     * @hide
754     */
755    @SystemApi
756    public boolean hasVoiceMailNumber(PhoneAccountHandle accountHandle) {
757        try {
758            if (isServiceConnected()) {
759                return getTelecomService().hasVoiceMailNumber(accountHandle);
760            }
761        } catch (RemoteException e) {
762            Log.e(TAG, "RemoteException calling ITelecomService#hasVoiceMailNumber.", e);
763        }
764        return false;
765    }
766
767    /**
768     * Return the line 1 phone number for given phone account.
769     *
770     * @param accountHandle The handle for the account retrieve a number for.
771     * @return A string representation of the line 1 phone number.
772     *
773     * @hide
774     */
775    @SystemApi
776    public String getLine1Number(PhoneAccountHandle accountHandle) {
777        try {
778            if (isServiceConnected()) {
779                return getTelecomService().getLine1Number(accountHandle);
780            }
781        } catch (RemoteException e) {
782            Log.e(TAG, "RemoteException calling ITelecomService#getLine1Number.", e);
783        }
784        return null;
785    }
786
787    /**
788     * Returns whether there is an ongoing phone call (can be in dialing, ringing, active or holding
789     * states).
790     * <p>
791     * Requires permission: {@link android.Manifest.permission#READ_PHONE_STATE}
792     * </p>
793     */
794    public boolean isInCall() {
795        try {
796            if (isServiceConnected()) {
797                return getTelecomService().isInCall();
798            }
799        } catch (RemoteException e) {
800            Log.e(TAG, "RemoteException calling isInCall().", e);
801        }
802        return false;
803    }
804
805    /**
806     * Returns one of the following constants that represents the current state of Telecom:
807     *
808     * {@link TelephonyManager#CALL_STATE_RINGING}
809     * {@link TelephonyManager#CALL_STATE_OFFHOOK}
810     * {@link TelephonyManager#CALL_STATE_IDLE}
811     *
812     * Note that this API does not require the
813     * {@link android.Manifest.permission#READ_PHONE_STATE} permission. This is intentional, to
814     * preserve the behavior of {@link TelephonyManager#getCallState()}, which also did not require
815     * the permission.
816     * @hide
817     */
818    @SystemApi
819    public int getCallState() {
820        try {
821            if (isServiceConnected()) {
822                return getTelecomService().getCallState();
823            }
824        } catch (RemoteException e) {
825            Log.d(TAG, "RemoteException calling getCallState().", e);
826        }
827        return TelephonyManager.CALL_STATE_IDLE;
828    }
829
830    /**
831     * Returns whether there currently exists is a ringing incoming-call.
832     *
833     * @hide
834     */
835    @SystemApi
836    public boolean isRinging() {
837        try {
838            if (isServiceConnected()) {
839                return getTelecomService().isRinging();
840            }
841        } catch (RemoteException e) {
842            Log.e(TAG, "RemoteException attempting to get ringing state of phone app.", e);
843        }
844        return false;
845    }
846
847    /**
848     * Ends an ongoing call.
849     * TODO: L-release - need to convert all invocations of ITelecomService#endCall to use this
850     * method (clockwork & gearhead).
851     * @hide
852     */
853    @SystemApi
854    public boolean endCall() {
855        try {
856            if (isServiceConnected()) {
857                return getTelecomService().endCall();
858            }
859        } catch (RemoteException e) {
860            Log.e(TAG, "Error calling ITelecomService#endCall", e);
861        }
862        return false;
863    }
864
865    /**
866     * If there is a ringing incoming call, this method accepts the call on behalf of the user.
867     * TODO: L-release - need to convert all invocation of ITelecmmService#answerRingingCall to use
868     * this method (clockwork & gearhead).
869     *
870     * @hide
871     */
872    @SystemApi
873    public void acceptRingingCall() {
874        try {
875            if (isServiceConnected()) {
876                getTelecomService().acceptRingingCall();
877            }
878        } catch (RemoteException e) {
879            Log.e(TAG, "Error calling ITelecomService#acceptRingingCall", e);
880        }
881    }
882
883    /**
884     * Silences the ringer if a ringing call exists.
885     *
886     * @hide
887     */
888    @SystemApi
889    public void silenceRinger() {
890        try {
891            if (isServiceConnected()) {
892                getTelecomService().silenceRinger();
893            }
894        } catch (RemoteException e) {
895            Log.e(TAG, "Error calling ITelecomService#silenceRinger", e);
896        }
897    }
898
899    /**
900     * Returns whether TTY is supported on this device.
901     *
902     * @hide
903     */
904    @SystemApi
905    public boolean isTtySupported() {
906        try {
907            if (isServiceConnected()) {
908                return getTelecomService().isTtySupported();
909            }
910        } catch (RemoteException e) {
911            Log.e(TAG, "RemoteException attempting to get TTY supported state.", e);
912        }
913        return false;
914    }
915
916    /**
917     * Returns the current TTY mode of the device. For TTY to be on the user must enable it in
918     * settings and have a wired headset plugged in.
919     * Valid modes are:
920     * - {@link TelecomManager#TTY_MODE_OFF}
921     * - {@link TelecomManager#TTY_MODE_FULL}
922     * - {@link TelecomManager#TTY_MODE_HCO}
923     * - {@link TelecomManager#TTY_MODE_VCO}
924     * @hide
925     */
926    public int getCurrentTtyMode() {
927        try {
928            if (isServiceConnected()) {
929                return getTelecomService().getCurrentTtyMode();
930            }
931        } catch (RemoteException e) {
932            Log.e(TAG, "RemoteException attempting to get the current TTY mode.", e);
933        }
934        return TTY_MODE_OFF;
935    }
936
937    /**
938     * Registers a new incoming call. A {@link ConnectionService} should invoke this method when it
939     * has an incoming call. The specified {@link PhoneAccountHandle} must have been registered
940     * with {@link #registerPhoneAccount}. Once invoked, this method will cause the system to bind
941     * to the {@link ConnectionService} associated with the {@link PhoneAccountHandle} and request
942     * additional information about the call (See
943     * {@link ConnectionService#onCreateIncomingConnection}) before starting the incoming call UI.
944     *
945     * @param phoneAccount A {@link PhoneAccountHandle} registered with
946     *            {@link #registerPhoneAccount}.
947     * @param extras A bundle that will be passed through to
948     *            {@link ConnectionService#onCreateIncomingConnection}.
949     * @hide
950     */
951    @SystemApi
952    public void addNewIncomingCall(PhoneAccountHandle phoneAccount, Bundle extras) {
953        try {
954            if (isServiceConnected()) {
955                getTelecomService().addNewIncomingCall(
956                        phoneAccount, extras == null ? new Bundle() : extras);
957            }
958        } catch (RemoteException e) {
959            Log.e(TAG, "RemoteException adding a new incoming call: " + phoneAccount, e);
960        }
961    }
962
963    /**
964     * Registers a new unknown call with Telecom. This can only be called by the system Telephony
965     * service. This is invoked when Telephony detects a new unknown connection that was neither
966     * a new incoming call, nor an user-initiated outgoing call.
967     *
968     * @param phoneAccount A {@link PhoneAccountHandle} registered with
969     *            {@link #registerPhoneAccount}.
970     * @param extras A bundle that will be passed through to
971     *            {@link ConnectionService#onCreateIncomingConnection}.
972     * @hide
973     */
974    @SystemApi
975    public void addNewUnknownCall(PhoneAccountHandle phoneAccount, Bundle extras) {
976        try {
977            if (isServiceConnected()) {
978                getTelecomService().addNewUnknownCall(
979                        phoneAccount, extras == null ? new Bundle() : extras);
980            }
981        } catch (RemoteException e) {
982            Log.e(TAG, "RemoteException adding a new unknown call: " + phoneAccount, e);
983        }
984    }
985
986    /**
987     * Processes the specified dial string as an MMI code.
988     * MMI codes are any sequence of characters entered into the dialpad that contain a "*" or "#".
989     * Some of these sequences launch special behavior through handled by Telephony.
990     * This method uses the default subscription.
991     * <p>
992     * Requires that the method-caller be set as the system dialer app.
993     * </p>
994     *
995     * @param dialString The digits to dial.
996     * @return True if the digits were processed as an MMI code, false otherwise.
997     */
998    public boolean handleMmi(String dialString) {
999        ITelecomService service = getTelecomService();
1000        if (service != null) {
1001            try {
1002                return service.handlePinMmi(dialString);
1003            } catch (RemoteException e) {
1004                Log.e(TAG, "Error calling ITelecomService#handlePinMmi", e);
1005            }
1006        }
1007        return false;
1008    }
1009
1010    /**
1011     * Processes the specified dial string as an MMI code.
1012     * MMI codes are any sequence of characters entered into the dialpad that contain a "*" or "#".
1013     * Some of these sequences launch special behavior through handled by Telephony.
1014     * <p>
1015     * Requires that the method-caller be set as the system dialer app.
1016     * </p>
1017     *
1018     * @param accountHandle The handle for the account the MMI code should apply to.
1019     * @param dialString The digits to dial.
1020     * @return True if the digits were processed as an MMI code, false otherwise.
1021     * @hide
1022     */
1023    @SystemApi
1024    public boolean handleMmi(PhoneAccountHandle accountHandle, String dialString) {
1025        ITelecomService service = getTelecomService();
1026        if (service != null) {
1027            try {
1028                return service.handlePinMmiForPhoneAccount(accountHandle, dialString);
1029            } catch (RemoteException e) {
1030                Log.e(TAG, "Error calling ITelecomService#handlePinMmi", e);
1031            }
1032        }
1033        return false;
1034    }
1035
1036    /**
1037     * @param accountHandle The handle for the account to derive an adn query URI for or
1038     * {@code null} to return a URI which will use the default account.
1039     * @return The URI (with the content:// scheme) specific to the specified {@link PhoneAccount}
1040     * for the the content retrieve.
1041     * @hide
1042     */
1043    @SystemApi
1044    public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
1045        ITelecomService service = getTelecomService();
1046        if (service != null && accountHandle != null) {
1047            try {
1048                return service.getAdnUriForPhoneAccount(accountHandle);
1049            } catch (RemoteException e) {
1050                Log.e(TAG, "Error calling ITelecomService#getAdnUriForPhoneAccount", e);
1051            }
1052        }
1053        return Uri.parse("content://icc/adn");
1054    }
1055
1056    /**
1057     * Removes the missed-call notification if one is present.
1058     * <p>
1059     * Requires that the method-caller be set as the system dialer app.
1060     * </p>
1061     */
1062    public void cancelMissedCallsNotification() {
1063        ITelecomService service = getTelecomService();
1064        if (service != null) {
1065            try {
1066                service.cancelMissedCallsNotification();
1067            } catch (RemoteException e) {
1068                Log.e(TAG, "Error calling ITelecomService#cancelMissedCallsNotification", e);
1069            }
1070        }
1071    }
1072
1073    /**
1074     * Brings the in-call screen to the foreground if there is an ongoing call. If there is
1075     * currently no ongoing call, then this method does nothing.
1076     * <p>
1077     * Requires that the method-caller be set as the system dialer app or have the
1078     * {@link android.Manifest.permission#READ_PHONE_STATE} permission.
1079     * </p>
1080     *
1081     * @param showDialpad Brings up the in-call dialpad as part of showing the in-call screen.
1082     */
1083    public void showInCallScreen(boolean showDialpad) {
1084        ITelecomService service = getTelecomService();
1085        if (service != null) {
1086            try {
1087                service.showInCallScreen(showDialpad);
1088            } catch (RemoteException e) {
1089                Log.e(TAG, "Error calling ITelecomService#showCallScreen", e);
1090            }
1091        }
1092    }
1093
1094    private ITelecomService getTelecomService() {
1095        return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
1096    }
1097
1098    private boolean isServiceConnected() {
1099        boolean isConnected = getTelecomService() != null;
1100        if (!isConnected) {
1101            Log.w(TAG, "Telecom Service not found.");
1102        }
1103        return isConnected;
1104    }
1105}
1106