Merge "Add indication APIs to expose QOS from LTE and NR bearers" am: 90f426fab4

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1395327

Change-Id: If4917e82f6dcc6e0f5606b0dfecabc7dbf72982d
This commit is contained in:
Daniel Bright
2020-12-04 17:58:04 +00:00
committed by Automerger Merge Worker
7 changed files with 988 additions and 10 deletions

View File

@@ -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",

View File

@@ -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.
*/
@@ -705,6 +762,35 @@ public final class DataCallResponse implements Parcelable {
return this;
}
/**
* 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.
*
@@ -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);
}
}
}

View File

@@ -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];
}
};
}

View File

@@ -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];
}
};
}

View File

@@ -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);
}
}

View File

@@ -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];
}
};
}

View File

@@ -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];
}
};
}