Merge "Add dependencies of EuiccCard." am: 90b4e47d94
am: 4f217d740a
Change-Id: I874b4244dd0c79c1bee34480c34d6ee6ac9e0855
This commit is contained in:
179
telephony/java/android/telephony/euicc/EuiccNotification.java
Normal file
179
telephony/java/android/telephony/euicc/EuiccNotification.java
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This represents a signed notification which is defined in SGP.22. It can be either a profile
|
||||
* installation result or a notification generated for profile operations (e.g., enabling,
|
||||
* disabling, or deleting).
|
||||
*
|
||||
* @hide
|
||||
*
|
||||
* TODO(b/35851809): Make this a @SystemApi.
|
||||
*/
|
||||
public class EuiccNotification implements Parcelable {
|
||||
/** Event */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(flag = true, prefix = { "EVENT_" }, value = {
|
||||
EVENT_INSTALL,
|
||||
EVENT_ENABLE,
|
||||
EVENT_DISABLE,
|
||||
EVENT_DELETE
|
||||
})
|
||||
public @interface Event {}
|
||||
|
||||
/** A profile is downloaded and installed. */
|
||||
public static final int EVENT_INSTALL = 1;
|
||||
|
||||
/** A profile is enabled. */
|
||||
public static final int EVENT_ENABLE = 1 << 1;
|
||||
|
||||
/** A profile is disabled. */
|
||||
public static final int EVENT_DISABLE = 1 << 2;
|
||||
|
||||
/** A profile is deleted. */
|
||||
public static final int EVENT_DELETE = 1 << 3;
|
||||
|
||||
/** Value of the bits of all above events */
|
||||
@Event
|
||||
public static final int ALL_EVENTS =
|
||||
EVENT_INSTALL | EVENT_ENABLE | EVENT_DISABLE | EVENT_DELETE;
|
||||
|
||||
private final int mSeq;
|
||||
private final String mTargetAddr;
|
||||
@Event private final int mEvent;
|
||||
@Nullable private final byte[] mData;
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
*
|
||||
* @param seq The sequence number of this notification.
|
||||
* @param targetAddr The target server where to send this notification.
|
||||
* @param event The event which causes this notification.
|
||||
* @param data The data which needs to be sent to the target server. This can be null for
|
||||
* building a list of notification metadata without data.
|
||||
*/
|
||||
public EuiccNotification(int seq, String targetAddr, @Event int event, @Nullable byte[] data) {
|
||||
mSeq = seq;
|
||||
mTargetAddr = targetAddr;
|
||||
mEvent = event;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
/** @return The sequence number of this notification. */
|
||||
public int getSeq() {
|
||||
return mSeq;
|
||||
}
|
||||
|
||||
/** @return The target server address where this notification should be sent to. */
|
||||
public String getTargetAddr() {
|
||||
return mTargetAddr;
|
||||
}
|
||||
|
||||
/** @return The event of this notification. */
|
||||
@Event
|
||||
public int getEvent() {
|
||||
return mEvent;
|
||||
}
|
||||
|
||||
/** @return The notification data which needs to be sent to the target server. */
|
||||
@Nullable
|
||||
public byte[] getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EuiccNotification that = (EuiccNotification) obj;
|
||||
return mSeq == that.mSeq
|
||||
&& Objects.equals(mTargetAddr, that.mTargetAddr)
|
||||
&& mEvent == that.mEvent
|
||||
&& Arrays.equals(mData, that.mData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = 31 * result + mSeq;
|
||||
result = 31 * result + Objects.hashCode(mTargetAddr);
|
||||
result = 31 * result + mEvent;
|
||||
result = 31 * result + Arrays.hashCode(mData);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EuiccNotification (seq="
|
||||
+ mSeq
|
||||
+ ", targetAddr="
|
||||
+ mTargetAddr
|
||||
+ ", event="
|
||||
+ mEvent
|
||||
+ ", data="
|
||||
+ (mData == null ? "null" : "byte[" + mData.length + "]")
|
||||
+ ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(mSeq);
|
||||
dest.writeString(mTargetAddr);
|
||||
dest.writeInt(mEvent);
|
||||
dest.writeByteArray(mData);
|
||||
}
|
||||
|
||||
private EuiccNotification(Parcel source) {
|
||||
mSeq = source.readInt();
|
||||
mTargetAddr = source.readString();
|
||||
mEvent = source.readInt();
|
||||
mData = source.createByteArray();
|
||||
}
|
||||
|
||||
public static final Creator<EuiccNotification> CREATOR =
|
||||
new Creator<EuiccNotification>() {
|
||||
@Override
|
||||
public EuiccNotification createFromParcel(Parcel source) {
|
||||
return new EuiccNotification(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EuiccNotification[] newArray(int size) {
|
||||
return new EuiccNotification[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
259
telephony/java/android/telephony/euicc/EuiccRat.java
Normal file
259
telephony/java/android/telephony/euicc/EuiccRat.java
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* 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.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;
|
||||
|
||||
/**
|
||||
* This represents the RAT (Rules Authorisation Table) stored on eUICC.
|
||||
*
|
||||
* @hide
|
||||
*
|
||||
* TODO(b/35851809): Make this a @SystemApi.
|
||||
*/
|
||||
public final class EuiccRat implements Parcelable {
|
||||
/** Profile policy rule flags */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(flag = true, prefix = { "POLICY_RULE_FLAG_" }, value = {
|
||||
POLICY_RULE_FLAG_CONSENT_REQUIRED
|
||||
})
|
||||
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 EuiccRat} 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 EuiccRat build() {
|
||||
if (mPosition != mPolicyRules.length) {
|
||||
throw new IllegalStateException(
|
||||
"Not enough rules are added, expected: "
|
||||
+ mPolicyRules.length
|
||||
+ ", added: "
|
||||
+ mPosition);
|
||||
}
|
||||
return new EuiccRat(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, CarrierIdentifier[] carrierId, int policyRuleFlags) {
|
||||
if (mPosition >= mPolicyRules.length) {
|
||||
throw new ArrayIndexOutOfBoundsException(mPosition);
|
||||
}
|
||||
mPolicyRules[mPosition] = policyRules;
|
||||
mCarrierIds[mPosition] = carrierId;
|
||||
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 EuiccRat(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;
|
||||
}
|
||||
|
||||
EuiccRat that = (EuiccRat) 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 EuiccRat(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 Creator<EuiccRat> CREATOR =
|
||||
new Creator<EuiccRat>() {
|
||||
@Override
|
||||
public EuiccRat createFromParcel(Parcel source) {
|
||||
return new EuiccRat(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EuiccRat[] newArray(int size) {
|
||||
return new EuiccRat[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user