Merge "Add indication APIs to expose QOS from LTE and NR bearers"
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
105
telephony/java/android/telephony/data/EpsQos.java
Normal file
105
telephony/java/android/telephony/data/EpsQos.java
Normal 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
112
telephony/java/android/telephony/data/NrQos.java
Normal file
112
telephony/java/android/telephony/data/NrQos.java
Normal 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
175
telephony/java/android/telephony/data/Qos.java
Normal file
175
telephony/java/android/telephony/data/Qos.java
Normal 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);
|
||||
}
|
||||
}
|
||||
373
telephony/java/android/telephony/data/QosFilter.java
Normal file
373
telephony/java/android/telephony/data/QosFilter.java
Normal 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
125
telephony/java/android/telephony/data/QosSession.java
Normal file
125
telephony/java/android/telephony/data/QosSession.java
Normal 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user