Loading src/java/com/android/internal/telephony/CallStateException.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ public class CallStateException extends Exception public static final int ERROR_CALLING_DISABLED = 5; public static final int ERROR_CALLING_DISABLED = 5; public static final int ERROR_TOO_MANY_CALLS = 6; public static final int ERROR_TOO_MANY_CALLS = 6; public static final int ERROR_OTASP_PROVISIONING_IN_PROCESS = 7; public static final int ERROR_OTASP_PROVISIONING_IN_PROCESS = 7; public static final int ERROR_FDN_BLOCKED = 8; public public CallStateException() CallStateException() Loading src/java/com/android/internal/telephony/FdnUtils.java 0 → 100644 +192 −0 Original line number Original line 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 src/java/com/android/internal/telephony/GsmCdmaPhone.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -1494,6 +1494,12 @@ public class GsmCdmaPhone extends Phone { + ((imsPhone != null) ? imsPhone.getServiceState().getState() : "N/A")); + ((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 // Bypass WiFi Only WFC check if this is an emergency call - we should still try to // place over cellular if possible. // place over cellular if possible. if (!isEmergency) { if (!isEmergency) { Loading src/java/com/android/internal/telephony/SmsController.java +41 −1 Original line number Original line Diff line number Diff line Loading @@ -151,6 +151,14 @@ public class SmsController extends ISmsImplBase { if (callingPackage == null) { if (callingPackage == null) { callingPackage = getCallingPackage(); 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); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { if (iccSmsIntMgr != null) { iccSmsIntMgr.sendData(callingPackage, callingAttributionTag, destAddr, scAddr, destPort, iccSmsIntMgr.sendData(callingPackage, callingAttributionTag, destAddr, scAddr, destPort, Loading Loading @@ -201,6 +209,14 @@ public class SmsController extends ISmsImplBase { } finally { } finally { Binder.restoreCallingIdentity(token); 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)) { if (isBluetoothSubscription(info)) { sendBluetoothText(info, destAddr, text, sentIntent, deliveryIntent); sendBluetoothText(info, destAddr, text, sentIntent, deliveryIntent); } else { } else { Loading Loading @@ -259,6 +275,14 @@ public class SmsController extends ISmsImplBase { if (callingPackage == null) { if (callingPackage == null) { callingPackage = getCallingPackage(); 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); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { if (iccSmsIntMgr != null) { iccSmsIntMgr.sendTextWithOptions(callingPackage, callingAttributionTag, destAddr, iccSmsIntMgr.sendTextWithOptions(callingPackage, callingAttributionTag, destAddr, Loading @@ -281,6 +305,14 @@ public class SmsController extends ISmsImplBase { if (getCallingPackage() != null) { if (getCallingPackage() != null) { callingPackage = getCallingPackage(); 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); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { if (iccSmsIntMgr != null) { iccSmsIntMgr.sendMultipartText(callingPackage, callingAttributionTag, destAddr, scAddr, iccSmsIntMgr.sendMultipartText(callingPackage, callingAttributionTag, destAddr, scAddr, Loading @@ -301,6 +333,14 @@ public class SmsController extends ISmsImplBase { if (callingPackage == null) { if (callingPackage == null) { callingPackage = getCallingPackage(); 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); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { if (iccSmsIntMgr != null) { iccSmsIntMgr.sendMultipartTextWithOptions(callingPackage, callingAttributionTag, iccSmsIntMgr.sendMultipartTextWithOptions(callingPackage, callingAttributionTag, Loading tests/telephonytests/src/com/android/internal/telephony/FdnUtilsTest.java 0 → 100644 +166 −0 Original line number Original line 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 Loading
src/java/com/android/internal/telephony/CallStateException.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ public class CallStateException extends Exception public static final int ERROR_CALLING_DISABLED = 5; public static final int ERROR_CALLING_DISABLED = 5; public static final int ERROR_TOO_MANY_CALLS = 6; public static final int ERROR_TOO_MANY_CALLS = 6; public static final int ERROR_OTASP_PROVISIONING_IN_PROCESS = 7; public static final int ERROR_OTASP_PROVISIONING_IN_PROCESS = 7; public static final int ERROR_FDN_BLOCKED = 8; public public CallStateException() CallStateException() Loading
src/java/com/android/internal/telephony/FdnUtils.java 0 → 100644 +192 −0 Original line number Original line 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
src/java/com/android/internal/telephony/GsmCdmaPhone.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -1494,6 +1494,12 @@ public class GsmCdmaPhone extends Phone { + ((imsPhone != null) ? imsPhone.getServiceState().getState() : "N/A")); + ((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 // Bypass WiFi Only WFC check if this is an emergency call - we should still try to // place over cellular if possible. // place over cellular if possible. if (!isEmergency) { if (!isEmergency) { Loading
src/java/com/android/internal/telephony/SmsController.java +41 −1 Original line number Original line Diff line number Diff line Loading @@ -151,6 +151,14 @@ public class SmsController extends ISmsImplBase { if (callingPackage == null) { if (callingPackage == null) { callingPackage = getCallingPackage(); 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); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { if (iccSmsIntMgr != null) { iccSmsIntMgr.sendData(callingPackage, callingAttributionTag, destAddr, scAddr, destPort, iccSmsIntMgr.sendData(callingPackage, callingAttributionTag, destAddr, scAddr, destPort, Loading Loading @@ -201,6 +209,14 @@ public class SmsController extends ISmsImplBase { } finally { } finally { Binder.restoreCallingIdentity(token); 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)) { if (isBluetoothSubscription(info)) { sendBluetoothText(info, destAddr, text, sentIntent, deliveryIntent); sendBluetoothText(info, destAddr, text, sentIntent, deliveryIntent); } else { } else { Loading Loading @@ -259,6 +275,14 @@ public class SmsController extends ISmsImplBase { if (callingPackage == null) { if (callingPackage == null) { callingPackage = getCallingPackage(); 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); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { if (iccSmsIntMgr != null) { iccSmsIntMgr.sendTextWithOptions(callingPackage, callingAttributionTag, destAddr, iccSmsIntMgr.sendTextWithOptions(callingPackage, callingAttributionTag, destAddr, Loading @@ -281,6 +305,14 @@ public class SmsController extends ISmsImplBase { if (getCallingPackage() != null) { if (getCallingPackage() != null) { callingPackage = getCallingPackage(); 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); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { if (iccSmsIntMgr != null) { iccSmsIntMgr.sendMultipartText(callingPackage, callingAttributionTag, destAddr, scAddr, iccSmsIntMgr.sendMultipartText(callingPackage, callingAttributionTag, destAddr, scAddr, Loading @@ -301,6 +333,14 @@ public class SmsController extends ISmsImplBase { if (callingPackage == null) { if (callingPackage == null) { callingPackage = getCallingPackage(); 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); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { if (iccSmsIntMgr != null) { iccSmsIntMgr.sendMultipartTextWithOptions(callingPackage, callingAttributionTag, iccSmsIntMgr.sendMultipartTextWithOptions(callingPackage, callingAttributionTag, Loading
tests/telephonytests/src/com/android/internal/telephony/FdnUtilsTest.java 0 → 100644 +166 −0 Original line number Original line 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