Merge "Add API to check if a SIM card matches carrier restrictions." am: 31e933cf78
am: 1f2a143d98
Change-Id: If1ec8a58e68410f522279d1199e3c44c47f231e7
This commit is contained in:
@@ -5529,6 +5529,7 @@ package android.telephony {
|
||||
method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getExcludedCarriers();
|
||||
method public int getMultiSimPolicy();
|
||||
method public boolean isAllCarriersAllowed();
|
||||
method public java.util.List<java.lang.Boolean> isCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final int CARRIER_RESTRICTION_DEFAULT_ALLOWED = 1; // 0x1
|
||||
field public static final int CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED = 0; // 0x0
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Contains the list of carrier restrictions.
|
||||
@@ -93,6 +94,9 @@ public final class CarrierRestrictionRules implements Parcelable {
|
||||
value = {CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED, CARRIER_RESTRICTION_DEFAULT_ALLOWED})
|
||||
public @interface CarrierRestrictionDefault {}
|
||||
|
||||
/* Wild character for comparison */
|
||||
private static final char WILD_CHARACTER = '?';
|
||||
|
||||
private List<CarrierIdentifier> mAllowedCarriers;
|
||||
private List<CarrierIdentifier> mExcludedCarriers;
|
||||
@CarrierRestrictionDefault
|
||||
@@ -165,6 +169,124 @@ public final class CarrierRestrictionRules implements Parcelable {
|
||||
return mMultiSimPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests an array of carriers with the carrier restriction configuration. The list of carrier
|
||||
* ids passed as argument does not need to be the same as currently present in the device.
|
||||
*
|
||||
* @param carrierIds list of {@link CarrierIdentifier}, one for each SIM slot on the device
|
||||
* @return a list of boolean with the same size as input, indicating if each
|
||||
* {@link CarrierIdentifier} is allowed or not.
|
||||
*/
|
||||
public List<Boolean> isCarrierIdentifiersAllowed(@NonNull List<CarrierIdentifier> carrierIds) {
|
||||
ArrayList<Boolean> result = new ArrayList<>(carrierIds.size());
|
||||
|
||||
// First calculate the result for each slot independently
|
||||
for (int i = 0; i < carrierIds.size(); i++) {
|
||||
boolean inAllowedList = isCarrierIdInList(carrierIds.get(i), mAllowedCarriers);
|
||||
boolean inExcludedList = isCarrierIdInList(carrierIds.get(i), mExcludedCarriers);
|
||||
if (mCarrierRestrictionDefault == CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED) {
|
||||
result.add((inAllowedList && !inExcludedList) ? true : false);
|
||||
} else {
|
||||
result.add((inExcludedList && !inAllowedList) ? false : true);
|
||||
}
|
||||
}
|
||||
// Apply the multi-slot policy, if needed.
|
||||
if (mMultiSimPolicy == MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT) {
|
||||
for (boolean b : result) {
|
||||
if (b) {
|
||||
result.replaceAll(x -> true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if a certain carrier {@code id} is present inside a {@code list}
|
||||
*
|
||||
* @return true if the carrier {@code id} is present, false otherwise
|
||||
*/
|
||||
private static boolean isCarrierIdInList(CarrierIdentifier id, List<CarrierIdentifier> list) {
|
||||
for (CarrierIdentifier listItem : list) {
|
||||
// Compare MCC and MNC
|
||||
if (!patternMatch(id.getMcc(), listItem.getMcc())
|
||||
|| !patternMatch(id.getMnc(), listItem.getMnc())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Compare SPN. Comparison is on the complete strings, case insensitive and with wild
|
||||
// characters.
|
||||
String listItemValue = convertNullToEmpty(listItem.getSpn());
|
||||
String idValue = convertNullToEmpty(id.getSpn());
|
||||
if (!listItemValue.isEmpty()) {
|
||||
if (!patternMatch(idValue, listItemValue)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// The IMSI of the configuration can be shorter than actual IMSI in the SIM card.
|
||||
listItemValue = convertNullToEmpty(listItem.getImsi());
|
||||
idValue = convertNullToEmpty(id.getImsi());
|
||||
if (!patternMatch(
|
||||
idValue.substring(0, Math.min(idValue.length(), listItemValue.length())),
|
||||
listItemValue)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The GID1 of the configuration can be shorter than actual GID1 in the SIM card.
|
||||
listItemValue = convertNullToEmpty(listItem.getGid1());
|
||||
idValue = convertNullToEmpty(id.getGid1());
|
||||
if (!patternMatch(
|
||||
idValue.substring(0, Math.min(idValue.length(), listItemValue.length())),
|
||||
listItemValue)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The GID2 of the configuration can be shorter than actual GID2 in the SIM card.
|
||||
listItemValue = convertNullToEmpty(listItem.getGid2());
|
||||
idValue = convertNullToEmpty(id.getGid2());
|
||||
if (!patternMatch(
|
||||
idValue.substring(0, Math.min(idValue.length(), listItemValue.length())),
|
||||
listItemValue)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Valid match was found in the list
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String convertNullToEmpty(String value) {
|
||||
return Objects.toString(value, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a case insensitive string comparison against a given pattern. The character '?'
|
||||
* is used in the pattern as wild character in the comparison. The string must have the same
|
||||
* length as the pattern.
|
||||
*
|
||||
* @param str string to match
|
||||
* @param pattern string containing the pattern
|
||||
* @return true in case of match, false otherwise
|
||||
*/
|
||||
private static boolean patternMatch(String str, String pattern) {
|
||||
if (str.length() != pattern.length()) {
|
||||
return false;
|
||||
}
|
||||
String lowerCaseStr = str.toLowerCase();
|
||||
String lowerCasePattern = pattern.toLowerCase();
|
||||
|
||||
for (int i = 0; i < lowerCasePattern.length(); i++) {
|
||||
if (lowerCasePattern.charAt(i) != lowerCaseStr.charAt(i)
|
||||
&& lowerCasePattern.charAt(i) != WILD_CHARACTER) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Parcelable#writeToParcel}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user