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

Commit 053ce5bc authored by Beth Thibodeau's avatar Beth Thibodeau
Browse files

Revert "Added support for FDN Check."

Revert submission 17070464-FDN_CHECK

Reason for revert: DroidMonitor: Potential culprit for b/225059967 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted
Reverted Changes:
Iaf5f1c875:Added FDN Check.
I553977883:Added support for FDN Check.

Change-Id: Ie690ec111ba445b0a4474f2033b249e696400eca
parent c23e4bbd
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ public class CallStateException extends Exception
    public static final int ERROR_CALLING_DISABLED = 5;
    public static final int ERROR_TOO_MANY_CALLS = 6;
    public static final int ERROR_OTASP_PROVISIONING_IN_PROCESS = 7;
    public static final int ERROR_FDN_BLOCKED = 8;

    public
    CallStateException()
+0 −192
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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;
import com.android.i18n.phonenumbers.PhoneNumberUtil;
import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.uicc.AdnRecord;
import com.android.internal.telephony.uicc.AdnRecordCache;
import com.android.internal.telephony.uicc.IccConstants;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.UiccCardApplication;
import com.android.internal.telephony.uicc.UiccController;
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
 * designed as per 3GPP 22.101.
 */
public class FdnUtils {
    private static final boolean VDBG = false;
    private static final String LOG_TAG = FdnUtils.class.getSimpleName();

    /**
     * The following function checks if dialed number is blocked due to FDN.
     *
     * @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.
     */
    public static boolean isNumberBlockedByFDN(int phoneId, String dialStr,
            String defaultCountryIso) {
        final UiccCardApplication app = getUiccCardApplication(phoneId);

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

        final ArrayList<AdnRecord> fdnList = getFdnList(app);
        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.
     */
    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)) {
            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));
    }

    /**
     * Checks if dialStr is part of FDN list.
     *
     * @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.
     */
    @VisibleForTesting
    public static boolean isFDN(String dialStr, String defaultCountryIso,
            ArrayList<AdnRecord> fdnList) {
        if (fdnList == null || fdnList.isEmpty() || TextUtils.isEmpty(dialStr)) {
            Rlog.w(LOG_TAG, "isFDN: unexpected null value");
            return false;
        }

        // Parse the dialStr and convert it to E164 format
        String dialStrE164 = null;
        String dialStrNational = null;
        final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
        try {
            final PhoneNumber phoneNumber = phoneNumberUtil.parse(dialStr, defaultCountryIso);
            dialStrE164 = phoneNumberUtil.format(phoneNumber, PhoneNumberFormat.E164);
            dialStrNational = String.valueOf(phoneNumber.getNationalNumber());
        } catch (NumberParseException ignored) {
            Rlog.w(LOG_TAG, "isFDN: could not parse dialStr");
        }

        /**
         * Returns true if dialStrE164 or dialStrNational or dialStr starts with fdnNumber
         * E.g.1: returns true if fdnNumber="123" and dialStr="12345"
         * E.g.2: does not return true if fdnNumber="1123" and dialStr="12345"
         */
        for (AdnRecord fdn: fdnList) {
            String fdnNumber = fdn.getNumber();
            if (TextUtils.isEmpty(fdnNumber)) {
                continue;
            }

            if(!TextUtils.isEmpty(dialStrE164)) {
                if(dialStrE164.startsWith(fdnNumber)) {
                    return true;
                }
            }

            if(!TextUtils.isEmpty(dialStrNational)) {
                if (dialStrNational.startsWith(fdnNumber)) {
                    return true;
                }
            }

            if (dialStr.startsWith(fdnNumber)) {
                return true;
            }
        }

        if (VDBG) {
            Rlog.i(LOG_TAG, "isFDN: dialed number not present in FDN list");
        }
        return false;
    }

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

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

        final AdnRecordCache adnRecordCache = iccRecords.getAdnCache();
        if(adnRecordCache == null) {
            return null;
        }

        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()
                .getUiccProfileForPhone(phoneId);
        if (uiccProfile == null) {
            return null;
        }

        return uiccProfile.getApplication(UiccController.APP_FAM_3GPP);
    }
}
 No newline at end of file
