Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5ae80ee authored by Wenyi Wang's avatar Wenyi Wang
Browse files

DO NOT MERGE Guard against SecurityException in QuickContact

* Also removed some unused methods
* Now, all calls to getCallCapablePhoneAccounts() have been wrapped
  with a try-catch block.

Bug: 31304557

Test: throw a SecurityException manually and verify QuickContact works

Change-Id: I611ef18f88a233e7665b55727d1b9ce53f4d1d7f
parent 860698b8
Loading
Loading
Loading
Loading
+15 −25
Original line number Diff line number Diff line
@@ -115,13 +115,6 @@ public class CallUtil {
        return Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null);
    }

    /**
     * @return Uri that directly dials a user's voicemail inbox.
     */
    public static Uri getVoicemailUri() {
        return Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "", null);
    }

    /**
     * Determines if video calling is available, and if so whether presence checking is available
     * as well.
@@ -166,22 +159,11 @@ public class CallUtil {
            return VIDEO_CALLING_DISABLED;
        } catch (SecurityException e) {
            FeedbackHelper.sendFeedback(context, TAG,
                    "Security exception when querying intent activities", e);
                    "Security exception when getting call capable phone accounts", e);
            return VIDEO_CALLING_DISABLED;
        }
    }

    /**
     * Determines if one of the call capable phone accounts defined supports video calling.
     *
     * @param context The context.
     * @return {@code true} if one of the call capable phone accounts supports video calling,
     *      {@code false} otherwise.
     */
    public static boolean isVideoEnabled(Context context) {
        return (getVideoCallingAvailability(context) & VIDEO_CALLING_ENABLED) != 0;
    }

    /**
     * Determines if one of the call capable phone accounts defined supports calling with a subject
     * specified.
@@ -201,13 +183,21 @@ public class CallUtil {
            return false;
        }

        try {
            List<PhoneAccountHandle> accountHandles = telecommMgr.getCallCapablePhoneAccounts();
            for (PhoneAccountHandle accountHandle : accountHandles) {
                PhoneAccount account = telecommMgr.getPhoneAccount(accountHandle);
            if (account != null && account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_SUBJECT)) {
                if (account != null
                        && account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_SUBJECT)) {
                    return true;
                }
            }
            return false;
        } catch (SecurityException e) {
            FeedbackHelper.sendFeedback(context, TAG,
                    "Security exception when getting call capable phone accounts", e);
            return false;
        }

    }
}
+0 −234
Original line number Diff line number Diff line
@@ -17,27 +17,15 @@ package com.android.contacts.common.compat.telecom;

import android.app.Activity;
import android.content.Intent;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import com.android.contacts.common.compat.CompatUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * Compatibility class for {@link android.telecom.TelecomManager}.
 */
