All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.android.telephony.euicc.EuiccRulesAuthTable Maven / Gradle / Ivy

Go to download

A library jar that provides APIs for Applications written for the Google Android Platform.

There is a newer version: 15-robolectric-12650502
Show newest version
/*
 * 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.euicc;

import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.carrier.CarrierIdentifier;
import android.service.euicc.EuiccProfileInfo;
import android.text.TextUtils;

import com.android.internal.annotations.VisibleForTesting;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

/**
 * This represents the RAT (Rules Authorisation Table) stored on eUICC.
 * @hide
 */
@SystemApi
public final class EuiccRulesAuthTable implements Parcelable {
    /** Profile policy rule flags */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, prefix = { "POLICY_RULE_FLAG_" }, value = {
            POLICY_RULE_FLAG_CONSENT_REQUIRED
    })
    /** @hide */
    public @interface PolicyRuleFlag {}

    /** User consent is required to install the profile. */
    public static final int POLICY_RULE_FLAG_CONSENT_REQUIRED = 1;

    private final int[] mPolicyRules;
    private final CarrierIdentifier[][] mCarrierIds;
    private final int[] mPolicyRuleFlags;

    /** This is used to build new {@link EuiccRulesAuthTable} instance. */
    public static final class Builder {
        private int[] mPolicyRules;
        private CarrierIdentifier[][] mCarrierIds;
        private int[] mPolicyRuleFlags;
        private int mPosition;

        /**
         * Creates a new builder.
         *
         * @param ruleNum The number of authorisation rules in the table.
         */
        public Builder(int ruleNum) {
            mPolicyRules = new int[ruleNum];
            mCarrierIds = new CarrierIdentifier[ruleNum][];
            mPolicyRuleFlags = new int[ruleNum];
        }

        /**
         * Builds the RAT instance. This builder should not be used anymore after this method is
         * called, otherwise {@link NullPointerException} will be thrown.
         */
        public EuiccRulesAuthTable build() {
            if (mPosition != mPolicyRules.length) {
                throw new IllegalStateException(
                        "Not enough rules are added, expected: "
                                + mPolicyRules.length
                                + ", added: "
                                + mPosition);
            }
            return new EuiccRulesAuthTable(mPolicyRules, mCarrierIds, mPolicyRuleFlags);
        }

        /**
         * Adds an authorisation rule.
         *
         * @throws ArrayIndexOutOfBoundsException If the {@code mPosition} is larger than the size
         *     this table.
         */
        public Builder add(int policyRules, List carrierId, int policyRuleFlags) {
            if (mPosition >= mPolicyRules.length) {
                throw new ArrayIndexOutOfBoundsException(mPosition);
            }
            mPolicyRules[mPosition] = policyRules;
            if (carrierId != null && carrierId.size() > 0) {
                mCarrierIds[mPosition] = carrierId.toArray(new CarrierIdentifier[carrierId.size()]);
            }
            mPolicyRuleFlags[mPosition] = policyRuleFlags;
            mPosition++;
            return this;
        }
    }

    /**
     * @param mccRule A 2-character or 3-character string which can be either MCC or MNC. The
     *     character 'E' is used as a wild char to match any digit.
     * @param mcc A 2-character or 3-character string which can be either MCC or MNC.
     * @return Whether the {@code mccRule} matches {@code mcc}.
     *
     * @hide
     */
    @VisibleForTesting
    public static boolean match(String mccRule, String mcc) {
        if (mccRule.length() < mcc.length()) {
            return false;
        }
        for (int i = 0; i < mccRule.length(); i++) {
            // 'E' is the wild char to match any digit.
            if (mccRule.charAt(i) == 'E'
                    || (i < mcc.length() && mccRule.charAt(i) == mcc.charAt(i))) {
                continue;
            }
            return false;
        }
        return true;
    }

    private EuiccRulesAuthTable(int[] policyRules, CarrierIdentifier[][] carrierIds,
            int[] policyRuleFlags) {
        mPolicyRules = policyRules;
        mCarrierIds = carrierIds;
        mPolicyRuleFlags = policyRuleFlags;
    }

    /**
     * Finds the index of the first authorisation rule matching the given policy and carrier id. If
     * the returned index is not negative, the carrier is allowed to apply this policy to its
     * profile.
     *
     * @param policy The policy rule.
     * @param carrierId The carrier id.
     * @return The index of authorization rule. If no rule is found, -1 will be returned.
     */
    public int findIndex(@EuiccProfileInfo.PolicyRule int policy, CarrierIdentifier carrierId) {
        for (int i = 0; i < mPolicyRules.length; i++) {
            if ((mPolicyRules[i] & policy) == 0) {
                continue;
            }
            CarrierIdentifier[] carrierIds = mCarrierIds[i];
            if (carrierIds == null || carrierIds.length == 0) {
                continue;
            }
            for (int j = 0; j < carrierIds.length; j++) {
                CarrierIdentifier ruleCarrierId = carrierIds[j];
                if (!match(ruleCarrierId.getMcc(), carrierId.getMcc())
                        || !match(ruleCarrierId.getMnc(), carrierId.getMnc())) {
                    continue;
                }
                String gid = ruleCarrierId.getGid1();
                if (!TextUtils.isEmpty(gid) && !gid.equals(carrierId.getGid1())) {
                    continue;
                }
                gid = ruleCarrierId.getGid2();
                if (!TextUtils.isEmpty(gid) && !gid.equals(carrierId.getGid2())) {
                    continue;
                }
                return i;
            }
        }
        return -1;
    }

    /**
     * Tests if the entry in the table has the given policy rule flag.
     *
     * @param index The index of the entry.
     * @param flag The policy rule flag to be tested.
     * @throws ArrayIndexOutOfBoundsException If the {@code index} is negative or larger than the
     *     size of this table.
     */
    public boolean hasPolicyRuleFlag(int index, @PolicyRuleFlag int flag) {
        if (index < 0 || index >= mPolicyRules.length) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        return (mPolicyRuleFlags[index] & flag) != 0;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeIntArray(mPolicyRules);
        for (CarrierIdentifier[] ids : mCarrierIds) {
            dest.writeTypedArray(ids, flags);
        }
        dest.writeIntArray(mPolicyRuleFlags);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }

        EuiccRulesAuthTable that = (EuiccRulesAuthTable) obj;
        if (mCarrierIds.length != that.mCarrierIds.length) {
            return false;
        }
        for (int i = 0; i < mCarrierIds.length; i++) {
            CarrierIdentifier[] carrierIds = mCarrierIds[i];
            CarrierIdentifier[] thatCarrierIds = that.mCarrierIds[i];
            if (carrierIds != null && thatCarrierIds != null) {
                if (carrierIds.length != thatCarrierIds.length) {
                    return false;
                }
                for (int j = 0; j < carrierIds.length; j++) {
                    if (!carrierIds[j].equals(thatCarrierIds[j])) {
                        return false;
                    }
                }
                continue;
            } else if (carrierIds == null && thatCarrierIds == null) {
                continue;
            }
            return false;
        }

        return Arrays.equals(mPolicyRules, that.mPolicyRules)
                && Arrays.equals(mPolicyRuleFlags, that.mPolicyRuleFlags);
    }

    private EuiccRulesAuthTable(Parcel source) {
        mPolicyRules = source.createIntArray();
        int len = mPolicyRules.length;
        mCarrierIds = new CarrierIdentifier[len][];
        for (int i = 0; i < len; i++) {
            mCarrierIds[i] = source.createTypedArray(CarrierIdentifier.CREATOR);
        }
        mPolicyRuleFlags = source.createIntArray();
    }

    public static final @android.annotation.NonNull Creator CREATOR =
            new Creator() {
                @Override
                public EuiccRulesAuthTable createFromParcel(Parcel source) {
                    return new EuiccRulesAuthTable(source);
                }

                @Override
                public EuiccRulesAuthTable[] newArray(int size) {
                    return new EuiccRulesAuthTable[size];
                }
            };
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy