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

Commit ef9327f2 authored by Aishwarya Mallampati's avatar Aishwarya Mallampati Committed by Jack Yu
Browse files

Added support for FDN Check in SMS.

If FDN is available and enabled, then sms to only numbers
present in the FDN list are allowed.

Bug: 218262162
Test: Manual
      atest FrameworksTelephonyTests:com.android.internal.telephony.FdnUtilsTest
      atest android.app.appops.cts.AppOpsLoggingTest#sendSms
Merged-In: I77f873fc34380f0101faf629da6d8ff0ec7a65ae
Change-Id: I77f873fc34380f0101faf629da6d8ff0ec7a65ae
parent fde23576
Loading
Loading
Loading
Loading
+17 −42
Original line number Diff line number Diff line
@@ -16,9 +16,6 @@

package com.android.internal.telephony;

import android.content.Context;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import com.android.i18n.phonenumbers.NumberParseException;
@@ -36,7 +33,6 @@ import com.android.internal.telephony.uicc.UiccProfile;
import com.android.telephony.Rlog;

import java.util.ArrayList;
import java.util.Locale;

/**
 * This is a basic utility class for common functions related to Fixed Dialing Numbers
@@ -52,40 +48,30 @@ public class FdnUtils {
     * @param phoneId The phone object id for which the FDN check is performed
     * @param dialStr dialed phone number
     * @param defaultCountryIso country ISO for the subscription associated with this phone
     * @return true if dialStr is blocked due to FDN check.
     * @return {@code true} if dialStr is blocked due to FDN check.
     */
    public static boolean isNumberBlockedByFDN(int phoneId, String dialStr,
            String defaultCountryIso) {
        final UiccCardApplication app = getUiccCardApplication(phoneId);

        if (!isFdnEnabled(app)) {
        if (!isFdnEnabled(phoneId)) {
            return false;
        }

        final ArrayList<AdnRecord> fdnList = getFdnList(app);
        ArrayList<AdnRecord> fdnList = getFdnList(phoneId);
        return !isFDN(dialStr, defaultCountryIso, fdnList);
    }

    /**
     * The following function checks if destination address or smsc is blocked due to FDN.
     * @param context context
     * @param subId subscription ID
     * @param destAddr destination address of the message
     * @param smscAddr smsc address of the subscription
     * @return true if either destAddr or smscAddr is blocked due to FDN.
     * Checks if FDN is enabled
     * @param phoneId The phone object id for which the FDN check is performed
     * @return {@code true} if FDN is enabled
     */
    public static boolean isNumberBlockedByFDN(Context context, int subId, String destAddr,
            String smscAddr) {
        // Skip FDN check for emergency numbers
        final TelephonyManager tm = context.getSystemService(TelephonyManager.class);
        if(tm.isEmergencyNumber(destAddr)) {
    public static boolean isFdnEnabled(int phoneId) {
        UiccCardApplication app = getUiccCardApplication(phoneId);
        if (app == null || (!app.getIccFdnAvailable())) {
            return false;
        }

        final int phoneId = SubscriptionManager.getPhoneId(subId);
        final String defaultCountryIso = tm.getSimCountryIso().toUpperCase(Locale.ENGLISH);
        return (isNumberBlockedByFDN(phoneId, smscAddr, defaultCountryIso) ||
                isNumberBlockedByFDN(phoneId, destAddr, defaultCountryIso));
        return app.getIccFdnEnabled();
    }

    /**
@@ -94,7 +80,7 @@ public class FdnUtils {
     * @param fdnList List of all FDN records associated with a sim card
     * @param dialStr dialed phone number
     * @param defaultCountryIso country ISO for the subscription associated with this phone
     * @return true if dialStr is present in the fdnList.
     * @return {@code true} if dialStr is present in the fdnList.
     */
    @VisibleForTesting
    public static boolean isFDN(String dialStr, String defaultCountryIso,
@@ -109,7 +95,7 @@ public class FdnUtils {
        String dialStrNational = null;
        final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
        try {
            final PhoneNumber phoneNumber = phoneNumberUtil.parse(dialStr, defaultCountryIso);
            PhoneNumber phoneNumber = phoneNumberUtil.parse(dialStr, defaultCountryIso);
            dialStrE164 = phoneNumberUtil.format(phoneNumber, PhoneNumberFormat.E164);
            dialStrNational = String.valueOf(phoneNumber.getNationalNumber());
        } catch (NumberParseException ignored) {
@@ -150,17 +136,18 @@ public class FdnUtils {
        return false;
    }

    private static ArrayList<AdnRecord> getFdnList(UiccCardApplication app) {
    private static ArrayList<AdnRecord> getFdnList(int phoneId) {
        UiccCardApplication app = getUiccCardApplication(phoneId);
        if (app == null) {
            return null;
        }

        final IccRecords iccRecords = app.getIccRecords();
        IccRecords iccRecords = app.getIccRecords();
        if (iccRecords == null) {
            return null;
        }

        final AdnRecordCache adnRecordCache = iccRecords.getAdnCache();
        AdnRecordCache adnRecordCache = iccRecords.getAdnCache();
        if(adnRecordCache == null) {
            return null;
        }
@@ -168,20 +155,8 @@ public class FdnUtils {
        return adnRecordCache.getRecordsIfLoaded(IccConstants.EF_FDN);
    }

    private static boolean isFdnEnabled(UiccCardApplication app) {
        if (app == null) {
            return false;
        }

        if (!app.getIccFdnAvailable()) {
            return false;
        }

        return app.getIccFdnEnabled();
    }

    private static UiccCardApplication getUiccCardApplication(int phoneId) {
        final UiccProfile uiccProfile = UiccController.getInstance()
        UiccProfile uiccProfile = UiccController.getInstance()
                .getUiccProfileForPhone(phoneId);
        if (uiccProfile == null) {
            return null;
+81 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Locale;

/**
 * Implements the ISmsImplBase interface used in the SmsManager API.
@@ -151,6 +152,13 @@ public class SmsController extends ISmsImplBase {
        if (callingPackage == null) {
            callingPackage = getCallingPackage();
        }

        // Perform FDN check
        if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
            sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
            return;
        }

        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
        if (iccSmsIntMgr != null) {
            iccSmsIntMgr.sendData(callingPackage, callingAttributionTag, destAddr, scAddr, destPort,
@@ -194,6 +202,13 @@ public class SmsController extends ISmsImplBase {
            sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
            return;
        }

        // Perform FDN check
        if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
            sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
            return;
        }

        long token = Binder.clearCallingIdentity();
        SubscriptionInfo info;
        try {
@@ -201,6 +216,7 @@ public class SmsController extends ISmsImplBase {
        } finally {
            Binder.restoreCallingIdentity(token);
        }

        if (isBluetoothSubscription(info)) {
            sendBluetoothText(info, destAddr, text, sentIntent, deliveryIntent);
        } else {
@@ -259,6 +275,13 @@ public class SmsController extends ISmsImplBase {
        if (callingPackage == null) {
            callingPackage = getCallingPackage();
        }

        // Perform FDN check
        if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
            sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
            return;
        }

        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
        if (iccSmsIntMgr != null) {
            iccSmsIntMgr.sendTextWithOptions(callingPackage, callingAttributionTag, destAddr,
@@ -281,6 +304,13 @@ public class SmsController extends ISmsImplBase {
        if (getCallingPackage() != null) {
            callingPackage = getCallingPackage();
        }

        // Perform FDN check
        if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
            sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
            return;
        }

        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
        if (iccSmsIntMgr != null) {
            iccSmsIntMgr.sendMultipartText(callingPackage, callingAttributionTag, destAddr, scAddr,
@@ -301,6 +331,13 @@ public class SmsController extends ISmsImplBase {
        if (callingPackage == null) {
            callingPackage = getCallingPackage();
        }

        // Perform FDN check
        if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
            sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
            return;
        }

        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
        if (iccSmsIntMgr != null) {
            iccSmsIntMgr.sendMultipartTextWithOptions(callingPackage, callingAttributionTag,
@@ -856,4 +893,48 @@ public class SmsController extends ISmsImplBase {
    public static String formatCrossStackMessageId(long id) {
        return "{x-message-id:" + id + "}";
    }

    /**
     * The following function checks if destination address or smsc is blocked due to FDN.
     * @param subId subscription ID
     * @param destAddr destination address of the message
     * @return true if either destAddr or smscAddr is blocked due to FDN.
     */
    private boolean isNumberBlockedByFDN(int subId, String destAddr, String callingPackage) {
        int phoneId = SubscriptionManager.getPhoneId(subId);
        if (!FdnUtils.isFdnEnabled(subId)) {
            return false;
        }

        // Skip FDN check for emergency numbers
        TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
        if (tm.isEmergencyNumber(destAddr)) {
            return false;
        }

        // Check if destAddr is present in FDN list
        String defaultCountryIso = tm.getSimCountryIso().toUpperCase(Locale.ENGLISH);
        if (FdnUtils.isNumberBlockedByFDN(phoneId, destAddr, defaultCountryIso)) {
            return true;
        }

        // Get SMSC address for this subscription
        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
        String smscAddr;
        if (iccSmsIntMgr != null) {
            long identity = Binder.clearCallingIdentity();
            try {
                smscAddr =  iccSmsIntMgr.getSmscAddressFromIccEf(callingPackage);
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        } else {
            Rlog.e(LOG_TAG, "getSmscAddressFromIccEfForSubscriber iccSmsIntMgr is null"
                + " for Subscription: " + subId);
            return true;
        }

        // Check if smscAddr is present in FDN list
        return FdnUtils.isNumberBlockedByFDN(phoneId, smscAddr, defaultCountryIso);
    }
}