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