Merge "Add 5G/NR QOS support" am: bd3a33ed9f am: 3e7751c427 am: 80f11bb5bb
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1643762 Change-Id: I74c0d7d771d0b7e067dddc582389f77b8a899542
This commit is contained in:
committed by
Automerger Merge Worker
commit
89ff2a8ab6
@@ -12303,6 +12303,20 @@ package android.telephony.data {
|
|||||||
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.EpsBearerQosSessionAttributes> CREATOR;
|
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.EpsBearerQosSessionAttributes> CREATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class NrQosSessionAttributes implements android.os.Parcelable android.net.QosSessionAttributes {
|
||||||
|
method public int describeContents();
|
||||||
|
method public int get5Qi();
|
||||||
|
method public long getAveragingWindow();
|
||||||
|
method public long getGuaranteedDownlinkBitRate();
|
||||||
|
method public long getGuaranteedUplinkBitRate();
|
||||||
|
method public long getMaxDownlinkBitRate();
|
||||||
|
method public long getMaxUplinkBitRate();
|
||||||
|
method public int getQfi();
|
||||||
|
method @NonNull public java.util.List<java.net.InetSocketAddress> getRemoteAddresses();
|
||||||
|
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||||
|
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.NrQosSessionAttributes> CREATOR;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class QualifiedNetworksService extends android.app.Service {
|
public abstract class QualifiedNetworksService extends android.app.Service {
|
||||||
ctor public QualifiedNetworksService();
|
ctor public QualifiedNetworksService();
|
||||||
method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityProvider onCreateNetworkAvailabilityProvider(int);
|
method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityProvider onCreateNetworkAvailabilityProvider(int);
|
||||||
|
|||||||
@@ -232,8 +232,8 @@ package android.net {
|
|||||||
method public final void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
|
method public final void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
|
||||||
method public final void sendNetworkScore(@IntRange(from=0, to=99) int);
|
method public final void sendNetworkScore(@IntRange(from=0, to=99) int);
|
||||||
method public final void sendQosCallbackError(int, int);
|
method public final void sendQosCallbackError(int, int);
|
||||||
method public final void sendQosSessionAvailable(int, int, @NonNull android.telephony.data.EpsBearerQosSessionAttributes);
|
method public final void sendQosSessionAvailable(int, int, @NonNull android.net.QosSessionAttributes);
|
||||||
method public final void sendQosSessionLost(int, int);
|
method public final void sendQosSessionLost(int, int, int);
|
||||||
method public final void sendSocketKeepaliveEvent(int, int);
|
method public final void sendSocketKeepaliveEvent(int, int);
|
||||||
method @Deprecated public void setLegacySubtype(int, @NonNull String);
|
method @Deprecated public void setLegacySubtype(int, @NonNull String);
|
||||||
method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
|
method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
|
||||||
@@ -385,6 +385,7 @@ package android.net {
|
|||||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSession> CREATOR;
|
field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSession> CREATOR;
|
||||||
field public static final int TYPE_EPS_BEARER = 1; // 0x1
|
field public static final int TYPE_EPS_BEARER = 1; // 0x1
|
||||||
|
field public static final int TYPE_NR_BEARER = 2; // 0x2
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface QosSessionAttributes {
|
public interface QosSessionAttributes {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.net.NetworkInfo;
|
|||||||
import android.net.NetworkScore;
|
import android.net.NetworkScore;
|
||||||
import android.net.QosSession;
|
import android.net.QosSession;
|
||||||
import android.telephony.data.EpsBearerQosSessionAttributes;
|
import android.telephony.data.EpsBearerQosSessionAttributes;
|
||||||
|
import android.telephony.data.NrQosSessionAttributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for NetworkAgents to send network properties.
|
* Interface for NetworkAgents to send network properties.
|
||||||
@@ -37,6 +38,7 @@ oneway interface INetworkAgentRegistry {
|
|||||||
void sendSocketKeepaliveEvent(int slot, int reason);
|
void sendSocketKeepaliveEvent(int slot, int reason);
|
||||||
void sendUnderlyingNetworks(in @nullable List<Network> networks);
|
void sendUnderlyingNetworks(in @nullable List<Network> networks);
|
||||||
void sendEpsQosSessionAvailable(int callbackId, in QosSession session, in EpsBearerQosSessionAttributes attributes);
|
void sendEpsQosSessionAvailable(int callbackId, in QosSession session, in EpsBearerQosSessionAttributes attributes);
|
||||||
|
void sendNrQosSessionAvailable(int callbackId, in QosSession session, in NrQosSessionAttributes attributes);
|
||||||
void sendQosSessionLost(int qosCallbackId, in QosSession session);
|
void sendQosSessionLost(int qosCallbackId, in QosSession session);
|
||||||
void sendQosCallbackError(int qosCallbackId, int exceptionType);
|
void sendQosCallbackError(int qosCallbackId, int exceptionType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package android.net;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.net.QosSession;
|
import android.net.QosSession;
|
||||||
import android.telephony.data.EpsBearerQosSessionAttributes;
|
import android.telephony.data.EpsBearerQosSessionAttributes;
|
||||||
|
import android.telephony.data.NrQosSessionAttributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AIDL interface for QosCallback
|
* AIDL interface for QosCallback
|
||||||
@@ -29,6 +30,8 @@ oneway interface IQosCallback
|
|||||||
{
|
{
|
||||||
void onQosEpsBearerSessionAvailable(in QosSession session,
|
void onQosEpsBearerSessionAvailable(in QosSession session,
|
||||||
in EpsBearerQosSessionAttributes attributes);
|
in EpsBearerQosSessionAttributes attributes);
|
||||||
|
void onNrQosSessionAvailable(in QosSession session,
|
||||||
|
in NrQosSessionAttributes attributes);
|
||||||
void onQosSessionLost(in QosSession session);
|
void onQosSessionLost(in QosSession session);
|
||||||
void onError(in int type);
|
void onError(in int type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.os.Looper;
|
|||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.telephony.data.EpsBearerQosSessionAttributes;
|
import android.telephony.data.EpsBearerQosSessionAttributes;
|
||||||
|
import android.telephony.data.NrQosSessionAttributes;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
@@ -1160,29 +1161,37 @@ public abstract class NetworkAgent {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the attributes of Eps Bearer Qos Session back to the Application
|
* Sends the attributes of Qos Session back to the Application
|
||||||
*
|
*
|
||||||
* @param qosCallbackId the callback id that the session belongs to
|
* @param qosCallbackId the callback id that the session belongs to
|
||||||
* @param sessionId the unique session id across all Eps Bearer Qos Sessions
|
* @param sessionId the unique session id across all Qos Sessions
|
||||||
* @param attributes the attributes of the Eps Qos Session
|
* @param attributes the attributes of the Qos Session
|
||||||
*/
|
*/
|
||||||
public final void sendQosSessionAvailable(final int qosCallbackId, final int sessionId,
|
public final void sendQosSessionAvailable(final int qosCallbackId, final int sessionId,
|
||||||
@NonNull final EpsBearerQosSessionAttributes attributes) {
|
@NonNull final QosSessionAttributes attributes) {
|
||||||
Objects.requireNonNull(attributes, "The attributes must be non-null");
|
Objects.requireNonNull(attributes, "The attributes must be non-null");
|
||||||
queueOrSendMessage(ra -> ra.sendEpsQosSessionAvailable(qosCallbackId,
|
if (attributes instanceof EpsBearerQosSessionAttributes) {
|
||||||
new QosSession(sessionId, QosSession.TYPE_EPS_BEARER),
|
queueOrSendMessage(ra -> ra.sendEpsQosSessionAvailable(qosCallbackId,
|
||||||
attributes));
|
new QosSession(sessionId, QosSession.TYPE_EPS_BEARER),
|
||||||
|
(EpsBearerQosSessionAttributes)attributes));
|
||||||
|
} else if (attributes instanceof NrQosSessionAttributes) {
|
||||||
|
queueOrSendMessage(ra -> ra.sendNrQosSessionAvailable(qosCallbackId,
|
||||||
|
new QosSession(sessionId, QosSession.TYPE_NR_BEARER),
|
||||||
|
(NrQosSessionAttributes)attributes));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends event that the Eps Qos Session was lost.
|
* Sends event that the Qos Session was lost.
|
||||||
*
|
*
|
||||||
* @param qosCallbackId the callback id that the session belongs to
|
* @param qosCallbackId the callback id that the session belongs to
|
||||||
* @param sessionId the unique session id across all Eps Bearer Qos Sessions
|
* @param sessionId the unique session id across all Qos Sessions
|
||||||
|
* @param qosSessionType the session type {@code QosSesson#QosSessionType}
|
||||||
*/
|
*/
|
||||||
public final void sendQosSessionLost(final int qosCallbackId, final int sessionId) {
|
public final void sendQosSessionLost(final int qosCallbackId,
|
||||||
|
final int sessionId, final int qosSessionType) {
|
||||||
queueOrSendMessage(ra -> ra.sendQosSessionLost(qosCallbackId,
|
queueOrSendMessage(ra -> ra.sendQosSessionLost(qosCallbackId,
|
||||||
new QosSession(sessionId, QosSession.TYPE_EPS_BEARER)));
|
new QosSession(sessionId, qosSessionType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package android.net;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.telephony.data.EpsBearerQosSessionAttributes;
|
import android.telephony.data.EpsBearerQosSessionAttributes;
|
||||||
|
import android.telephony.data.NrQosSessionAttributes;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
@@ -83,6 +84,25 @@ class QosCallbackConnection extends android.net.IQosCallback.Stub {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when either the {@link NrQosSessionAttributes} has changed or on the first time
|
||||||
|
* the attributes have become available.
|
||||||
|
*
|
||||||
|
* @param session the session that is now available
|
||||||
|
* @param attributes the corresponding attributes of session
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onNrQosSessionAvailable(@NonNull final QosSession session,
|
||||||
|
@NonNull final NrQosSessionAttributes attributes) {
|
||||||
|
|
||||||
|
mExecutor.execute(() -> {
|
||||||
|
final QosCallback callback = mCallback;
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onQosSessionAvailable(session, attributes);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the session is lost.
|
* Called when the session is lost.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ public final class QosSession implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public static final int TYPE_EPS_BEARER = 1;
|
public static final int TYPE_EPS_BEARER = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link QosSession} is a NR Session.
|
||||||
|
*/
|
||||||
|
public static final int TYPE_NR_BEARER = 2;
|
||||||
|
|
||||||
private final int mSessionId;
|
private final int mSessionId;
|
||||||
|
|
||||||
private final int mSessionType;
|
private final int mSessionType;
|
||||||
@@ -100,6 +105,7 @@ public final class QosSession implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
@IntDef(value = {
|
@IntDef(value = {
|
||||||
TYPE_EPS_BEARER,
|
TYPE_EPS_BEARER,
|
||||||
|
TYPE_NR_BEARER,
|
||||||
})
|
})
|
||||||
@interface QosSessionType {}
|
@interface QosSessionType {}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import android.os.IBinder;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.telephony.data.EpsBearerQosSessionAttributes;
|
import android.telephony.data.EpsBearerQosSessionAttributes;
|
||||||
|
import android.telephony.data.NrQosSessionAttributes;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
@@ -633,7 +634,13 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
@Override
|
@Override
|
||||||
public void sendEpsQosSessionAvailable(final int qosCallbackId, final QosSession session,
|
public void sendEpsQosSessionAvailable(final int qosCallbackId, final QosSession session,
|
||||||
final EpsBearerQosSessionAttributes attributes) {
|
final EpsBearerQosSessionAttributes attributes) {
|
||||||
mQosCallbackTracker.sendEventQosSessionAvailable(qosCallbackId, session, attributes);
|
mQosCallbackTracker.sendEventEpsQosSessionAvailable(qosCallbackId, session, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendNrQosSessionAvailable(final int qosCallbackId, final QosSession session,
|
||||||
|
final NrQosSessionAttributes attributes) {
|
||||||
|
mQosCallbackTracker.sendEventNrQosSessionAvailable(qosCallbackId, session, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.net.QosSession;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.telephony.data.EpsBearerQosSessionAttributes;
|
import android.telephony.data.EpsBearerQosSessionAttributes;
|
||||||
|
import android.telephony.data.NrQosSessionAttributes;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -146,13 +147,23 @@ class QosCallbackAgentConnection implements IBinder.DeathRecipient {
|
|||||||
mNetworkAgentInfo.onQosCallbackUnregistered(mAgentCallbackId);
|
mNetworkAgentInfo.onQosCallbackUnregistered(mAgentCallbackId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendEventQosSessionAvailable(final QosSession session,
|
void sendEventEpsQosSessionAvailable(final QosSession session,
|
||||||
final EpsBearerQosSessionAttributes attributes) {
|
final EpsBearerQosSessionAttributes attributes) {
|
||||||
try {
|
try {
|
||||||
if (DBG) log("sendEventQosSessionAvailable: sending...");
|
if (DBG) log("sendEventEpsQosSessionAvailable: sending...");
|
||||||
mCallback.onQosEpsBearerSessionAvailable(session, attributes);
|
mCallback.onQosEpsBearerSessionAvailable(session, attributes);
|
||||||
} catch (final RemoteException e) {
|
} catch (final RemoteException e) {
|
||||||
loge("sendEventQosSessionAvailable: remote exception", e);
|
loge("sendEventEpsQosSessionAvailable: remote exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendEventNrQosSessionAvailable(final QosSession session,
|
||||||
|
final NrQosSessionAttributes attributes) {
|
||||||
|
try {
|
||||||
|
if (DBG) log("sendEventNrQosSessionAvailable: sending...");
|
||||||
|
mCallback.onNrQosSessionAvailable(session, attributes);
|
||||||
|
} catch (final RemoteException e) {
|
||||||
|
loge("sendEventNrQosSessionAvailable: remote exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.os.Binder;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.telephony.data.EpsBearerQosSessionAttributes;
|
import android.telephony.data.EpsBearerQosSessionAttributes;
|
||||||
|
import android.telephony.data.NrQosSessionAttributes;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.net.module.util.CollectionUtils;
|
import com.android.net.module.util.CollectionUtils;
|
||||||
@@ -179,17 +180,31 @@ public class QosCallbackTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the NetworkAgent sends the qos session available event
|
* Called when the NetworkAgent sends the qos session available event for EPS
|
||||||
*
|
*
|
||||||
* @param qosCallbackId the callback id that the qos session is now available to
|
* @param qosCallbackId the callback id that the qos session is now available to
|
||||||
* @param session the qos session that is now available
|
* @param session the qos session that is now available
|
||||||
* @param attributes the qos attributes that are now available on the qos session
|
* @param attributes the qos attributes that are now available on the qos session
|
||||||
*/
|
*/
|
||||||
public void sendEventQosSessionAvailable(final int qosCallbackId,
|
public void sendEventEpsQosSessionAvailable(final int qosCallbackId,
|
||||||
final QosSession session,
|
final QosSession session,
|
||||||
final EpsBearerQosSessionAttributes attributes) {
|
final EpsBearerQosSessionAttributes attributes) {
|
||||||
runOnAgentConnection(qosCallbackId, "sendEventQosSessionAvailable: ",
|
runOnAgentConnection(qosCallbackId, "sendEventEpsQosSessionAvailable: ",
|
||||||
ac -> ac.sendEventQosSessionAvailable(session, attributes));
|
ac -> ac.sendEventEpsQosSessionAvailable(session, attributes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the NetworkAgent sends the qos session available event for NR
|
||||||
|
*
|
||||||
|
* @param qosCallbackId the callback id that the qos session is now available to
|
||||||
|
* @param session the qos session that is now available
|
||||||
|
* @param attributes the qos attributes that are now available on the qos session
|
||||||
|
*/
|
||||||
|
public void sendEventNrQosSessionAvailable(final int qosCallbackId,
|
||||||
|
final QosSession session,
|
||||||
|
final NrQosSessionAttributes attributes) {
|
||||||
|
runOnAgentConnection(qosCallbackId, "sendEventNrQosSessionAvailable: ",
|
||||||
|
ac -> ac.sendEventNrQosSessionAvailable(session, attributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -50,6 +50,18 @@ public final class NrQos extends Qos implements Parcelable {
|
|||||||
return new NrQos(in);
|
return new NrQos(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int get5Qi() {
|
||||||
|
return fiveQi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getQfi() {
|
||||||
|
return qosFlowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAveragingWindow() {
|
||||||
|
return averagingWindowMs;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
super.writeToParcel(Qos.QOS_TYPE_NR, dest, flags);
|
super.writeToParcel(Qos.QOS_TYPE_NR, dest, flags);
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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;
|
||||||
|
|
||||||
|
parcelable NrQosSessionAttributes;
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.annotation.SystemApi;
|
||||||
|
import android.net.QosSessionAttributes;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides Qos attributes of an NR bearer.
|
||||||
|
*
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
@SystemApi
|
||||||
|
public final class NrQosSessionAttributes implements Parcelable, QosSessionAttributes {
|
||||||
|
private static final String TAG = NrQosSessionAttributes.class.getSimpleName();
|
||||||
|
private final int m5Qi;
|
||||||
|
private final int mQfi;
|
||||||
|
private final long mMaxUplinkBitRate;
|
||||||
|
private final long mMaxDownlinkBitRate;
|
||||||
|
private final long mGuaranteedUplinkBitRate;
|
||||||
|
private final long mGuaranteedDownlinkBitRate;
|
||||||
|
private final long mAveragingWindow;
|
||||||
|
@NonNull private final List<InetSocketAddress> mRemoteAddresses;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 5G QOS Identifier (5QI), see 3GPP TS 24.501 and 23.501.
|
||||||
|
* The allowed values are standard values(1-9, 65-68, 69-70, 75, 79-80, 82-85)
|
||||||
|
* defined in the spec and operator specific values in the range 128-254.
|
||||||
|
*
|
||||||
|
* @return the 5QI of the QOS flow
|
||||||
|
*/
|
||||||
|
public int get5Qi() {
|
||||||
|
return m5Qi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QOS flow identifier of the QOS flow description in the
|
||||||
|
* range of 1 to 63. see 3GPP TS 24.501 and 23.501.
|
||||||
|
*
|
||||||
|
* @return the QOS flow identifier of the session
|
||||||
|
*/
|
||||||
|
public int getQfi() {
|
||||||
|
return mQfi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum bit rate in kbps that is guaranteed to be provided by the network on the uplink.
|
||||||
|
*
|
||||||
|
* see 3GPP TS 24.501 section 6.2.5
|
||||||
|
*
|
||||||
|
* Note: The Qos Session may be shared with OTHER applications besides yours.
|
||||||
|
*
|
||||||
|
* @return the guaranteed bit rate in kbps
|
||||||
|
*/
|
||||||
|
public long getGuaranteedUplinkBitRate() {
|
||||||
|
return mGuaranteedUplinkBitRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum bit rate in kbps that is guaranteed to be provided by the network on the downlink.
|
||||||
|
*
|
||||||
|
* see 3GPP TS 24.501 section 6.2.5
|
||||||
|
*
|
||||||
|
* Note: The Qos Session may be shared with OTHER applications besides yours.
|
||||||
|
*
|
||||||
|
* @return the guaranteed bit rate in kbps
|
||||||
|
*/
|
||||||
|
public long getGuaranteedDownlinkBitRate() {
|
||||||
|
return mGuaranteedDownlinkBitRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum uplink kbps that the network will accept.
|
||||||
|
*
|
||||||
|
* see 3GPP TS 24.501 section 6.2.5
|
||||||
|
*
|
||||||
|
* Note: The Qos Session may be shared with OTHER applications besides yours.
|
||||||
|
*
|
||||||
|
* @return the max uplink bit rate in kbps
|
||||||
|
*/
|
||||||
|
public long getMaxUplinkBitRate() {
|
||||||
|
return mMaxUplinkBitRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum downlink kbps that the network can provide.
|
||||||
|
*
|
||||||
|
* see 3GPP TS 24.501 section 6.2.5
|
||||||
|
*
|
||||||
|
* Note: The Qos Session may be shared with OTHER applications besides yours.
|
||||||
|
*
|
||||||
|
* @return the max downlink bit rate in kbps
|
||||||
|
*/
|
||||||
|
public long getMaxDownlinkBitRate() {
|
||||||
|
return mMaxDownlinkBitRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The duration in milliseconds over which the maximum bit rates and guaranteed bit rates
|
||||||
|
* are calculated
|
||||||
|
*
|
||||||
|
* see 3GPP TS 24.501 section 6.2.5
|
||||||
|
*
|
||||||
|
* @return the averaging window duration in milliseconds
|
||||||
|
*/
|
||||||
|
public long getAveragingWindow() {
|
||||||
|
return mAveragingWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of remote addresses associated with the Qos Session. The given uplink bit rates apply
|
||||||
|
* to this given list of remote addresses.
|
||||||
|
*
|
||||||
|
* Note: In the event that the list is empty, it is assumed that the uplink bit rates apply to
|
||||||
|
* all remote addresses that are not contained in a different set of attributes.
|
||||||
|
*
|
||||||
|
* @return list of remote socket addresses that the attributes apply to
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public List<InetSocketAddress> getRemoteAddresses() {
|
||||||
|
return mRemoteAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ..ctor for attributes
|
||||||
|
*
|
||||||
|
* @param fiveQi 5G quality class indicator
|
||||||
|
* @param qfi QOS flow identifier
|
||||||
|
* @param maxDownlinkBitRate the max downlink bit rate in kbps
|
||||||
|
* @param maxUplinkBitRate the max uplink bit rate in kbps
|
||||||
|
* @param guaranteedDownlinkBitRate the guaranteed downlink bit rate in kbps
|
||||||
|
* @param guaranteedUplinkBitRate the guaranteed uplink bit rate in kbps
|
||||||
|
* @param averagingWindow the averaging window duration in milliseconds
|
||||||
|
* @param remoteAddresses the remote addresses that the uplink bit rates apply to
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public NrQosSessionAttributes(final int fiveQi, final int qfi,
|
||||||
|
final long maxDownlinkBitRate, final long maxUplinkBitRate,
|
||||||
|
final long guaranteedDownlinkBitRate, final long guaranteedUplinkBitRate,
|
||||||
|
final long averagingWindow, @NonNull final List<InetSocketAddress> remoteAddresses) {
|
||||||
|
Objects.requireNonNull(remoteAddresses, "remoteAddress must be non-null");
|
||||||
|
m5Qi = fiveQi;
|
||||||
|
mQfi = qfi;
|
||||||
|
mMaxDownlinkBitRate = maxDownlinkBitRate;
|
||||||
|
mMaxUplinkBitRate = maxUplinkBitRate;
|
||||||
|
mGuaranteedDownlinkBitRate = guaranteedDownlinkBitRate;
|
||||||
|
mGuaranteedUplinkBitRate = guaranteedUplinkBitRate;
|
||||||
|
mAveragingWindow = averagingWindow;
|
||||||
|
|
||||||
|
final List<InetSocketAddress> remoteAddressesTemp = copySocketAddresses(remoteAddresses);
|
||||||
|
mRemoteAddresses = Collections.unmodifiableList(remoteAddressesTemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<InetSocketAddress> copySocketAddresses(
|
||||||
|
@NonNull final List<InetSocketAddress> remoteAddresses) {
|
||||||
|
final List<InetSocketAddress> remoteAddressesTemp = new ArrayList<>();
|
||||||
|
for (final InetSocketAddress socketAddress : remoteAddresses) {
|
||||||
|
if (socketAddress != null && socketAddress.getAddress() != null) {
|
||||||
|
remoteAddressesTemp.add(socketAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return remoteAddressesTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NrQosSessionAttributes(@NonNull final Parcel in) {
|
||||||
|
m5Qi = in.readInt();
|
||||||
|
mQfi = in.readInt();
|
||||||
|
mMaxDownlinkBitRate = in.readLong();
|
||||||
|
mMaxUplinkBitRate = in.readLong();
|
||||||
|
mGuaranteedDownlinkBitRate = in.readLong();
|
||||||
|
mGuaranteedUplinkBitRate = in.readLong();
|
||||||
|
mAveragingWindow = in.readLong();
|
||||||
|
|
||||||
|
final int size = in.readInt();
|
||||||
|
final List<InetSocketAddress> remoteAddresses = new ArrayList<>(size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
final byte[] addressBytes = in.createByteArray();
|
||||||
|
final int port = in.readInt();
|
||||||
|
try {
|
||||||
|
remoteAddresses.add(
|
||||||
|
new InetSocketAddress(InetAddress.getByAddress(addressBytes), port));
|
||||||
|
} catch (final UnknownHostException e) {
|
||||||
|
// Impossible case since its filtered out the null values in the ..ctor
|
||||||
|
Log.e(TAG, "unable to unparcel remote address at index: " + i, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mRemoteAddresses = Collections.unmodifiableList(remoteAddresses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull final Parcel dest, final int flags) {
|
||||||
|
dest.writeInt(m5Qi);
|
||||||
|
dest.writeInt(mQfi);
|
||||||
|
dest.writeLong(mMaxDownlinkBitRate);
|
||||||
|
dest.writeLong(mMaxUplinkBitRate);
|
||||||
|
dest.writeLong(mGuaranteedDownlinkBitRate);
|
||||||
|
dest.writeLong(mGuaranteedUplinkBitRate);
|
||||||
|
dest.writeLong(mAveragingWindow);
|
||||||
|
|
||||||
|
final int size = mRemoteAddresses.size();
|
||||||
|
dest.writeInt(size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
final InetSocketAddress address = mRemoteAddresses.get(i);
|
||||||
|
dest.writeByteArray(address.getAddress().getAddress());
|
||||||
|
dest.writeInt(address.getPort());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static final Creator<NrQosSessionAttributes> CREATOR =
|
||||||
|
new Creator<NrQosSessionAttributes>() {
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public NrQosSessionAttributes createFromParcel(@NonNull final Parcel in) {
|
||||||
|
return new NrQosSessionAttributes(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public NrQosSessionAttributes[] newArray(final int size) {
|
||||||
|
return new NrQosSessionAttributes[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -265,6 +265,7 @@ import android.security.Credentials;
|
|||||||
import android.system.Os;
|
import android.system.Os;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.telephony.data.EpsBearerQosSessionAttributes;
|
import android.telephony.data.EpsBearerQosSessionAttributes;
|
||||||
|
import android.telephony.data.NrQosSessionAttributes;
|
||||||
import android.test.mock.MockContentResolver;
|
import android.test.mock.MockContentResolver;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
@@ -9963,13 +9964,43 @@ public class ConnectivityServiceTest {
|
|||||||
&& session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes));
|
&& session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes));
|
||||||
|
|
||||||
mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
|
mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
|
||||||
.sendQosSessionLost(qosCallbackId, sessionId);
|
.sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER);
|
||||||
waitForIdle();
|
waitForIdle();
|
||||||
verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session ->
|
verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session ->
|
||||||
session.getSessionId() == sessionId
|
session.getSessionId() == sessionId
|
||||||
&& session.getSessionType() == QosSession.TYPE_EPS_BEARER));
|
&& session.getSessionType() == QosSession.TYPE_EPS_BEARER));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNrQosCallbackAvailableAndLost() throws Exception {
|
||||||
|
mQosCallbackMockHelper = new QosCallbackMockHelper();
|
||||||
|
final int sessionId = 10;
|
||||||
|
final int qosCallbackId = 1;
|
||||||
|
|
||||||
|
when(mQosCallbackMockHelper.mFilter.validate())
|
||||||
|
.thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE);
|
||||||
|
mQosCallbackMockHelper.registerQosCallback(
|
||||||
|
mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback);
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
final NrQosSessionAttributes attributes = new NrQosSessionAttributes(
|
||||||
|
1, 2, 3, 4, 5, 6, 7, new ArrayList<>());
|
||||||
|
mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
|
||||||
|
.sendQosSessionAvailable(qosCallbackId, sessionId, attributes);
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
verify(mQosCallbackMockHelper.mCallback).onNrQosSessionAvailable(argThat(session ->
|
||||||
|
session.getSessionId() == sessionId
|
||||||
|
&& session.getSessionType() == QosSession.TYPE_NR_BEARER), eq(attributes));
|
||||||
|
|
||||||
|
mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
|
||||||
|
.sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_NR_BEARER);
|
||||||
|
waitForIdle();
|
||||||
|
verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session ->
|
||||||
|
session.getSessionId() == sessionId
|
||||||
|
&& session.getSessionType() == QosSession.TYPE_NR_BEARER));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQosCallbackTooManyRequests() throws Exception {
|
public void testQosCallbackTooManyRequests() throws Exception {
|
||||||
mQosCallbackMockHelper = new QosCallbackMockHelper();
|
mQosCallbackMockHelper = new QosCallbackMockHelper();
|
||||||
|
|||||||
Reference in New Issue
Block a user