public class TelecomManagerCompat {
    public static final String TELECOM_MANAGER_CLASS = "android.telecom.TelecomManager";
    /**
     * Places a new outgoing call to the provided address using the system telecom service with
     * the specified intent.
@@ -57,226 +45,4 @@ public class TelecomManagerCompat {
        }
        activity.startActivityForResult(intent, 0);
    }

    /**
     * Get the URI for running an adn query.
     *
     * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
     * @param accountHandle The handle for the account to derive an adn query URI for or
     * {@code null} to return a URI which will use the default account.
     * @return The URI (with the content:// scheme) specific to the specified {@link PhoneAccount}
     * for the the content retrieve.
     */
    public static Uri getAdnUriForPhoneAccount(@Nullable TelecomManager telecomManager,
            PhoneAccountHandle accountHandle) {
        if (telecomManager != null && (CompatUtils.isMarshmallowCompatible()
                || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS, "getAdnUriForPhoneAccount",
                        PhoneAccountHandle.class))) {
            return telecomManager.getAdnUriForPhoneAccount(accountHandle);
        }
        return Uri.parse("content://icc/adn");
    }

    /**
     * Returns a list of {@link PhoneAccountHandle}s which can be used to make and receive phone
     * calls. The returned list includes only those accounts which have been explicitly enabled
     * by the user.
     *
     * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
     * @return A list of PhoneAccountHandle objects.
     */
    public static List<PhoneAccountHandle> getCallCapablePhoneAccounts(
            @Nullable TelecomManager telecomManager) {
        if (telecomManager != null && (CompatUtils.isMarshmallowCompatible()
                || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS,
                        "getCallCapablePhoneAccounts"))) {
            return telecomManager.getCallCapablePhoneAccounts();
        }
        return new ArrayList<>();
    }

    /**
     * Used to determine the currently selected default dialer package.
     *
     * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
     * @return package name for the default dialer package or null if no package has been
     *         selected as the default dialer.
     */
    @Nullable
    public static String getDefaultDialerPackage(@Nullable TelecomManager telecomManager) {
        if (telecomManager != null && CompatUtils.isDefaultDialerCompatible()) {
            return telecomManager.getDefaultDialerPackage();
        }
        return null;
    }

    /**
     * Return the {@link PhoneAccount} which will be used to place outgoing calls to addresses with
     * the specified {@code uriScheme}. This PhoneAccount will always be a member of the
     * list which is returned from invoking {@link TelecomManager#getCallCapablePhoneAccounts()}.
     * The specific account returned depends on the following priorities:
     *
     * 1. If the user-selected default PhoneAccount supports the specified scheme, it will
     * be returned.
     * 2. If there exists only one PhoneAccount that supports the specified scheme, it
     * will be returned.
     *
     * If no PhoneAccount fits the criteria above, this method will return {@code null}.
     *
     * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
     * @param uriScheme The URI scheme.
     * @return The {@link PhoneAccountHandle} corresponding to the account to be used.
     */
    @Nullable
    public static PhoneAccountHandle getDefaultOutgoingPhoneAccount(
            @Nullable TelecomManager telecomManager, @Nullable String uriScheme) {
        if (telecomManager != null && (CompatUtils.isMarshmallowCompatible()
                || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS,
                        "getDefaultOutgoingPhoneAccount", String.class))) {
            return telecomManager.getDefaultOutgoingPhoneAccount(uriScheme);
        }
        return null;
    }

    /**
     * Return the line 1 phone number for given phone account.
     *
     * @param telecomManager the {@link TelecomManager} to use in the event that
     *    {@link TelecomManager#getLine1Number(PhoneAccountHandle)} is available
     * @param telephonyManager the {@link TelephonyManager} to use if TelecomManager#getLine1Number
     *    is unavailable
     * @param phoneAccountHandle the phoneAccountHandle upon which to check the line one number
     * @return the line one number
     */
    @Nullable
    public static String getLine1Number(@Nullable TelecomManager telecomManager,
            @Nullable TelephonyManager telephonyManager,
            @Nullable PhoneAccountHandle phoneAccountHandle) {
        if (telecomManager != null && CompatUtils.isMarshmallowCompatible()) {
            return telecomManager.getLine1Number(phoneAccountHandle);
        }
        if (telephonyManager != null) {
            return telephonyManager.getLine1Number();
        }
        return null;
    }

    /**
     * Return whether a given phone number is the configured voicemail number for a
     * particular phone account.
     *
     * @param telecomManager the {@link TelecomManager} to use for checking the number.
     * @param accountHandle The handle for the account to check the voicemail number against
     * @param number The number to look up.
     */
    public static boolean isVoiceMailNumber(@Nullable TelecomManager telecomManager,
            @Nullable PhoneAccountHandle accountHandle, @Nullable String number) {
        if (telecomManager != null && (CompatUtils.isMarshmallowCompatible()
                || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS, "isVoiceMailNumber",
                        PhoneAccountHandle.class, String.class))) {
            return telecomManager.isVoiceMailNumber(accountHandle, number);
        }
        return PhoneNumberUtils.isVoiceMailNumber(number);
    }

    /**
     * Return the {@link PhoneAccount} for a specified {@link PhoneAccountHandle}. Object includes
     * resources which can be used in a user interface.
     *
     * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
     * @param account The {@link PhoneAccountHandle}.
     * @return The {@link PhoneAccount} object or null if it doesn't exist.
     */
    @Nullable
    public static PhoneAccount getPhoneAccount(@Nullable TelecomManager telecomManager,
            @Nullable PhoneAccountHandle accountHandle) {
        if (telecomManager != null && (CompatUtils.isMethodAvailable(
                TELECOM_MANAGER_CLASS, "getPhoneAccount", PhoneAccountHandle.class))) {
            return telecomManager.getPhoneAccount(accountHandle);
        }
        return null;
    }

    /**
     * Return the voicemail number for a given phone account.
     *
     * @param telecomManager The {@link TelecomManager} object to use for retrieving the voicemail
     * number if accountHandle is specified.
     * @param telephonyManager The {@link TelephonyManager} object to use for retrieving the
     * voicemail number if accountHandle is null.
     * @param accountHandle The handle for the phone account.
     * @return The voicemail number for the phone account, and {@code null} if one has not been
     *         configured.
     */
    @Nullable
    public static String getVoiceMailNumber(@Nullable TelecomManager telecomManager,
            @Nullable TelephonyManager telephonyManager,
            @Nullable PhoneAccountHandle accountHandle) {
        if (telecomManager != null && (CompatUtils.isMethodAvailable(
                TELECOM_MANAGER_CLASS, "getVoiceMailNumber", PhoneAccountHandle.class))) {
            return telecomManager.getVoiceMailNumber(accountHandle);
        } else if (telephonyManager != null){
            return telephonyManager.getVoiceMailNumber();
        }
        return null;
    }

    /**
     * Processes the specified dial string as an MMI code.
     * MMI codes are any sequence of characters entered into the dialpad that contain a "*" or "#".
     * Some of these sequences launch special behavior through handled by Telephony.
     *
     * @param telecomManager The {@link TelecomManager} object to use for handling MMI.
     * @param dialString The digits to dial.
     * @return {@code true} if the digits were processed as an MMI code, {@code false} otherwise.
     */
    public static boolean handleMmi(@Nullable TelecomManager telecomManager,
            @Nullable String dialString, @Nullable PhoneAccountHandle accountHandle) {
        if (telecomManager == null || TextUtils.isEmpty(dialString)) {
            return false;
        }
        if (CompatUtils.isMarshmallowCompatible()) {
            return telecomManager.handleMmi(dialString, accountHandle);
        }

        Object handleMmiResult = CompatUtils.invokeMethod(
                telecomManager,
                "handleMmi",
                new Class<?>[] {PhoneAccountHandle.class, String.class},
                new Object[] {accountHandle, dialString});
        if (handleMmiResult != null) {
            return (boolean) handleMmiResult;
        }

        return telecomManager.handleMmi(dialString);
    }

    /**
     * Silences the ringer if a ringing call exists. Noop if {@link TelecomManager#silenceRinger()}
     * is unavailable.
     *
     * @param telecomManager the TelecomManager to use to silence the ringer.
     */
    public static void silenceRinger(@Nullable TelecomManager telecomManager) {
        if (telecomManager != null && (CompatUtils.isMarshmallowCompatible() || CompatUtils
                .isMethodAvailable(TELECOM_MANAGER_CLASS, "silenceRinger"))) {
            telecomManager.silenceRinger();
        }
    }

    /**
     * Returns the current SIM call manager. Apps must be prepared for this method to return null,
     * indicating that there currently exists no registered SIM call manager.
     *
     * @param telecomManager the {@link TelecomManager} to use to fetch the SIM call manager.
     * @return The phone account handle of the current sim call manager.
     */
    @Nullable
    public static PhoneAccountHandle getSimCallManager(TelecomManager telecomManager) {
        if (telecomManager != null && (CompatUtils.isMarshmallowCompatible() || CompatUtils
                .isMethodAvailable(TELECOM_MANAGER_CLASS, "getSimCallManager"))) {
            return telecomManager.getSimCallManager();
        }
        return null;
    }
}