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