summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--StubLibraries.bp1
-rw-r--r--telephony/java/android/telephony/data/DataCallResponse.java107
-rw-r--r--telephony/java/android/telephony/data/EpsQos.java105
-rw-r--r--telephony/java/android/telephony/data/NrQos.java112
-rw-r--r--telephony/java/android/telephony/data/Qos.java175
-rw-r--r--telephony/java/android/telephony/data/QosFilter.java373
-rw-r--r--telephony/java/android/telephony/data/QosSession.java125
7 files changed, 988 insertions, 10 deletions
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 90bac37b944e..2f3945f88f35 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -68,6 +68,7 @@ stubs_defaults {
"android.hardware.cas-V1.2-java",
"android.hardware.health-V1.0-java-constants",
"android.hardware.radio-V1.5-java",
+ "android.hardware.radio-V1.6-java",
"android.hardware.thermal-V1.0-java-constants",
"android.hardware.thermal-V2.0-java",
"android.hardware.tv.input-V1.0-java-constants",
diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java
index ca9bf3cfaa0d..f0088b913d4e 100644
--- a/telephony/java/android/telephony/data/DataCallResponse.java
+++ b/telephony/java/android/telephony/data/DataCallResponse.java
@@ -134,6 +134,8 @@ public final class DataCallResponse implements Parcelable {
private final int mMtuV6;
private final @HandoverFailureMode int mHandoverFailureMode;
private final int mPduSessionId;
+ private final Qos mDefaultQos;
+ private final List<QosSession> mQosSessions;
/**
* @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error.
@@ -182,6 +184,8 @@ public final class DataCallResponse implements Parcelable {
mMtu = mMtuV4 = mMtuV6 = mtu;
mHandoverFailureMode = HANDOVER_FAILURE_MODE_LEGACY;
mPduSessionId = PDU_SESSION_ID_NOT_SET;
+ mDefaultQos = null;
+ mQosSessions = new ArrayList<>();
}
private DataCallResponse(@DataFailureCause int cause, long suggestedRetryTime, int id,
@@ -189,7 +193,8 @@ public final class DataCallResponse implements Parcelable {
@Nullable String interfaceName, @Nullable List<LinkAddress> addresses,
@Nullable List<InetAddress> dnsAddresses, @Nullable List<InetAddress> gatewayAddresses,
@Nullable List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6,
- @HandoverFailureMode int handoverFailureMode, int pduSessionId) {
+ @HandoverFailureMode int handoverFailureMode, int pduSessionId,
+ @Nullable Qos defaultQos, @Nullable List<QosSession> qosSessions) {
mCause = cause;
mSuggestedRetryTime = suggestedRetryTime;
mId = id;
@@ -209,6 +214,8 @@ public final class DataCallResponse implements Parcelable {
mMtuV6 = mtuV6;
mHandoverFailureMode = handoverFailureMode;
mPduSessionId = pduSessionId;
+ mDefaultQos = defaultQos;
+ mQosSessions = qosSessions;
}
/** @hide */
@@ -233,6 +240,9 @@ public final class DataCallResponse implements Parcelable {
mMtuV6 = source.readInt();
mHandoverFailureMode = source.readInt();
mPduSessionId = source.readInt();
+ mDefaultQos = source.readParcelable(Qos.class.getClassLoader());
+ mQosSessions = new ArrayList<>();
+ source.readList(mQosSessions, QosSession.class.getClassLoader());
}
/**
@@ -350,6 +360,28 @@ public final class DataCallResponse implements Parcelable {
return mPduSessionId;
}
+ /**
+ * @return default QOS of the data call received from the network
+ *
+ * @hide
+ */
+
+ @Nullable
+ public Qos getDefaultQos() {
+ return mDefaultQos;
+ }
+
+ /**
+ * @return All the dedicated bearer QOS sessions of the data call received from the network
+ *
+ * @hide
+ */
+
+ @NonNull
+ public List<QosSession> getQosSessions() {
+ return mQosSessions;
+ }
+
@NonNull
@Override
public String toString() {
@@ -370,6 +402,8 @@ public final class DataCallResponse implements Parcelable {
.append(" mtuV6=").append(getMtuV6())
.append(" handoverFailureMode=").append(getHandoverFailureMode())
.append(" pduSessionId=").append(getPduSessionId())
+ .append(" defaultQos=").append(mDefaultQos)
+ .append(" qosSessions=").append(mQosSessions)
.append("}");
return sb.toString();
}
@@ -383,12 +417,22 @@ public final class DataCallResponse implements Parcelable {
}
DataCallResponse other = (DataCallResponse) o;
- return this.mCause == other.mCause
- && this.mSuggestedRetryTime == other.mSuggestedRetryTime
- && this.mId == other.mId
- && this.mLinkStatus == other.mLinkStatus
- && this.mProtocolType == other.mProtocolType
- && this.mInterfaceName.equals(other.mInterfaceName)
+
+ final boolean isQosSame = (mDefaultQos == null || other.mDefaultQos == null) ?
+ mDefaultQos == other.mDefaultQos :
+ mDefaultQos.equals(other.mDefaultQos);
+
+ final boolean isQosSessionsSame = (mQosSessions == null || mQosSessions == null) ?
+ mQosSessions == other.mQosSessions :
+ mQosSessions.size() == other.mQosSessions.size()
+ && mQosSessions.containsAll(other.mQosSessions);
+
+ return mCause == other.mCause
+ && mSuggestedRetryTime == other.mSuggestedRetryTime
+ && mId == other.mId
+ && mLinkStatus == other.mLinkStatus
+ && mProtocolType == other.mProtocolType
+ && mInterfaceName.equals(other.mInterfaceName)
&& mAddresses.size() == other.mAddresses.size()
&& mAddresses.containsAll(other.mAddresses)
&& mDnsAddresses.size() == other.mDnsAddresses.size()
@@ -401,14 +445,17 @@ public final class DataCallResponse implements Parcelable {
&& mMtuV4 == other.mMtuV4
&& mMtuV6 == other.mMtuV6
&& mHandoverFailureMode == other.mHandoverFailureMode
- && mPduSessionId == other.mPduSessionId;
+ && mPduSessionId == other.mPduSessionId
+ && isQosSame
+ && isQosSessionsSame;
}
@Override
public int hashCode() {
return Objects.hash(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType,
mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, mPcscfAddresses,
- mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId);
+ mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, mDefaultQos,
+ mQosSessions);
}
@Override
@@ -433,6 +480,12 @@ public final class DataCallResponse implements Parcelable {
dest.writeInt(mMtuV6);
dest.writeInt(mHandoverFailureMode);
dest.writeInt(mPduSessionId);
+ if (mDefaultQos.getType() == Qos.QOS_TYPE_EPS) {
+ dest.writeParcelable((EpsQos)mDefaultQos, flags);
+ } else {
+ dest.writeParcelable((NrQos)mDefaultQos, flags);
+ }
+ dest.writeList(mQosSessions);
}
public static final @android.annotation.NonNull Parcelable.Creator<DataCallResponse> CREATOR =
@@ -512,6 +565,10 @@ public final class DataCallResponse implements Parcelable {
private int mPduSessionId = PDU_SESSION_ID_NOT_SET;
+ private Qos mDefaultQos;
+
+ private List<QosSession> mQosSessions = new ArrayList<>();
+
/**
* Default constructor for Builder.
*/
@@ -706,6 +763,35 @@ public final class DataCallResponse implements Parcelable {
}
/**
+ * Set the default QOS for this data connection.
+ *
+ * @param defaultQos QOS (Quality Of Service) received from network.
+ *
+ * @return The same instance of the builder.
+ *
+ * @hide
+ */
+ public @NonNull Builder setDefaultQos(@Nullable Qos defaultQos) {
+ mDefaultQos = defaultQos;
+ return this;
+ }
+
+ /**
+ * Set the dedicated bearer QOS sessions for this data connection.
+ *
+ * @param qosSessions Dedicated bearer QOS (Quality Of Service) sessions received
+ * from network.
+ *
+ * @return The same instance of the builder.
+ *
+ * @hide
+ */
+ public @NonNull Builder setQosSessions(@NonNull List<QosSession> qosSessions) {
+ mQosSessions = qosSessions;
+ return this;
+ }
+
+ /**
* Build the DataCallResponse.
*
* @return the DataCallResponse object.
@@ -713,7 +799,8 @@ public final class DataCallResponse implements Parcelable {
public @NonNull DataCallResponse build() {
return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus,
mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses,
- mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId);
+ mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId,
+ mDefaultQos, mQosSessions);
}
}
}
diff --git a/telephony/java/android/telephony/data/EpsQos.java b/telephony/java/android/telephony/data/EpsQos.java
new file mode 100644
index 000000000000..ad43068b2f11
--- /dev/null
+++ b/telephony/java/android/telephony/data/EpsQos.java
@@ -0,0 +1,105 @@
+/**
+ * Copyright 2020 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.data;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+
+/**
+ * Class that stores information specific to NR QOS.
+ *
+ * @hide
+ */
+public final class EpsQos extends Qos implements Parcelable {
+
+ int qosClassId;
+
+ public EpsQos() {
+ super(Qos.QOS_TYPE_EPS,
+ new android.hardware.radio.V1_6.QosBandwidth(),
+ new android.hardware.radio.V1_6.QosBandwidth());
+ }
+
+ public EpsQos(@NonNull android.hardware.radio.V1_6.EpsQos qos) {
+ super(Qos.QOS_TYPE_EPS, qos.downlink, qos.uplink);
+ qosClassId = qos.qci;
+ }
+
+ private EpsQos(Parcel source) {
+ super(source);
+ qosClassId = source.readInt();
+ }
+
+ public static @NonNull EpsQos createFromParcelBody(@NonNull Parcel in) {
+ return new EpsQos(in);
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ super.writeToParcel(Qos.QOS_TYPE_EPS, dest, flags);
+ dest.writeInt(qosClassId);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), qosClassId);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (o == null || !(o instanceof EpsQos)) {
+ return false;
+ }
+
+ EpsQos other = (EpsQos) o;
+
+ return this.qosClassId == other.qosClassId
+ && super.equals(other);
+ }
+
+ @Override
+ public String toString() {
+ return "EpsQos {"
+ + " qosClassId=" + qosClassId
+ + " downlink=" + downlink
+ + " uplink=" + uplink + "}";
+ }
+
+ public static final @NonNull Parcelable.Creator<EpsQos> CREATOR =
+ new Parcelable.Creator<EpsQos>() {
+ @Override
+ public EpsQos createFromParcel(Parcel source) {
+ return new EpsQos(source);
+ }
+
+ @Override
+ public EpsQos[] newArray(int size) {
+ return new EpsQos[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/data/NrQos.java b/telephony/java/android/telephony/data/NrQos.java
new file mode 100644
index 000000000000..2011eed26977
--- /dev/null
+++ b/telephony/java/android/telephony/data/NrQos.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright 2020 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.data;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Class that stores information specific to NR QOS.
+ *
+ * @hide
+ */
+public final class NrQos extends Qos implements Parcelable {
+ int qosFlowId;
+ int fiveQi;
+ int averagingWindowMs;
+
+ public NrQos(@NonNull android.hardware.radio.V1_6.NrQos qos) {
+ super(Qos.QOS_TYPE_NR, qos.downlink, qos.uplink);
+ fiveQi = qos.fiveQi;
+ qosFlowId = qos.qfi;
+ averagingWindowMs = qos.averagingWindowMs;
+ }
+
+ private NrQos(Parcel source) {
+ super(source);
+ this.qosFlowId = source.readInt();
+ this.fiveQi = source.readInt();
+ this.averagingWindowMs = source.readInt();
+ }
+
+ public static @NonNull NrQos createFromParcelBody(@NonNull Parcel in) {
+ return new NrQos(in);
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ super.writeToParcel(Qos.QOS_TYPE_NR, dest, flags);
+ dest.writeInt(qosFlowId);
+ dest.writeInt(fiveQi);
+ dest.writeInt(averagingWindowMs);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), qosFlowId, fiveQi, averagingWindowMs);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (o == null || !(o instanceof NrQos)) {
+ return false;
+ }
+
+ NrQos other = (NrQos) o;
+
+ if (!super.equals(other)) {
+ return false;
+ }
+
+ return this.qosFlowId == other.qosFlowId
+ && this.fiveQi == other.fiveQi
+ && this.averagingWindowMs == other.averagingWindowMs;
+ }
+
+ @Override
+ public String toString() {
+ return "NrQos {"
+ + " fiveQi=" + fiveQi
+ + " downlink=" + downlink
+ + " uplink=" + uplink
+ + " qosFlowId=" + qosFlowId
+ + " averagingWindowMs=" + averagingWindowMs + "}";
+ }
+
+ public static final @NonNull Parcelable.Creator<NrQos> CREATOR =
+ new Parcelable.Creator<NrQos>() {
+ @Override
+ public NrQos createFromParcel(Parcel source) {
+ return new NrQos(source);
+ }
+
+ @Override
+ public NrQos[] newArray(int size) {
+ return new NrQos[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/data/Qos.java b/telephony/java/android/telephony/data/Qos.java
new file mode 100644
index 000000000000..c8bb91e28bf2
--- /dev/null
+++ b/telephony/java/android/telephony/data/Qos.java
@@ -0,0 +1,175 @@
+/**
+ * Copyright 2020 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.data;
+
+import android.annotation.CallSuper;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Class that stores information specific to QOS.
+ *
+ * @hide
+ */
+public abstract class Qos {
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "QOS_TYPE_",
+ value = {QOS_TYPE_EPS, QOS_TYPE_NR})
+ public @interface QosType {}
+
+ @QosType
+ final int type;
+
+ static final int QOS_TYPE_EPS = 1;
+ static final int QOS_TYPE_NR = 2;
+
+ final QosBandwidth downlink;
+ final QosBandwidth uplink;
+
+ Qos(int type,
+ @NonNull android.hardware.radio.V1_6.QosBandwidth downlink,
+ @NonNull android.hardware.radio.V1_6.QosBandwidth uplink) {
+ this.type = type;
+ this.downlink = new QosBandwidth(downlink.maxBitrateKbps, downlink.guaranteedBitrateKbps);
+ this.uplink = new QosBandwidth(uplink.maxBitrateKbps, uplink.guaranteedBitrateKbps);
+ }
+
+ static class QosBandwidth implements Parcelable {
+ int maxBitrateKbps;
+ int guaranteedBitrateKbps;
+
+ QosBandwidth() {
+ }
+
+ QosBandwidth(int maxBitrateKbps, int guaranteedBitrateKbps) {
+ this.maxBitrateKbps = maxBitrateKbps;
+ this.guaranteedBitrateKbps = guaranteedBitrateKbps;
+ }
+
+ private QosBandwidth(Parcel source) {
+ maxBitrateKbps = source.readInt();
+ guaranteedBitrateKbps = source.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(maxBitrateKbps);
+ dest.writeInt(guaranteedBitrateKbps);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(maxBitrateKbps, guaranteedBitrateKbps);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (o == null || !(o instanceof QosBandwidth)) {
+ return false;
+ }
+
+ QosBandwidth other = (QosBandwidth) o;
+ return maxBitrateKbps == other.maxBitrateKbps
+ && guaranteedBitrateKbps == other.guaranteedBitrateKbps;
+ }
+
+ @Override
+ public String toString() {
+ return "Bandwidth {"
+ + " maxBitrateKbps=" + maxBitrateKbps
+ + " guaranteedBitrateKbps=" + guaranteedBitrateKbps + "}";
+ }
+
+ public static final @NonNull Parcelable.Creator<QosBandwidth> CREATOR =
+ new Parcelable.Creator<QosBandwidth>() {
+ @Override
+ public QosBandwidth createFromParcel(Parcel source) {
+ return new QosBandwidth(source);
+ }
+
+ @Override
+ public QosBandwidth[] newArray(int size) {
+ return new QosBandwidth[size];
+ }
+ };
+ };
+
+ protected Qos(@NonNull Parcel source) {
+ type = source.readInt();
+ downlink = source.readParcelable(QosBandwidth.class.getClassLoader());
+ uplink = source.readParcelable(QosBandwidth.class.getClassLoader());
+ }
+
+ /**
+ * Used by child classes for parceling.
+ *
+ * @hide
+ */
+ @CallSuper
+ public void writeToParcel(@QosType int type, Parcel dest, int flags) {
+ dest.writeInt(type);
+ dest.writeParcelable(downlink, flags);
+ dest.writeParcelable(uplink, flags);
+ }
+
+ /** @hide */
+ public static @NonNull Qos create(@NonNull android.hardware.radio.V1_6.Qos qos) {
+ switch (qos.getDiscriminator()) {
+ case android.hardware.radio.V1_6.Qos.hidl_discriminator.eps:
+ return new EpsQos(qos.eps());
+ case android.hardware.radio.V1_6.Qos.hidl_discriminator.nr:
+ return new NrQos(qos.nr());
+ default:
+ return null;
+ }
+ }
+
+ /** @hide */
+ public @QosType int getType() {
+ return type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(downlink, uplink);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ Qos other = (Qos) o;
+ return type == other.type
+ && downlink.equals(other.downlink)
+ && uplink.equals(other.uplink);
+ }
+}
diff --git a/telephony/java/android/telephony/data/QosFilter.java b/telephony/java/android/telephony/data/QosFilter.java
new file mode 100644
index 000000000000..69277445634d
--- /dev/null
+++ b/telephony/java/android/telephony/data/QosFilter.java
@@ -0,0 +1,373 @@
+/**
+ * Copyright 2020 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.data;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.net.InetAddresses;
+import android.net.LinkAddress;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+
+/**
+ * Class that stores QOS filter parameters as defined in
+ * 3gpp 24.008 10.5.6.12 and 3gpp 24.501 9.11.4.13.
+ *
+ * @hide
+ */
+public final class QosFilter implements Parcelable {
+
+ private List<LinkAddress> localAddresses;
+ private List<LinkAddress> remoteAddresses;
+ private PortRange localPort;
+ private PortRange remotePort;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "QOS_PROTOCOL_",
+ value = {QOS_PROTOCOL_UNSPECIFIED, QOS_PROTOCOL_TCP, QOS_PROTOCOL_UDP,
+ QOS_PROTOCOL_ESP, QOS_PROTOCOL_AH})
+ public @interface QosProtocol {}
+
+ public static final int QOS_PROTOCOL_UNSPECIFIED =
+ android.hardware.radio.V1_6.QosProtocol.UNSPECIFIED;
+ public static final int QOS_PROTOCOL_TCP = android.hardware.radio.V1_6.QosProtocol.TCP;
+ public static final int QOS_PROTOCOL_UDP = android.hardware.radio.V1_6.QosProtocol.UDP;
+ public static final int QOS_PROTOCOL_ESP = android.hardware.radio.V1_6.QosProtocol.ESP;
+ public static final int QOS_PROTOCOL_AH = android.hardware.radio.V1_6.QosProtocol.AH;
+
+ @QosProtocol
+ private int protocol;
+
+ private int typeOfServiceMask;
+
+ private long flowLabel;
+
+ /** IPSec security parameter index */
+ private long securityParameterIndex;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "QOS_FILTER_DIRECTION_",
+ value = {QOS_FILTER_DIRECTION_DOWNLINK, QOS_FILTER_DIRECTION_UPLINK,
+ QOS_FILTER_DIRECTION_BIDIRECTIONAL})
+ public @interface QosFilterDirection {}
+
+ public static final int QOS_FILTER_DIRECTION_DOWNLINK =
+ android.hardware.radio.V1_6.QosFilterDirection.DOWNLINK;
+ public static final int QOS_FILTER_DIRECTION_UPLINK =
+ android.hardware.radio.V1_6.QosFilterDirection.UPLINK;
+ public static final int QOS_FILTER_DIRECTION_BIDIRECTIONAL =
+ android.hardware.radio.V1_6.QosFilterDirection.BIDIRECTIONAL;
+
+ @QosFilterDirection
+ private int filterDirection;
+
+ /**
+ * Specified the order in which the filter needs to be matched.
+ * A Lower numerical value has a higher precedence.
+ */
+ private int precedence;
+
+ QosFilter() {
+ localAddresses = new ArrayList<>();
+ remoteAddresses = new ArrayList<>();
+ localPort = new PortRange();
+ remotePort = new PortRange();
+ protocol = QOS_PROTOCOL_UNSPECIFIED;
+ filterDirection = QOS_FILTER_DIRECTION_BIDIRECTIONAL;
+ }
+
+ public QosFilter(List<LinkAddress> localAddresses, List<LinkAddress> remoteAddresses,
+ PortRange localPort, PortRange remotePort, int protocol, int tos,
+ long flowLabel, long spi, int direction, int precedence) {
+ this.localAddresses = localAddresses;
+ this.remoteAddresses = remoteAddresses;
+ this.localPort = localPort;
+ this.remotePort = remotePort;
+ this.protocol = protocol;
+ this.typeOfServiceMask = tos;
+ this.flowLabel = flowLabel;
+ this.securityParameterIndex = spi;
+ this.filterDirection = direction;
+ this.precedence = precedence;
+ }
+
+ /** @hide */
+ public static @NonNull QosFilter create(
+ @NonNull android.hardware.radio.V1_6.QosFilter qosFilter) {
+ QosFilter ret = new QosFilter();
+
+ String[] localAddresses = qosFilter.localAddresses.stream().toArray(String[]::new);
+ if (localAddresses != null) {
+ for (String address : localAddresses) {
+ ret.localAddresses.add(createLinkAddressFromString(address));
+ }
+ }
+
+ String[] remoteAddresses = qosFilter.remoteAddresses.stream().toArray(String[]::new);
+ if (remoteAddresses != null) {
+ for (String address : remoteAddresses) {
+ ret.remoteAddresses.add(createLinkAddressFromString(address));
+ }
+ }
+
+ if (qosFilter.localPort != null) {
+ if (qosFilter.localPort.getDiscriminator()
+ == android.hardware.radio.V1_6.MaybePort.hidl_discriminator.range) {
+ final android.hardware.radio.V1_6.PortRange portRange = qosFilter.localPort.range();
+ ret.localPort.start = portRange.start;
+ ret.localPort.end = portRange.end;
+ }
+ }
+
+ if (qosFilter.remotePort != null) {
+ if (qosFilter.remotePort.getDiscriminator()
+ == android.hardware.radio.V1_6.MaybePort.hidl_discriminator.range) {
+ final android.hardware.radio.V1_6.PortRange portRange
+ = qosFilter.remotePort.range();
+ ret.remotePort.start = portRange.start;
+ ret.remotePort.end = portRange.end;
+ }
+ }
+
+ ret.protocol = qosFilter.protocol;
+
+ if (qosFilter.tos != null) {
+ if (qosFilter.tos.getDiscriminator()
+ == android.hardware.radio.V1_6.QosFilter.TypeOfService.hidl_discriminator.value) {
+ ret.typeOfServiceMask = qosFilter.tos.value();
+ }
+ }
+
+ if (qosFilter.flowLabel != null) {
+ if (qosFilter.flowLabel.getDiscriminator()
+ == android.hardware.radio.V1_6.QosFilter.Ipv6FlowLabel.hidl_discriminator.value) {
+ ret.flowLabel = qosFilter.flowLabel.value();
+ }
+ }
+
+ if (qosFilter.spi != null) {
+ if (qosFilter.spi.getDiscriminator()
+ == android.hardware.radio.V1_6.QosFilter.IpsecSpi.hidl_discriminator.value) {
+ ret.securityParameterIndex = qosFilter.spi.value();
+ }
+ }
+
+ ret.filterDirection = qosFilter.direction;
+ ret.precedence = qosFilter.precedence;
+
+ return ret;
+ }
+
+ public static class PortRange implements Parcelable {
+ int start;
+ int end;
+
+ PortRange() {
+ start = -1;
+ end = -1;
+ }
+
+ private PortRange(Parcel source) {
+ start = source.readInt();
+ end = source.readInt();
+ }
+
+ public PortRange(int start, int end) {
+ this.start = start;
+ this.end = end;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(start);
+ dest.writeInt(end);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final @NonNull Parcelable.Creator<PortRange> CREATOR =
+ new Parcelable.Creator<PortRange>() {
+ @Override
+ public PortRange createFromParcel(Parcel source) {
+ return new PortRange(source);
+ }
+
+ @Override
+ public PortRange[] newArray(int size) {
+ return new PortRange[size];
+ }
+ };
+
+ @Override
+ public String toString() {
+ return "PortRange {"
+ + " start=" + start
+ + " end=" + end + "}";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (o == null || !(o instanceof PortRange)) {
+ return false;
+ }
+
+ PortRange other = (PortRange) o;
+ return start == other.start
+ && end == other.end;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(start, end);
+ }
+ };
+
+ @Override
+ public String toString() {
+ return "QosFilter {"
+ + " localAddresses=" + localAddresses
+ + " remoteAddresses=" + remoteAddresses
+ + " localPort=" + localPort
+ + " remotePort=" + remotePort
+ + " protocol=" + protocol
+ + " typeOfServiceMask=" + typeOfServiceMask
+ + " flowLabel=" + flowLabel
+ + " securityParameterIndex=" + securityParameterIndex
+ + " filterDirection=" + filterDirection
+ + " precedence=" + precedence + "}";
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(localAddresses, remoteAddresses, localPort,
+ remotePort, protocol, typeOfServiceMask, flowLabel,
+ securityParameterIndex, filterDirection, precedence);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (o == null || !(o instanceof QosFilter)) {
+ return false;
+ }
+
+ QosFilter other = (QosFilter) o;
+
+ return localAddresses.size() == other.localAddresses.size()
+ && localAddresses.containsAll(other.localAddresses)
+ && remoteAddresses.size() == other.remoteAddresses.size()
+ && remoteAddresses.containsAll(other.remoteAddresses)
+ && localPort.equals(other.localPort)
+ && remotePort.equals(other.remotePort)
+ && protocol == other.protocol
+ && typeOfServiceMask == other.typeOfServiceMask
+ && flowLabel == other.flowLabel
+ && securityParameterIndex == other.securityParameterIndex
+ && filterDirection == other.filterDirection
+ && precedence == other.precedence;
+ }
+
+ private static LinkAddress createLinkAddressFromString(String addressString) {
+ addressString = addressString.trim();
+ InetAddress address = null;
+ int prefixLength = -1;
+ try {
+ String[] pieces = addressString.split("/", 2);
+ address = InetAddresses.parseNumericAddress(pieces[0]);
+ if (pieces.length == 1) {
+ prefixLength = (address instanceof Inet4Address) ? 32 : 128;
+ } else if (pieces.length == 2) {
+ prefixLength = Integer.parseInt(pieces[1]);
+ }
+ } catch (NullPointerException e) { // Null string.
+ } catch (ArrayIndexOutOfBoundsException e) { // No prefix length.
+ } catch (NumberFormatException e) { // Non-numeric prefix.
+ } catch (IllegalArgumentException e) { // Invalid IP address.
+ }
+
+ if (address == null || prefixLength == -1) {
+ throw new IllegalArgumentException("Invalid link address " + addressString);
+ }
+
+ return new LinkAddress(address, prefixLength, 0, 0,
+ LinkAddress.LIFETIME_UNKNOWN, LinkAddress.LIFETIME_UNKNOWN);
+ }
+
+ private QosFilter(Parcel source) {
+ localAddresses = new ArrayList<>();
+ source.readList(localAddresses, LinkAddress.class.getClassLoader());
+ remoteAddresses = new ArrayList<>();
+ source.readList(remoteAddresses, LinkAddress.class.getClassLoader());
+ localPort = source.readParcelable(PortRange.class.getClassLoader());
+ remotePort = source.readParcelable(PortRange.class.getClassLoader());
+ protocol = source.readInt();
+ typeOfServiceMask = source.readInt();
+ flowLabel = source.readLong();
+ securityParameterIndex = source.readLong();
+ filterDirection = source.readInt();
+ precedence = source.readInt();
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeList(localAddresses);
+ dest.writeList(remoteAddresses);
+ dest.writeParcelable(localPort, flags);
+ dest.writeParcelable(remotePort, flags);
+ dest.writeInt(protocol);
+ dest.writeInt(typeOfServiceMask);
+ dest.writeLong(flowLabel);
+ dest.writeLong(securityParameterIndex);
+ dest.writeInt(filterDirection);
+ dest.writeInt(precedence);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final @NonNull Parcelable.Creator<QosFilter> CREATOR =
+ new Parcelable.Creator<QosFilter>() {
+ @Override
+ public QosFilter createFromParcel(Parcel source) {
+ return new QosFilter(source);
+ }
+
+ @Override
+ public QosFilter[] newArray(int size) {
+ return new QosFilter[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/data/QosSession.java b/telephony/java/android/telephony/data/QosSession.java
new file mode 100644
index 000000000000..f07b6a9f6725
--- /dev/null
+++ b/telephony/java/android/telephony/data/QosSession.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright 2020 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.data;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+
+/**
+ * Class that stores information specific to QOS session.
+ *
+ * @hide
+ */
+public final class QosSession implements Parcelable{
+
+ final int qosSessionId;
+ final Qos qos;
+ final List<QosFilter> qosFilterList;
+
+ public QosSession(int qosSessionId, @NonNull Qos qos, @NonNull List<QosFilter> qosFilterList) {
+ this.qosSessionId = qosSessionId;
+ this.qos = qos;
+ this.qosFilterList = qosFilterList;
+ }
+
+ private QosSession(Parcel source) {
+ qosSessionId = source.readInt();
+ qos = source.readParcelable(Qos.class.getClassLoader());
+ qosFilterList = new ArrayList<>();
+ source.readList(qosFilterList, QosFilter.class.getClassLoader());
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(qosSessionId);
+ if (qos.getType() == Qos.QOS_TYPE_EPS) {
+ dest.writeParcelable((EpsQos)qos, flags);
+ } else {
+ dest.writeParcelable((NrQos)qos, flags);
+ }
+ dest.writeList(qosFilterList);
+ }
+
+ public static @NonNull QosSession create(
+ @NonNull android.hardware.radio.V1_6.QosSession qosSession) {
+ List<QosFilter> qosFilters = new ArrayList<>();
+
+ if (qosSession.qosFilters != null) {
+ for (android.hardware.radio.V1_6.QosFilter filter : qosSession.qosFilters) {
+ qosFilters.add(QosFilter.create(filter));
+ }
+ }
+
+ return new QosSession(
+ qosSession.qosSessionId,
+ Qos.create(qosSession.qos),
+ qosFilters);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ return "QosSession {"
+ + " qosSessionId=" + qosSessionId
+ + " qos=" + qos
+ + " qosFilterList=" + qosFilterList + "}";
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(qosSessionId, qos, qosFilterList);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (o == null || !(o instanceof QosSession)) {
+ return false;
+ }
+
+ QosSession other = (QosSession) o;
+ return this.qosSessionId == other.qosSessionId
+ && this.qos.equals(other.qos)
+ && this.qosFilterList.size() == other.qosFilterList.size()
+ && this.qosFilterList.containsAll(other.qosFilterList);
+ }
+
+
+ public static final @NonNull Parcelable.Creator<QosSession> CREATOR =
+ new Parcelable.Creator<QosSession>() {
+ @Override
+ public QosSession createFromParcel(Parcel source) {
+ return new QosSession(source);
+ }
+
+ @Override
+ public QosSession[] newArray(int size) {
+ return new QosSession[size];
+ }
+ };
+}