Home | History | Annotate | Download | only in telecom
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.contacts.common.compat.telecom;
     17 
     18 import android.app.Activity;
     19 import android.content.Intent;
     20 import android.content.Context;
     21 import android.net.Uri;
     22 import android.support.annotation.Nullable;
     23 import android.telecom.PhoneAccount;
     24 import android.telecom.PhoneAccountHandle;
     25 import android.telecom.TelecomManager;
     26 import android.telephony.PhoneNumberUtils;
     27 import android.telephony.TelephonyManager;
     28 import android.text.TextUtils;
     29 
     30 import com.android.contacts.common.compat.CompatUtils;
     31 
     32 import java.lang.reflect.Method;
     33 import java.util.ArrayList;
     34 import java.util.List;
     35 
     36 /**
     37  * Compatibility class for {@link android.telecom.TelecomManager}.
     38  */
     39 public class TelecomManagerCompat {
     40     public static final String TELECOM_MANAGER_CLASS = "android.telecom.TelecomManager";
     41     /**
     42      * Places a new outgoing call to the provided address using the system telecom service with
     43      * the specified intent.
     44      *
     45      * @param activity {@link Activity} used to start another activity for the given intent
     46      * @param telecomManager the {@link TelecomManager} used to place a call, if possible
     47      * @param intent the intent for the call
     48      */
     49     public static void placeCall(@Nullable Activity activity,
     50             @Nullable TelecomManager telecomManager, @Nullable Intent intent) {
     51         if (activity == null || telecomManager == null || intent == null) {
     52             return;
     53         }
     54         if (CompatUtils.isMarshmallowCompatible()) {
     55             telecomManager.placeCall(intent.getData(), intent.getExtras());
     56             return;
     57         }
     58         activity.startActivityForResult(intent, 0);
     59     }
     60 
     61     /**
     62      * Get the URI for running an adn query.
     63      *
     64      * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
     65      * @param accountHandle The handle for the account to derive an adn query URI for or
     66      * {@code null} to return a URI which will use the default account.
     67      * @return The URI (with the content:// scheme) specific to the specified {@link PhoneAccount}
     68      * for the the content retrieve.
     69      */
     70     public static Uri getAdnUriForPhoneAccount(@Nullable TelecomManager telecomManager,
     71             PhoneAccountHandle accountHandle) {
     72         if (telecomManager != null && (CompatUtils.isMarshmallowCompatible()
     73                 || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS, "getAdnUriForPhoneAccount",
     74                         PhoneAccountHandle.class))) {
     75             return telecomManager.getAdnUriForPhoneAccount(accountHandle);
     76         }
     77         return Uri.parse("content://icc/adn");
     78     }
     79 
     80     /**
     81      * Returns a list of {@link PhoneAccountHandle}s which can be used to make and receive phone
     82      * calls. The returned list includes only those accounts which have been explicitly enabled
     83      * by the user.
     84      *
     85      * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
     86      * @return A list of PhoneAccountHandle objects.
     87      */
     88     public static List<PhoneAccountHandle> getCallCapablePhoneAccounts(
     89             @Nullable TelecomManager telecomManager) {
     90         if (telecomManager != null && (CompatUtils.isMarshmallowCompatible()
     91                 || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS,
     92                         "getCallCapablePhoneAccounts"))) {
     93             return telecomManager.getCallCapablePhoneAccounts();
     94         }
     95         return new ArrayList<>();
     96     }
     97 
     98     /**
     99      * Used to determine the currently selected default dialer package.
    100      *
    101      * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
    102      * @return package name for the default dialer package or null if no package has been
    103      *         selected as the default dialer.
    104      */
    105     @Nullable
    106     public static String getDefaultDialerPackage(@Nullable TelecomManager telecomManager) {
    107         if (telecomManager != null && CompatUtils.isDefaultDialerCompatible()) {
    108             return telecomManager.getDefaultDialerPackage();
    109         }
    110         return null;
    111     }
    112 
    113     /**
    114      * Return the {@link PhoneAccount} which will be used to place outgoing calls to addresses with
    115      * the specified {@code uriScheme}. This PhoneAccount will always be a member of the
    116      * list which is returned from invoking {@link TelecomManager#getCallCapablePhoneAccounts()}.
    117      * The specific account returned depends on the following priorities:
    118      *
    119      * 1. If the user-selected default PhoneAccount supports the specified scheme, it will
    120      * be returned.
    121      * 2. If there exists only one PhoneAccount that supports the specified scheme, it
    122      * will be returned.
    123      *
    124      * If no PhoneAccount fits the criteria above, this method will return {@code null}.
    125      *
    126      * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
    127      * @param uriScheme The URI scheme.
    128      * @return The {@link PhoneAccountHandle} corresponding to the account to be used.
    129      */
    130     @Nullable
    131     public static PhoneAccountHandle getDefaultOutgoingPhoneAccount(
    132             @Nullable TelecomManager telecomManager, @Nullable String uriScheme) {
    133         if (telecomManager != null && (CompatUtils.isMarshmallowCompatible()
    134                 || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS,
    135                         "getDefaultOutgoingPhoneAccount", String.class))) {
    136             return telecomManager.getDefaultOutgoingPhoneAccount(uriScheme);
    137         }
    138         return null;
    139     }
    140 
    141     /**
    142      * Return the line 1 phone number for given phone account.
    143      *
    144      * @param telecomManager the {@link TelecomManager} to use in the event that
    145      *    {@link TelecomManager#getLine1Number(PhoneAccountHandle)} is available
    146      * @param telephonyManager the {@link TelephonyManager} to use if TelecomManager#getLine1Number
    147      *    is unavailable
    148      * @param phoneAccountHandle the phoneAccountHandle upon which to check the line one number
    149      * @return the line one number
    150      */
    151     @Nullable
    152     public static String getLine1Number(@Nullable TelecomManager telecomManager,
    153             @Nullable TelephonyManager telephonyManager,
    154             @Nullable PhoneAccountHandle phoneAccountHandle) {
    155         if (telecomManager != null && CompatUtils.isMarshmallowCompatible()) {
    156             return telecomManager.getLine1Number(phoneAccountHandle);
    157         }
    158         if (telephonyManager != null) {
    159             return telephonyManager.getLine1Number();
    160         }
    161         return null;
    162     }
    163 
    164     /**
    165      * Return whether a given phone number is the configured voicemail number for a
    166      * particular phone account.
    167      *
    168      * @param telecomManager the {@link TelecomManager} to use for checking the number.
    169      * @param accountHandle The handle for the account to check the voicemail number against
    170      * @param number The number to look up.
    171      */
    172     public static boolean isVoiceMailNumber(@Nullable TelecomManager telecomManager,
    173             @Nullable PhoneAccountHandle accountHandle, @Nullable String number) {
    174         if (telecomManager != null && (CompatUtils.isMarshmallowCompatible()
    175                 || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS, "isVoiceMailNumber",
    176                         PhoneAccountHandle.class, String.class))) {
    177             return telecomManager.isVoiceMailNumber(accountHandle, number);
    178         }
    179         return PhoneNumberUtils.isVoiceMailNumber(number);
    180     }
    181 
    182     /**
    183      * Return the {@link PhoneAccount} for a specified {@link PhoneAccountHandle}. Object includes
    184      * resources which can be used in a user interface.
    185      *
    186      * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
    187      * @param account The {@link PhoneAccountHandle}.
    188      * @return The {@link PhoneAccount} object or null if it doesn't exist.
    189      */
    190     @Nullable
    191     public static PhoneAccount getPhoneAccount(@Nullable TelecomManager telecomManager,
    192             @Nullable PhoneAccountHandle accountHandle) {
    193         if (telecomManager != null && (CompatUtils.isMethodAvailable(
    194                 TELECOM_MANAGER_CLASS, "getPhoneAccount", PhoneAccountHandle.class))) {
    195             return telecomManager.getPhoneAccount(accountHandle);
    196         }
    197         return null;
    198     }
    199 
    200     /**
    201      * Return the voicemail number for a given phone account.
    202      *
    203      * @param telecomManager The {@link TelecomManager} object to use for retrieving the voicemail
    204      * number if accountHandle is specified.
    205      * @param telephonyManager The {@link TelephonyManager} object to use for retrieving the
    206      * voicemail number if accountHandle is null.
    207      * @param accountHandle The handle for the phone account.
    208      * @return The voicemail number for the phone account, and {@code null} if one has not been
    209      *         configured.
    210      */
    211     @Nullable
    212     public static String getVoiceMailNumber(@Nullable TelecomManager telecomManager,
    213             @Nullable TelephonyManager telephonyManager,
    214             @Nullable PhoneAccountHandle accountHandle) {
    215         if (telecomManager != null && (CompatUtils.isMethodAvailable(
    216                 TELECOM_MANAGER_CLASS, "getVoiceMailNumber", PhoneAccountHandle.class))) {
    217             return telecomManager.getVoiceMailNumber(accountHandle);
    218         } else if (telephonyManager != null){
    219             return telephonyManager.getVoiceMailNumber();
    220         }
    221         return null;
    222     }
    223 
    224     /**
    225      * Processes the specified dial string as an MMI code.
    226      * MMI codes are any sequence of characters entered into the dialpad that contain a "*" or "#".
    227      * Some of these sequences launch special behavior through handled by Telephony.
    228      *
    229      * @param telecomManager The {@link TelecomManager} object to use for handling MMI.
    230      * @param dialString The digits to dial.
    231      * @return {@code true} if the digits were processed as an MMI code, {@code false} otherwise.
    232      */
    233     public static boolean handleMmi(@Nullable TelecomManager telecomManager,
    234             @Nullable String dialString, @Nullable PhoneAccountHandle accountHandle) {
    235         if (telecomManager == null || TextUtils.isEmpty(dialString)) {
    236             return false;
    237         }
    238         if (CompatUtils.isMarshmallowCompatible()) {
    239             return telecomManager.handleMmi(dialString, accountHandle);
    240         }
    241 
    242         Object handleMmiResult = CompatUtils.invokeMethod(
    243                 telecomManager,
    244                 "handleMmi",
    245                 new Class<?>[] {PhoneAccountHandle.class, String.class},
    246                 new Object[] {accountHandle, dialString});
    247         if (handleMmiResult != null) {
    248             return (boolean) handleMmiResult;
    249         }
    250 
    251         return telecomManager.handleMmi(dialString);
    252     }
    253 
    254     /**
    255      * Silences the ringer if a ringing call exists. Noop if {@link TelecomManager#silenceRinger()}
    256      * is unavailable.
    257      *
    258      * @param telecomManager the TelecomManager to use to silence the ringer.
    259      */
    260     public static void silenceRinger(@Nullable TelecomManager telecomManager) {
    261         if (telecomManager != null && (CompatUtils.isMarshmallowCompatible() || CompatUtils
    262                 .isMethodAvailable(TELECOM_MANAGER_CLASS, "silenceRinger"))) {
    263             telecomManager.silenceRinger();
    264         }
    265     }
    266 
    267     /**
    268      * Returns the current SIM call manager. Apps must be prepared for this method to return null,
    269      * indicating that there currently exists no registered SIM call manager.
    270      *
    271      * @param telecomManager the {@link TelecomManager} to use to fetch the SIM call manager.
    272      * @return The phone account handle of the current sim call manager.
    273      */
    274     @Nullable
    275     public static PhoneAccountHandle getSimCallManager(TelecomManager telecomManager) {
    276         if (telecomManager != null && (CompatUtils.isMarshmallowCompatible() || CompatUtils
    277                 .isMethodAvailable(TELECOM_MANAGER_CLASS, "getSimCallManager"))) {
    278             return telecomManager.getSimCallManager();
    279         }
    280         return null;
    281     }
    282 }
    283