script-astra/Android/Sdk/sources/android-35/com/android/internal/telephony/FdnUtils.java
localadmin 4380f00a78 init
2025-01-20 18:15:20 +03:00

225 lines
8.5 KiB
Java

/*
* 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.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.regex.PatternSyntaxException;
/**
* 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 {@code true} if dialStr is blocked due to FDN check.
*/
public static boolean isNumberBlockedByFDN(int phoneId, String dialStr,
String defaultCountryIso) {
if (!isFdnEnabled(phoneId)) {
return false;
}
ArrayList<AdnRecord> fdnList = getFdnList(phoneId);
return !isFDN(dialStr, defaultCountryIso, fdnList);
}
/**
* 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 isFdnEnabled(int phoneId) {
UiccCardApplication app = getUiccCardApplication(phoneId);
if (app == null || (!app.getIccFdnAvailable())) {
return false;
}
return app.getIccFdnEnabled();
}
/**
* If FDN is enabled, check to see if the given supplementary service control strings are
* blocked due to FDN.
* @param phoneId The phone object id for which the FDN check is performed
* @param controlStrings control strings associated with the supplementary service request
* @param defaultCountryIso country ISO for the subscription associated with this phone
* @return {@code true} if the FDN list does not contain any of the control strings.
*/
public static boolean isSuppServiceRequestBlockedByFdn(int phoneId,
ArrayList<String> controlStrings, String defaultCountryIso) {
if (!isFdnEnabled(phoneId)) {
return false;
}
ArrayList<AdnRecord> fdnList = getFdnList(phoneId);
for(String controlString : controlStrings) {
if(isFDN(controlString, defaultCountryIso, fdnList)) {
return false;
}
}
return true;
}
/**
* 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 {@code 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 {
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");
dialStr = extractSMSC(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(int phoneId) {
UiccCardApplication app = getUiccCardApplication(phoneId);
if (app == null) {
return null;
}
IccRecords iccRecords = app.getIccRecords();
if (iccRecords == null) {
return null;
}
AdnRecordCache adnRecordCache = iccRecords.getAdnCache();
if(adnRecordCache == null) {
return null;
}
return adnRecordCache.getRecordsIfLoaded(IccConstants.EF_FDN);
}
private static UiccCardApplication getUiccCardApplication(int phoneId) {
UiccProfile uiccProfile = UiccController.getInstance()
.getUiccProfileForPhone(phoneId);
if (uiccProfile == null) {
return null;
}
return uiccProfile.getApplication(UiccController.APP_FAM_3GPP);
}
private static String extractSMSC(String dialStr) {
try {
String[] dialStrParts = null;
if (dialStr.contains(",")) {
// SMSC can be in the format of ""+123456789123",123"
// Split into two parts using comma as delimiter
// and first part of the string is used as smsc address
dialStrParts = dialStr.split(",");
} else if (dialStr.contains("@")) {
// SMSC can be in the format of "+123456789123@ims.mnc.org"
// Split into two parts using @ as delimiter
// and first part of the string is used as smsc address
dialStrParts = dialStr.split("@");
}
if (dialStrParts != null && dialStrParts.length >= 1) {
if (dialStrParts[0].contains("\"")) {
// If SMSC is in this format: ""+123456789123",123", after performing above
// split we get string with double-quotation marks in it
// dialStrParts[0] = ""+123456789123"".
// Here, we remove double-quotation marks from the string.
dialStrParts[0] = dialStrParts[0].replaceAll("\"", "");
}
return dialStrParts[0];
}
} catch (PatternSyntaxException ex) {
Rlog.w(LOG_TAG, "extractSMSC: Could not extract number from dialStr " + ex);
}
// Return original dialStr if it is not in any of the formats mentions above.
return dialStr;
}
}