+0 −6
Original line number Diff line number Diff line
@@ -1491,12 +1491,6 @@ public class GsmCdmaPhone extends Phone {
                    + ((imsPhone != null) ? imsPhone.getServiceState().getState() : "N/A"));
        }

        // Perform FDN check for non-emergency calls - shouldn't dial if number is blocked by FDN
        if(!isEmergency && FdnUtils.isNumberBlockedByFDN(mPhoneId, dialString, getCountryIso())) {
            throw new CallStateException(CallStateException.ERROR_FDN_BLOCKED,
                    "cannot dial number blocked by FDN");
        }

        // Bypass WiFi Only WFC check if this is an emergency call - we should still try to
        // place over cellular if possible.
        if (!isEmergency) {
+1 −41
Original line number Diff line number Diff line
@@ -151,14 +151,6 @@ public class SmsController extends ISmsImplBase {
        if (callingPackage == null) {
            callingPackage = getCallingPackage();
        }

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

        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
        if (iccSmsIntMgr != null) {
            iccSmsIntMgr.sendData(callingPackage, callingAttributionTag, destAddr, scAddr, destPort,
@@ -209,14 +201,6 @@ public class SmsController extends ISmsImplBase {
        } finally {
            Binder.restoreCallingIdentity(token);
        }

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

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

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

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

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

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

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

        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
        if (iccSmsIntMgr != null) {
            iccSmsIntMgr.sendMultipartTextWithOptions(callingPackage, callingAttributionTag,
+0 −166
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.internal.telephony.uicc.AdnRecord;

import org.junit.Test;

import java.util.ArrayList;

public class FdnUtilsTest {

    private ArrayList<AdnRecord> initializeFdnList() {
        ArrayList<AdnRecord> fdnList = new ArrayList<>();
        AdnRecord adnRecord = new AdnRecord(null, null);
        // By default, every sim card holds 15 empty FDN records
        int fdnListSize = 15;
        for (int i = 0; i < fdnListSize; i++) {
            fdnList.add(adnRecord);
        }
        return fdnList;
    }

    @Test
    public void fdnListIsNull_returnsFalse() {
        assertFalse(FdnUtils.isFDN( "123456789", "US", null));
    }

    @Test
    public void fdnListIsEmpty_returnsFalse() {
        ArrayList<AdnRecord> fdnList = new ArrayList<>();
        assertFalse(FdnUtils.isFDN( "123456789", "US", fdnList));
    }

    @Test
    public void fdnListHasOnlyDefaultRecords_returnsFalse() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();

        assertFalse(FdnUtils.isFDN( "123456789", "US", fdnList));
    }

    @Test
    public void fdnListHasRecordWithEmptyNumberStr_returnsFalse() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "");
        fdnList.add(1, adnRecord);

        assertFalse(FdnUtils.isFDN( "123456789", "US", fdnList));
    }

    @Test
    public void dialStrInFdnList_returnsTrue() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "123456789");
        fdnList.add(2, adnRecord);

        assertTrue(FdnUtils.isFDN( "123456789", "US", fdnList));
    }

    @Test
    public void dialStrNotInFdnList_returnsFalse() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "111111111");
        fdnList.add(3, adnRecord);

        assertFalse(FdnUtils.isFDN("123456788", "US", fdnList));
    }

    @Test
    public void dialStrIsNull_returnsFalse() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "111111111");
        fdnList.add(4, adnRecord);

        assertFalse(FdnUtils.isFDN( null, "US", fdnList));
    }

    @Test
    public void fdnEntryFirstSubStringOfDialStr_returnsTrue() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "123");
        fdnList.add(5, adnRecord);

        assertTrue(FdnUtils.isFDN( "12345", "US", fdnList));
    }

    @Test
    public void fdnEntrySubStringOfDialStr_returnsFalse() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "123");
        fdnList.add(5, adnRecord);

        assertFalse(FdnUtils.isFDN("612345", "US", fdnList));
    }

    @Test
    public void dialStrFirstSubStringOfFdnEntry_returnsFalse() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "12345");
        fdnList.add(5, adnRecord);

        assertFalse(FdnUtils.isFDN("123", "US", fdnList));
    }

    @Test
    public void dialStrSubStringOfFdnEntry_returnsFalse() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "612345");
        fdnList.add(5, adnRecord);

        assertFalse(FdnUtils.isFDN("123", "US", fdnList));
    }

    @Test
    public void dialStrWithoutCountryCode_returnsTrue() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "+16502910000");
        fdnList.add(6, adnRecord);

        assertTrue(FdnUtils.isFDN( "6502910000", "US", fdnList));
    }

    @Test
    public void dialStrWithCountryCode_returnsTrue() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "6502910000");
        fdnList.add(6, adnRecord);

        assertTrue(FdnUtils.isFDN("+16502910000", "US", fdnList));
    }

    @Test
    public void defaultCountryIsoIsEmpty_returnsTrue() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "650");
        fdnList.add(6, adnRecord);

        assertTrue(FdnUtils.isFDN("+16502910000", "", fdnList));
    }

    @Test
    public void defaultCountryIsoIsEmpty_returnsFalse() {
        ArrayList<AdnRecord> fdnList = initializeFdnList();
        AdnRecord adnRecord = new AdnRecord(null, "+1650");
        fdnList.add(6, adnRecord);

        assertFalse(FdnUtils.isFDN("6502910000", "", fdnList));
    }
}
 No newline at end of file