Files
frameworks_base/telephony/java/android/telephony/CarrierRestrictionRules.java
Aurimas Liutikas 1da3bde08d Add missing nullability annotations.
To prepare for enabling MissingNullability Metalava check this CL
works on adding missing nullability issues that metalava flags if
we tell it to flag new things since API 29.

This is not a complete CL, mostly addresses public api and
toString/equals for @SystemApi

Exempt-From-Owner-Approval: Large scale nullability clean up
Bug: 124515653
Test: make -j checkapi
Merged-In: I109260842cfc25f06e40694997fcbb4afa02c867
Change-Id: I109260842cfc25f06e40694997fcbb4afa02c867
2019-08-30 00:16:24 +00:00

403 lines
15 KiB
Java

/*
* Copyright (C) 2018 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 android.telephony;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.carrier.CarrierIdentifier;
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.
* Allowed list: it indicates the list of carriers that are allowed.
* Excluded list: it indicates the list of carriers that are excluded.
* Default carrier restriction: it indicates the default behavior and the priority between the two
* lists:
* - not allowed: the device only allows usage of carriers that are present in the allowed list
* and not present in the excluded list. This implies that if a carrier is not present in either
* list, it is not allowed.
* - allowed: the device allows all carriers, except those present in the excluded list and not
* present in the allowed list. This implies that if a carrier is not present in either list,
* it is allowed.
* MultiSim policy: it indicates the behavior in case of devices with two or more SIM cards.
* - MULTISIM_POLICY_NONE: the same configuration is applied to all SIM slots independently. This
* is the default value if none is set.
* - MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT: it indicates that any SIM card can be used
* as far as one SIM card matching the configuration is present in the device.
*
* Both lists support the character '?' as wild character. For example, an entry indicating
* MCC=310 and MNC=??? will match all networks with MCC=310.
*
* Example 1: Allowed list contains MCC and MNC of operator A. Excluded list contains operator B,
* which has same MCC and MNC, but also GID1 value. The priority allowed list is set
* to true. Only SIM cards of operator A are allowed, but not those of B or any other
* operator.
* Example 2: Allowed list contains MCC and MNC of operator A. Excluded list contains an entry
* with same MCC, and '???' as MNC. The priority allowed list is set to false.
* SIM cards of operator A and all SIM cards with a different MCC value are allowed.
* SIM cards of operators with same MCC value and different MNC are not allowed.
* @hide
*/
@SystemApi
public final class CarrierRestrictionRules implements Parcelable {
/**
* The device only allows usage of carriers that are present in the allowed list and not
* present in the excluded list. This implies that if a carrier is not present in either list,
* it is not allowed.
*/
public static final int CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED = 0;
/**
* The device allows all carriers, except those present in the excluded list and not present
* in the allowed list. This implies that if a carrier is not present in either list, it is
* allowed.
*/
public static final int CARRIER_RESTRICTION_DEFAULT_ALLOWED = 1;
/** The same configuration is applied to all SIM slots independently. */
public static final int MULTISIM_POLICY_NONE = 0;
/** Any SIM card can be used as far as one SIM card matching the configuration is present. */
public static final int MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT = 1;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "MULTISIM_POLICY_",
value = {MULTISIM_POLICY_NONE, MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT})
public @interface MultiSimPolicy {}
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "CARRIER_RESTRICTION_DEFAULT_",
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
private int mCarrierRestrictionDefault;
@MultiSimPolicy
private int mMultiSimPolicy;
private CarrierRestrictionRules() {
mAllowedCarriers = new ArrayList<CarrierIdentifier>();
mExcludedCarriers = new ArrayList<CarrierIdentifier>();
mCarrierRestrictionDefault = CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED;
mMultiSimPolicy = MULTISIM_POLICY_NONE;
}
private CarrierRestrictionRules(Parcel in) {
mAllowedCarriers = new ArrayList<CarrierIdentifier>();
mExcludedCarriers = new ArrayList<CarrierIdentifier>();
in.readTypedList(mAllowedCarriers, CarrierIdentifier.CREATOR);
in.readTypedList(mExcludedCarriers, CarrierIdentifier.CREATOR);
mCarrierRestrictionDefault = in.readInt();
mMultiSimPolicy = in.readInt();
}
/**
* Creates a new builder for this class
* @hide
*/
public static Builder newBuilder() {
return new Builder();
}
/**
* Indicates if all carriers are allowed
*/
public boolean isAllCarriersAllowed() {
return (mAllowedCarriers.isEmpty() && mExcludedCarriers.isEmpty()
&& mCarrierRestrictionDefault == CARRIER_RESTRICTION_DEFAULT_ALLOWED);
}
/**
* Retrieves list of allowed carriers
*
* @return the list of allowed carriers
*/
public @NonNull List<CarrierIdentifier> getAllowedCarriers() {
return mAllowedCarriers;
}
/**
* Retrieves list of excluded carriers
*
* @return the list of excluded carriers
*/
public @NonNull List<CarrierIdentifier> getExcludedCarriers() {
return mExcludedCarriers;
}
/**
* Retrieves the default behavior of carrier restrictions
*/
public @CarrierRestrictionDefault int getDefaultCarrierRestriction() {
return mCarrierRestrictionDefault;
}
/**
* @return The policy used for multi-SIM devices
*/
public @MultiSimPolicy int getMultiSimPolicy() {
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 @NonNull List<Boolean> areCarrierIdentifiersAllowed(
@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}
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeTypedList(mAllowedCarriers);
out.writeTypedList(mExcludedCarriers);
out.writeInt(mCarrierRestrictionDefault);
out.writeInt(mMultiSimPolicy);
}
/**
* {@link Parcelable#describeContents}
*/
@Override
public int describeContents() {
return 0;
}
/**
* {@link Parcelable.Creator}
*/
public static final @android.annotation.NonNull Creator<CarrierRestrictionRules> CREATOR =
new Creator<CarrierRestrictionRules>() {
@Override
public CarrierRestrictionRules createFromParcel(Parcel in) {
return new CarrierRestrictionRules(in);
}
@Override
public CarrierRestrictionRules[] newArray(int size) {
return new CarrierRestrictionRules[size];
}
};
@NonNull
@Override
public String toString() {
return "CarrierRestrictionRules(allowed:" + mAllowedCarriers + ", excluded:"
+ mExcludedCarriers + ", default:" + mCarrierRestrictionDefault
+ ", multisim policy:" + mMultiSimPolicy + ")";
}
/**
* Builder for a {@link CarrierRestrictionRules}.
*/
public static final class Builder {
private final CarrierRestrictionRules mRules;
public Builder() {
mRules = new CarrierRestrictionRules();
}
/** build command */
public @NonNull CarrierRestrictionRules build() {
return mRules;
}
/**
* Indicate that all carriers are allowed.
*/
public @NonNull Builder setAllCarriersAllowed() {
mRules.mAllowedCarriers.clear();
mRules.mExcludedCarriers.clear();
mRules.mCarrierRestrictionDefault = CARRIER_RESTRICTION_DEFAULT_ALLOWED;
return this;
}
/**
* Set list of allowed carriers.
*
* @param allowedCarriers list of allowed carriers
*/
public @NonNull Builder setAllowedCarriers(
@NonNull List<CarrierIdentifier> allowedCarriers) {
mRules.mAllowedCarriers = new ArrayList<CarrierIdentifier>(allowedCarriers);
return this;
}
/**
* Set list of excluded carriers.
*
* @param excludedCarriers list of excluded carriers
*/
public @NonNull Builder setExcludedCarriers(
@NonNull List<CarrierIdentifier> excludedCarriers) {
mRules.mExcludedCarriers = new ArrayList<CarrierIdentifier>(excludedCarriers);
return this;
}
/**
* Set the default behavior of the carrier restrictions
*
* @param carrierRestrictionDefault prioritized carrier list
*/
public @NonNull Builder setDefaultCarrierRestriction(
@CarrierRestrictionDefault int carrierRestrictionDefault) {
mRules.mCarrierRestrictionDefault = carrierRestrictionDefault;
return this;
}
/**
* Set the policy to be used for multi-SIM devices
*
* @param multiSimPolicy multi SIM policy
*/
public @NonNull Builder setMultiSimPolicy(@MultiSimPolicy int multiSimPolicy) {
mRules.mMultiSimPolicy = multiSimPolicy;
return this;
}
}
}