diff --git a/core/api/current.txt b/core/api/current.txt index 0b2c6f4fe6966..d100104a4158b 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -41036,6 +41036,7 @@ package android.telephony { method public String getNetworkOperator(); method public String getNetworkOperatorName(); method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public int getNetworkSelectionMode(); + method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getNetworkSlicingConfiguration(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver); method public String getNetworkSpecifier(); method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getNetworkType(); method @Deprecated public int getPhoneCount(); @@ -41269,6 +41270,13 @@ package android.telephony { field public static final int ERROR_TIMEOUT = 1; // 0x1 } + public static class TelephonyManager.SlicingException extends java.lang.Exception { + ctor public TelephonyManager.SlicingException(int); + method public int getErrorCode(); + field public static final int ERROR_MODEM_ERROR = 2; // 0x2 + field public static final int ERROR_TIMEOUT = 1; // 0x1 + } + public abstract static class TelephonyManager.UssdResponseCallback { ctor public TelephonyManager.UssdResponseCallback(); method public void onReceiveUssdResponse(android.telephony.TelephonyManager, String, CharSequence); @@ -41444,6 +41452,88 @@ package android.telephony.data { method @NonNull public android.telephony.data.ApnSetting.Builder setUser(@Nullable String); } + public final class NetworkSliceInfo implements android.os.Parcelable { + method public int describeContents(); + method @IntRange(from=0xffffffff, to=0xfffffe) public int getMappedHplmnSliceDifferentiator(); + method public int getMappedHplmnSliceServiceType(); + method @IntRange(from=0xffffffff, to=0xfffffe) public int getSliceDifferentiator(); + method public int getSliceServiceType(); + method public int getStatus(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int SLICE_DIFFERENTIATOR_NO_SLICE = -1; // 0xffffffff + field public static final int SLICE_SERVICE_TYPE_EMBB = 1; // 0x1 + field public static final int SLICE_SERVICE_TYPE_MIOT = 3; // 0x3 + field public static final int SLICE_SERVICE_TYPE_NONE = 0; // 0x0 + field public static final int SLICE_SERVICE_TYPE_URLLC = 2; // 0x2 + field public static final int SLICE_STATUS_ALLOWED = 2; // 0x2 + field public static final int SLICE_STATUS_CONFIGURED = 1; // 0x1 + field public static final int SLICE_STATUS_DEFAULT_CONFIGURED = 5; // 0x5 + field public static final int SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_PLMN = 3; // 0x3 + field public static final int SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_REGISTERED_AREA = 4; // 0x4 + field public static final int SLICE_STATUS_UNKNOWN = 0; // 0x0 + } + + public static final class NetworkSliceInfo.Builder { + ctor public NetworkSliceInfo.Builder(); + method @NonNull public android.telephony.data.NetworkSliceInfo build(); + method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setMappedHplmnSliceDifferentiator(@IntRange(from=0xffffffff, to=0xfffffe) int); + method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setMappedHplmnSliceServiceType(int); + method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setSliceDifferentiator(@IntRange(from=0xffffffff, to=0xfffffe) int); + method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setSliceServiceType(int); + method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setStatus(int); + } + + public final class RouteSelectionDescriptor implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public java.util.List getDataNetworkName(); + method @IntRange(from=0x0, to=0xff) public int getPrecedence(); + method public int getSessionType(); + method @NonNull public java.util.List getSliceInfo(); + method public int getSscMode(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int ROUTE_SSC_MODE_1 = 1; // 0x1 + field public static final int ROUTE_SSC_MODE_2 = 2; // 0x2 + field public static final int ROUTE_SSC_MODE_3 = 3; // 0x3 + field public static final int SESSION_TYPE_IPV4 = 0; // 0x0 + field public static final int SESSION_TYPE_IPV4V6 = 2; // 0x2 + field public static final int SESSION_TYPE_IPV6 = 1; // 0x1 + } + + public final class SlicingConfig implements android.os.Parcelable { + ctor public SlicingConfig(); + method public int describeContents(); + method @NonNull public java.util.List getSliceInfo(); + method @NonNull public java.util.List getUrspRules(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + + public final class TrafficDescriptor implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public String getDataNetworkName(); + method @Nullable public String getOsAppId(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + + public static final class TrafficDescriptor.Builder { + ctor public TrafficDescriptor.Builder(); + method @NonNull public android.telephony.data.TrafficDescriptor build(); + method @NonNull public android.telephony.data.TrafficDescriptor.Builder setDataNetworkName(@NonNull String); + method @NonNull public android.telephony.data.TrafficDescriptor.Builder setOsAppId(@NonNull String); + } + + public final class UrspRule implements android.os.Parcelable { + method public int describeContents(); + method @IntRange(from=0x0, to=0xff) public int getPrecedence(); + method @NonNull public java.util.List getRouteSelectionDescriptor(); + method @NonNull public java.util.List getTrafficDescriptors(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + } package android.telephony.emergency { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 3e423e6908fd3..906a5951dc869 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -10800,32 +10800,6 @@ package android.telephony.data { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } - public final class NetworkSliceInfo implements android.os.Parcelable { - method public int describeContents(); - method @IntRange(from=android.telephony.data.NetworkSliceInfo.MIN_SLICE_DIFFERENTIATOR, to=android.telephony.data.NetworkSliceInfo.MAX_SLICE_DIFFERENTIATOR) public int getMappedHplmnSliceDifferentiator(); - method public int getMappedHplmnSliceServiceType(); - method @IntRange(from=android.telephony.data.NetworkSliceInfo.MIN_SLICE_DIFFERENTIATOR, to=android.telephony.data.NetworkSliceInfo.MAX_SLICE_DIFFERENTIATOR) public int getSliceDifferentiator(); - method public int getSliceServiceType(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator CREATOR; - field public static final int MAX_SLICE_DIFFERENTIATOR = 16777214; // 0xfffffe - field public static final int MIN_SLICE_DIFFERENTIATOR = -1; // 0xffffffff - field public static final int SLICE_DIFFERENTIATOR_NO_SLICE = -1; // 0xffffffff - field public static final int SLICE_SERVICE_TYPE_EMBB = 1; // 0x1 - field public static final int SLICE_SERVICE_TYPE_MIOT = 3; // 0x3 - field public static final int SLICE_SERVICE_TYPE_NONE = 0; // 0x0 - field public static final int SLICE_SERVICE_TYPE_URLLC = 2; // 0x2 - } - - public static final class NetworkSliceInfo.Builder { - ctor public NetworkSliceInfo.Builder(); - method @NonNull public android.telephony.data.NetworkSliceInfo build(); - method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setMappedHplmnSliceDifferentiator(@IntRange(from=android.telephony.data.NetworkSliceInfo.MIN_SLICE_DIFFERENTIATOR, to=android.telephony.data.NetworkSliceInfo.MAX_SLICE_DIFFERENTIATOR) int); - method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setMappedHplmnSliceServiceType(int); - method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setSliceDifferentiator(@IntRange(from=android.telephony.data.NetworkSliceInfo.MIN_SLICE_DIFFERENTIATOR, to=android.telephony.data.NetworkSliceInfo.MAX_SLICE_DIFFERENTIATOR) int); - method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setSliceServiceType(int); - } - public final class NrQosSessionAttributes implements android.os.Parcelable android.net.QosSessionAttributes { method public int describeContents(); method @NonNull public java.time.Duration getBitRateWindowDuration(); @@ -10882,15 +10856,6 @@ package android.telephony.data { method @NonNull public android.telephony.data.ThrottleStatus.Builder setTransportType(int); } - public final class TrafficDescriptor implements android.os.Parcelable { - ctor public TrafficDescriptor(@Nullable String, @Nullable String); - method public int describeContents(); - method @Nullable public String getDnn(); - method @Nullable public String getOsAppId(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator CREATOR; - } - } package android.telephony.euicc { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index b8a173ed5aee5..f55dc8b6f8f13 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -86,6 +86,7 @@ import android.telephony.CallForwardingInfo.CallForwardingReason; import android.telephony.VisualVoicemailService.VisualVoicemailTask; import android.telephony.data.ApnSetting; import android.telephony.data.ApnSetting.MvnoType; +import android.telephony.data.SlicingConfig; import android.telephony.emergency.EmergencyNumber; import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories; import android.telephony.gba.UaSecurityProtocolIdentifier; @@ -15221,4 +15222,96 @@ public class TelephonyManager { return PhoneCapability.DEFAULT_SSSS_CAPABILITY; } } + + /** + * Exception that may be supplied to the callback in {@link #getNetworkSlicingConfiguration} if + * something goes awry. + */ + public static class SlicingException extends Exception { + /** + * Getting the current slicing configuration successfully. Used internally only. + * @hide + */ + public static final int SUCCESS = 0; + + /** + * The system timed out waiting for a response from the Radio. + */ + public static final int ERROR_TIMEOUT = 1; + + /** + * The modem returned a failure. + */ + public static final int ERROR_MODEM_ERROR = 2; + + /** @hide */ + @IntDef(prefix = {"ERROR_"}, value = { + ERROR_TIMEOUT, + ERROR_MODEM_ERROR, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SlicingError {} + + private final int mErrorCode; + + public SlicingException(@SlicingError int errorCode) { + mErrorCode = errorCode; + } + + /** + * Fetches the error code associated with this exception. + * @return An error code. + */ + public @SlicingError int getErrorCode() { + return mErrorCode; + } + } + + /** @hide */ + public static final String KEY_SLICING_CONFIG_HANDLE = "slicing_config_handle"; + + /** + * Request to get the current slicing configuration including URSP rules and + * NSSAIs (configured, allowed and rejected). + * + * This method can be invoked if one of the following requirements is met: + *
    + *
  • If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this + * is a privileged permission that can only be granted to apps preloaded on the device. + *
  • If the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + *
+ * + * @param executor the executor on which callback will be invoked. + * @param callback a callback to receive the current slicing configuration. + */ + @SuppressAutoDoc // No support for carrier privileges (b/72967236). + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void getNetworkSlicingConfiguration( + @NonNull @CallbackExecutor Executor executor, + @NonNull OutcomeReceiver callback) { + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); + + try { + ITelephony telephony = getITelephony(); + if (telephony == null) { + throw new IllegalStateException("telephony service is null."); + } + telephony.getSlicingConfig(new ResultReceiver(null) { + @Override + protected void onReceiveResult(int resultCode, Bundle result) { + if (resultCode != SlicingException.SUCCESS) { + executor.execute(() -> callback.onError( + new SlicingException(resultCode))); + return; + } + SlicingConfig slicingConfig = + result.getParcelable(KEY_SLICING_CONFIG_HANDLE); + executor.execute(() -> callback.onResult(slicingConfig)); + } + }); + } catch (RemoteException ex) { + ex.rethrowAsRuntimeException(); + } + } } diff --git a/telephony/java/android/telephony/data/NetworkSliceInfo.java b/telephony/java/android/telephony/data/NetworkSliceInfo.java index 1d90095336858..232a93012f4bd 100644 --- a/telephony/java/android/telephony/data/NetworkSliceInfo.java +++ b/telephony/java/android/telephony/data/NetworkSliceInfo.java @@ -19,8 +19,6 @@ package android.telephony.data; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; -import android.annotation.SuppressLint; -import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -35,10 +33,7 @@ import java.util.Objects; * SliceServiceType defines the type of service provided by the slice, and SliceDifferentiator is * used to differentiate between multiple slices of the same type. If the devices is not on HPLMN, * the mappedHplmn versions of these 2 fields indicate the corresponding values in HPLMN. - * - * @hide */ -@SystemApi public final class NetworkSliceInfo implements Parcelable { /** * When set on a Slice Differentiator, this value indicates that there is no corresponding @@ -68,14 +63,14 @@ public final class NetworkSliceInfo implements Parcelable { /** * The min acceptable value for a Slice Differentiator + * @hide */ - @SuppressLint("MinMaxConstant") public static final int MIN_SLICE_DIFFERENTIATOR = -1; /** * The max acceptable value for a Slice Differentiator + * @hide */ - @SuppressLint("MinMaxConstant") public static final int MAX_SLICE_DIFFERENTIATOR = 0xFFFFFE; /** @hide */ @@ -88,6 +83,62 @@ public final class NetworkSliceInfo implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface SliceServiceType {} + /** + * The slice status is unknown. This can happen during IWLAN->cellular handover when the + * NetworkSliceInfo is received over IWLAN. + */ + public static final int SLICE_STATUS_UNKNOWN = 0; + + /** + * The slice is configured but not allowed or rejected yet. + */ + public static final int SLICE_STATUS_CONFIGURED = 1; + + /** + * The slice is allowed to be used. + */ + public static final int SLICE_STATUS_ALLOWED = 2; + + /** + * The slice is rejected because not available in PLMN. + */ + public static final int SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_PLMN = 3; + + /** + * The slice is rejected because not available in registered area. + */ + public static final int SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_REGISTERED_AREA = 4; + + /** + * The slice is configured by home operator(HPLMN) in default and is used if configured/allowed + * slices are not available for the serving PLMN. + */ + public static final int SLICE_STATUS_DEFAULT_CONFIGURED = 5; + + /** + * The min acceptable value for a slice status. + * @hide + */ + public static final int MIN_SLICE_STATUS = SLICE_STATUS_UNKNOWN; + + /** + * The max acceptable value for a slice status. + * @hide + */ + public static final int MAX_SLICE_STATUS = SLICE_STATUS_DEFAULT_CONFIGURED; + + /** @hide */ + @IntDef(prefix = { "SLICE_STATUS_" }, value = { + SLICE_STATUS_UNKNOWN, + SLICE_STATUS_CONFIGURED, + SLICE_STATUS_ALLOWED, + SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_PLMN, + SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_REGISTERED_AREA, + SLICE_STATUS_DEFAULT_CONFIGURED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SliceStatus {} + @SliceServiceType private final int mSliceServiceType; @@ -97,14 +148,18 @@ public final class NetworkSliceInfo implements Parcelable { private final int mMappedHplmnSliceServiceType; @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) private final int mMappedHplmnSliceDifferentiator; + @SliceStatus + @IntRange(from = MIN_SLICE_STATUS, to = MAX_SLICE_STATUS) + private final int mStatus; private NetworkSliceInfo(@SliceServiceType int sliceServiceType, int sliceDifferentiator, int mappedHplmnSliceServiceType, - int mappedHplmnSliceDifferentiator) { + int mappedHplmnSliceDifferentiator, int status) { mSliceServiceType = sliceServiceType; mSliceDifferentiator = sliceDifferentiator; mMappedHplmnSliceDifferentiator = mappedHplmnSliceDifferentiator; mMappedHplmnSliceServiceType = mappedHplmnSliceServiceType; + mStatus = status; } /** @@ -157,11 +212,21 @@ public final class NetworkSliceInfo implements Parcelable { return mMappedHplmnSliceDifferentiator; } + /** + * Field to indicate the current status of the slice. + * @return the current status for this slice info. + */ + @SliceStatus + public int getStatus() { + return mStatus; + } + private NetworkSliceInfo(@NonNull Parcel in) { mSliceServiceType = in.readInt(); mSliceDifferentiator = in.readInt(); mMappedHplmnSliceServiceType = in.readInt(); mMappedHplmnSliceDifferentiator = in.readInt(); + mStatus = in.readInt(); } @Override @@ -175,6 +240,7 @@ public final class NetworkSliceInfo implements Parcelable { dest.writeInt(mSliceDifferentiator); dest.writeInt(mMappedHplmnSliceServiceType); dest.writeInt(mMappedHplmnSliceDifferentiator); + dest.writeInt(mStatus); } public static final @android.annotation.NonNull Parcelable.Creator CREATOR = @@ -200,6 +266,7 @@ public final class NetworkSliceInfo implements Parcelable { + ", mMappedHplmnSliceServiceType=" + sliceServiceTypeToString(mMappedHplmnSliceServiceType) + ", mMappedHplmnSliceDifferentiator=" + mMappedHplmnSliceDifferentiator + + ", mStatus=" + sliceStatusToString(mStatus) + '}'; } @@ -218,6 +285,25 @@ public final class NetworkSliceInfo implements Parcelable { } } + private static String sliceStatusToString(@SliceStatus int sliceStatus) { + switch(sliceStatus) { + case SLICE_STATUS_UNKNOWN: + return "UNKNOWN"; + case SLICE_STATUS_CONFIGURED: + return "CONFIGURED"; + case SLICE_STATUS_ALLOWED: + return "ALLOWED"; + case SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_PLMN: + return "REJECTED_NOT_AVAILABLE_IN_PLMN"; + case SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_REGISTERED_AREA: + return "REJECTED_NOT_AVAILABLE_IN_REGISTERED_AREA"; + case SLICE_STATUS_DEFAULT_CONFIGURED: + return "DEFAULT_CONFIGURED"; + default: + return Integer.toString(sliceStatus); + } + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -226,13 +312,14 @@ public final class NetworkSliceInfo implements Parcelable { return mSliceServiceType == sliceInfo.mSliceServiceType && mSliceDifferentiator == sliceInfo.mSliceDifferentiator && mMappedHplmnSliceServiceType == sliceInfo.mMappedHplmnSliceServiceType - && mMappedHplmnSliceDifferentiator == sliceInfo.mMappedHplmnSliceDifferentiator; + && mMappedHplmnSliceDifferentiator == sliceInfo.mMappedHplmnSliceDifferentiator + && mStatus == sliceInfo.mStatus; } @Override public int hashCode() { return Objects.hash(mSliceServiceType, mSliceDifferentiator, mMappedHplmnSliceServiceType, - mMappedHplmnSliceDifferentiator); + mMappedHplmnSliceDifferentiator, mStatus); } /** @@ -257,6 +344,9 @@ public final class NetworkSliceInfo implements Parcelable { private int mMappedHplmnSliceServiceType = SLICE_SERVICE_TYPE_NONE; @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) private int mMappedHplmnSliceDifferentiator = SLICE_DIFFERENTIATOR_NO_SLICE; + @SliceStatus + @IntRange(from = MIN_SLICE_STATUS, to = MAX_SLICE_STATUS) + private int mStatus = SLICE_STATUS_UNKNOWN; /** * Default constructor for Builder. @@ -281,8 +371,7 @@ public final class NetworkSliceInfo implements Parcelable { * A value of {@link #SLICE_DIFFERENTIATOR_NO_SLICE} indicates that there is no * corresponding Slice. * - * @throws IllegalArgumentException if the parameter is not between - * {@link #MIN_SLICE_DIFFERENTIATOR} and {@link #MAX_SLICE_DIFFERENTIATOR}. + * @throws IllegalArgumentException if the parameter is not in the expected range. * * @return The same instance of the builder. */ @@ -316,8 +405,7 @@ public final class NetworkSliceInfo implements Parcelable { * A value of {@link #SLICE_DIFFERENTIATOR_NO_SLICE} indicates that there is no * corresponding Slice of the HPLMN. * - * @throws IllegalArgumentException if the parameter is not between - * {@link #MIN_SLICE_DIFFERENTIATOR} and {@link #MAX_SLICE_DIFFERENTIATOR}. + * @throws IllegalArgumentException if the parameter is not in the expected range. * * @return The same instance of the builder. */ @@ -333,6 +421,22 @@ public final class NetworkSliceInfo implements Parcelable { return this; } + /** + * Set the slice status. + * + * @throws IllegalArgumentException if the status is invalid. + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setStatus(@SliceStatus int status) { + if (status < MIN_SLICE_STATUS || status > MAX_SLICE_STATUS) { + throw new IllegalArgumentException("The slice status is not valid"); + } + this.mStatus = status; + return this; + } + /** * Build the {@link NetworkSliceInfo}. * @@ -341,7 +445,8 @@ public final class NetworkSliceInfo implements Parcelable { @NonNull public NetworkSliceInfo build() { return new NetworkSliceInfo(this.mSliceServiceType, this.mSliceDifferentiator, - this.mMappedHplmnSliceServiceType, this.mMappedHplmnSliceDifferentiator); + this.mMappedHplmnSliceServiceType, this.mMappedHplmnSliceDifferentiator, + this.mStatus); } } } diff --git a/telephony/java/android/telephony/data/RouteSelectionDescriptor.aidl b/telephony/java/android/telephony/data/RouteSelectionDescriptor.aidl new file mode 100644 index 0000000000000..563a00e5d177b --- /dev/null +++ b/telephony/java/android/telephony/data/RouteSelectionDescriptor.aidl @@ -0,0 +1,19 @@ +/* + * Copyright 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 RouteSelectionDescriptor; diff --git a/telephony/java/android/telephony/data/RouteSelectionDescriptor.java b/telephony/java/android/telephony/data/RouteSelectionDescriptor.java new file mode 100644 index 0000000000000..c2457f21f5efe --- /dev/null +++ b/telephony/java/android/telephony/data/RouteSelectionDescriptor.java @@ -0,0 +1,263 @@ +/** + * Copyright 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.IntDef; +import android.annotation.IntRange; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Represents a single route selection descriptor as defined in + * 3GPP TS 24.526. + */ +public final class RouteSelectionDescriptor implements Parcelable { + /** + * The min acceptable value for the precedence of a route selection descriptor. + * @hide + */ + public static final int MIN_ROUTE_PRECEDENCE = 0; + + /** + * The max acceptable value for the precedence of a route selection descriptor. + * @hide + */ + public static final int MAX_ROUTE_PRECEDENCE = 255; + + /** + * The route selection descriptor is for the session with IPV4 type. + */ + public static final int SESSION_TYPE_IPV4 = 0; + + /** + * The route selection descriptor is for the session with IPV6 type. + */ + public static final int SESSION_TYPE_IPV6 = 1; + + /** + * The route selection descriptor is for the session with both IP and IPV6 types. + */ + public static final int SESSION_TYPE_IPV4V6 = 2; + + /** @hide */ + @IntDef(prefix = { "SESSION_TYPE_" }, value = { + SESSION_TYPE_IPV4, + SESSION_TYPE_IPV6, + SESSION_TYPE_IPV4V6, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface RouteSessionType {} + + /** + * The route selection descriptor is using SSC mode 1. The session will provide continual + * support when UE's location is updated. + */ + public static final int ROUTE_SSC_MODE_1 = 1; + + /** + * The route selection descriptor is using SSC mode 2. The new session for the same network + * will be established after releasing the old session when UE's location is updated. + */ + public static final int ROUTE_SSC_MODE_2 = 2; + + /** + * The route selection descriptor is using SSC mode 3. The new session for the same network is + * allowed to be established before releasing the old session when UE's location is updated. + */ + public static final int ROUTE_SSC_MODE_3 = 3; + + /** + * The min acceptable value for the SSC mode of a route selection descriptor. + * @hide + */ + public static final int MIN_ROUTE_SSC_MODE = ROUTE_SSC_MODE_1; + + /** + * The max acceptable value for the SSC mode of a route selection descriptor. + * @hide + */ + public static final int MAX_ROUTE_SSC_MODE = ROUTE_SSC_MODE_3; + + /** @hide */ + @IntDef(prefix = { "ROUTE_SSC_MODE_" }, value = { + ROUTE_SSC_MODE_1, + ROUTE_SSC_MODE_2, + ROUTE_SSC_MODE_3, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface RouteSscMode {} + + @IntRange(from = MIN_ROUTE_PRECEDENCE, to = MAX_ROUTE_PRECEDENCE) + private final int mPrecedence; + @RouteSessionType + private final int mSessionType; + @RouteSscMode + @IntRange(from = MIN_ROUTE_SSC_MODE, to = MAX_ROUTE_SSC_MODE) + private final int mSscMode; + private final List mSliceInfo; + private final List mDnn; + + /** @hide */ + RouteSelectionDescriptor(android.hardware.radio.V1_6.RouteSelectionDescriptor rsd) { + this(rsd.precedence, rsd.sessionType.value(), rsd.sscMode.value(), rsd.sliceInfo, + rsd.dnn); + } + + /** @hide */ + public RouteSelectionDescriptor(int precedence, int sessionType, int sscMode, + List sliceInfo, List dnn) { + mPrecedence = precedence; + mSessionType = sessionType; + mSscMode = sscMode; + mSliceInfo = new ArrayList(); + for (android.hardware.radio.V1_6.SliceInfo si : sliceInfo) { + mSliceInfo.add(sliceInfoBuilder(si)); + } + mDnn = new ArrayList(); + mDnn.addAll(dnn); + } + + private NetworkSliceInfo sliceInfoBuilder(android.hardware.radio.V1_6.SliceInfo si) { + NetworkSliceInfo.Builder builder = new NetworkSliceInfo.Builder() + .setSliceServiceType(si.sst) + .setMappedHplmnSliceServiceType(si.mappedHplmnSst); + if (si.sliceDifferentiator != NetworkSliceInfo.SLICE_DIFFERENTIATOR_NO_SLICE) { + builder + .setSliceDifferentiator(si.sliceDifferentiator) + .setMappedHplmnSliceDifferentiator(si.mappedHplmnSD); + } + return builder.build(); + } + + private RouteSelectionDescriptor(Parcel p) { + mPrecedence = p.readInt(); + mSessionType = p.readInt(); + mSscMode = p.readInt(); + mSliceInfo = p.createTypedArrayList(NetworkSliceInfo.CREATOR); + mDnn = new ArrayList(); + p.readStringList(mDnn); + } + + /** + * Precedence value in the range of 0 to 255. Higher value has lower precedence. + * @return the precedence value for this route selection descriptor. + */ + @IntRange(from = MIN_ROUTE_PRECEDENCE, to = MAX_ROUTE_PRECEDENCE) + public int getPrecedence() { + return mPrecedence; + } + + /** + * This is used for checking which session type defined in 3GPP TS 23.501 is allowed for the + * route in a route selection descriptor. + * @return the session type for this route selection descriptor. + */ + @RouteSessionType + public int getSessionType() { + return mSessionType; + } + + /** + * SSC mode stands for Session and Service Continuity mode (which specifies the IP continuity + * mode) as defined in 3GPP TS 23.501. + * @return the SSC mode for this route selection descriptor. + */ + @RouteSscMode + public int getSscMode() { + return mSscMode; + } + + /** + * This is the list of all the slices available in the route selection descriptor as indicated + * by the network. These are the slices that can be used by the device if this route selection + * descriptor is used based the traffic (see 3GPP TS 23.501 for details). + * @return the list of all the slices available in the route selection descriptor. + */ + public @NonNull List getSliceInfo() { + return mSliceInfo; + } + + /** + * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003. There + * can be 0 or more DNNs specified in a route selection descriptor. + * @return the list of DNN for this route selection descriptor. + */ + public @NonNull List getDataNetworkName() { + return mDnn; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mPrecedence); + dest.writeInt(mSessionType); + dest.writeInt(mSscMode); + dest.writeTypedList(mSliceInfo, flags); + dest.writeStringList(mDnn); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public RouteSelectionDescriptor createFromParcel(Parcel source) { + return new RouteSelectionDescriptor(source); + } + + @Override + public RouteSelectionDescriptor[] newArray(int size) { + return new RouteSelectionDescriptor[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public boolean equals(@Nullable Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RouteSelectionDescriptor that = (RouteSelectionDescriptor) o; + return mPrecedence == that.mPrecedence + && mSessionType == that.mSessionType + && mSscMode == that.mSscMode + && mSliceInfo.size() == that.mSliceInfo.size() + && mSliceInfo.containsAll(that.mSliceInfo) + && mDnn.size() == that.mDnn.size() + && mDnn.containsAll(that.mDnn); + } + + @Override + public int hashCode() { + return Objects.hash(mPrecedence, mSessionType, mSscMode, mSliceInfo, mDnn); + } + + @Override + public String toString() { + return "{.precedence = " + mPrecedence + ", .sessionType = " + mSessionType + + ", .sscMode = " + mSscMode + ", .sliceInfo = " + mSliceInfo + + ", .dnn = " + mDnn + "}"; + } +} diff --git a/telephony/java/android/telephony/data/SlicingConfig.aidl b/telephony/java/android/telephony/data/SlicingConfig.aidl new file mode 100644 index 0000000000000..ad93d8cafeba4 --- /dev/null +++ b/telephony/java/android/telephony/data/SlicingConfig.aidl @@ -0,0 +1,19 @@ +/* + * Copyright 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 SlicingConfig; diff --git a/telephony/java/android/telephony/data/SlicingConfig.java b/telephony/java/android/telephony/data/SlicingConfig.java new file mode 100644 index 0000000000000..990e4d218930b --- /dev/null +++ b/telephony/java/android/telephony/data/SlicingConfig.java @@ -0,0 +1,137 @@ +/** + * Copyright 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.Nullable; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Represents a slicing configuration + */ +public final class SlicingConfig implements Parcelable { + private final List mUrspRules; + private final List mSliceInfo; + + public SlicingConfig() { + mUrspRules = new ArrayList(); + mSliceInfo = new ArrayList(); + } + + /** @hide */ + public SlicingConfig(android.hardware.radio.V1_6.SlicingConfig sc) { + this(sc.urspRules, sc.sliceInfo); + } + + /** @hide */ + public SlicingConfig(List urspRules, + List sliceInfo) { + mUrspRules = new ArrayList(); + for (android.hardware.radio.V1_6.UrspRule ur : urspRules) { + mUrspRules.add(new UrspRule(ur.precedence, ur.trafficDescriptors, + ur.routeSelectionDescriptor)); + } + mSliceInfo = new ArrayList(); + for (android.hardware.radio.V1_6.SliceInfo si : sliceInfo) { + mSliceInfo.add(sliceInfoBuilder(si)); + } + } + + private NetworkSliceInfo sliceInfoBuilder(android.hardware.radio.V1_6.SliceInfo si) { + NetworkSliceInfo.Builder builder = new NetworkSliceInfo.Builder() + .setSliceServiceType(si.sst) + .setMappedHplmnSliceServiceType(si.mappedHplmnSst); + if (si.sliceDifferentiator != NetworkSliceInfo.SLICE_DIFFERENTIATOR_NO_SLICE) { + builder + .setSliceDifferentiator(si.sliceDifferentiator) + .setMappedHplmnSliceDifferentiator(si.mappedHplmnSD); + } + return builder.build(); + } + + /** @hide */ + public SlicingConfig(Parcel p) { + mUrspRules = p.createTypedArrayList(UrspRule.CREATOR); + mSliceInfo = p.createTypedArrayList(NetworkSliceInfo.CREATOR); + } + + /** + * This list contains the current URSP rules. Empty list represents that no rules are + * configured. + * @return the current URSP rules for this slicing configuration. + */ + public @NonNull List getUrspRules() { + return mUrspRules; + } + + /** + * @return the list of all slices for this slicing configuration. + */ + public @NonNull List getSliceInfo() { + return mSliceInfo; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeTypedList(mUrspRules, flags); + dest.writeTypedList(mSliceInfo, flags); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public SlicingConfig createFromParcel(Parcel source) { + return new SlicingConfig(source); + } + + @Override + public SlicingConfig[] newArray(int size) { + return new SlicingConfig[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public boolean equals(@Nullable Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SlicingConfig that = (SlicingConfig) o; + return mUrspRules.size() == that.mUrspRules.size() + && mUrspRules.containsAll(that.mUrspRules) + && mSliceInfo.size() == that.mSliceInfo.size() + && mSliceInfo.containsAll(that.mSliceInfo); + } + + @Override + public int hashCode() { + return Objects.hash(mUrspRules, mSliceInfo); + } + + @Override + public String toString() { + return "{.urspRules = " + mUrspRules + ", .sliceInfo = " + mSliceInfo + "}"; + } +} diff --git a/telephony/java/android/telephony/data/TrafficDescriptor.java b/telephony/java/android/telephony/data/TrafficDescriptor.java index 480379d641b60..d813bc58fe6f4 100644 --- a/telephony/java/android/telephony/data/TrafficDescriptor.java +++ b/telephony/java/android/telephony/data/TrafficDescriptor.java @@ -18,20 +18,17 @@ package android.telephony.data; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import java.util.Objects; /** - * A traffic descriptor, as defined in 3GPP TS 24.526 Section 5.2. It is used for URSP traffic - * matching as described in 3GPP TS 24.526 Section 4.2.2. It includes an optional DNN, which, - * if present, must be used for traffic matching; it does not specify the end point to be used for - * the data call. - * @hide + * A traffic descriptor, as defined in 3GPP TS 24.526 Section 5.2. It is used for UE Route Selection + * Policy(URSP) traffic matching as described in 3GPP TS 24.526 Section 4.2.2. It includes an + * optional Data Network Name(DNN), which, if present, must be used for traffic matching; it does + * not specify the end point to be used for the data call. */ -@SystemApi public final class TrafficDescriptor implements Parcelable { private final String mDnn; private final String mOsAppId; @@ -45,8 +42,10 @@ public final class TrafficDescriptor implements Parcelable { * Create a traffic descriptor, as defined in 3GPP TS 24.526 Section 5.2 * @param dnn optional DNN, which must be used for traffic matching, if present * @param osAppId OsId + osAppId of the traffic descriptor + * + * @hide */ - public TrafficDescriptor(@Nullable String dnn, @Nullable String osAppId) { + public TrafficDescriptor(String dnn, String osAppId) { mDnn = dnn; mOsAppId = osAppId; } @@ -55,12 +54,13 @@ public final class TrafficDescriptor implements Parcelable { * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003. * @return the DNN of this traffic descriptor. */ - public @Nullable String getDnn() { + public @Nullable String getDataNetworkName() { return mDnn; } /** - * OsAppId represents the OsId + OsAppId as defined in 3GPP TS 24.526 Section 5.2. + * OsAppId is the app id as defined in 3GPP TS 24.526 Section 5.2, and it identifies a traffic + * category. * @return the OS App ID of this traffic descriptor. */ public @Nullable String getOsAppId() { @@ -108,4 +108,65 @@ public final class TrafficDescriptor implements Parcelable { public int hashCode() { return Objects.hash(mDnn, mOsAppId); } + + /** + * Provides a convenient way to set the fields of a {@link TrafficDescriptor} when creating a + * new instance. + * + *

The example below shows how you might create a new {@code TrafficDescriptor}: + * + *


+     *
+     * TrafficDescriptor response = new TrafficDescriptor.Builder()
+     *     .setDnn("")
+     *     .build();
+     * 
+ */ + public static final class Builder { + private String mDnn = null; + private String mOsAppId = null; + + /** + * Default constructor for Builder. + */ + public Builder() { + } + + /** + * Set the Data Network Name(DNN). + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setDataNetworkName(@NonNull String dnn) { + this.mDnn = dnn; + return this; + } + + /** + * Set the OS App ID. + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setOsAppId(@NonNull String osAppId) { + this.mOsAppId = osAppId; + return this; + } + + /** + * Build the {@link TrafficDescriptor}. + * + * @throws IllegalArgumentException if DNN and OS App ID are null. + * + * @return the {@link TrafficDescriptor} object. + */ + @NonNull + public TrafficDescriptor build() { + if (this.mDnn == null && this.mOsAppId == null) { + throw new IllegalArgumentException("DNN and OS App ID are null"); + } + return new TrafficDescriptor(this.mDnn, this.mOsAppId); + } + } } diff --git a/telephony/java/android/telephony/data/UrspRule.aidl b/telephony/java/android/telephony/data/UrspRule.aidl new file mode 100644 index 0000000000000..2bed583c750e0 --- /dev/null +++ b/telephony/java/android/telephony/data/UrspRule.aidl @@ -0,0 +1,19 @@ +/* + * Copyright 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 UrspRule; diff --git a/telephony/java/android/telephony/data/UrspRule.java b/telephony/java/android/telephony/data/UrspRule.java new file mode 100644 index 0000000000000..e2c47fd86b4bf --- /dev/null +++ b/telephony/java/android/telephony/data/UrspRule.java @@ -0,0 +1,178 @@ +/** + * Copyright 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.IntRange; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.hardware.radio.V1_6.OptionalDnn; +import android.hardware.radio.V1_6.OptionalOsAppId; +import android.os.Parcel; +import android.os.Parcelable; + + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Represents a single URSP rule as defined in 3GPP TS 24.526. URSP stands for UE Route Selection + * Policy. In 5G, network can provide URSP information to devices which provides information on + * what connection parameters should be used for what traffic. + */ +public final class UrspRule implements Parcelable { + /** + * The min acceptable value for the precedence of a URSP rule. + * @hide + */ + public static final int MIN_URSP_PRECEDENCE = 0; + + /** + * The max acceptable value for the precedence of a URSP rule. + * @hide + */ + public static final int MAX_URSP_PRECEDENCE = 255; + + @IntRange(from = MIN_URSP_PRECEDENCE, to = MAX_URSP_PRECEDENCE) + private final int mPrecedence; + private final List mTrafficDescriptors; + private final List mRouteSelectionDescriptor; + + UrspRule(android.hardware.radio.V1_6.UrspRule ur) { + this(ur.precedence, ur.trafficDescriptors, ur.routeSelectionDescriptor); + } + + /** @hide */ + public UrspRule(int precedence, + List trafficDescriptors, + List routeSelectionDescriptor) { + mPrecedence = precedence; + mTrafficDescriptors = new ArrayList(); + for (android.hardware.radio.V1_6.TrafficDescriptor td : trafficDescriptors) { + mTrafficDescriptors.add(convertToTrafficDescriptor(td)); + } + mRouteSelectionDescriptor = new ArrayList(); + for (android.hardware.radio.V1_6.RouteSelectionDescriptor rsd : routeSelectionDescriptor) { + mRouteSelectionDescriptor.add(new RouteSelectionDescriptor(rsd)); + } + } + + /** Convert an ArrayList of Bytes to an exactly-sized primitive array */ + private byte[] arrayListToPrimitiveArray(ArrayList bytes) { + byte[] ret = new byte[bytes.size()]; + for (int i = 0; i < ret.length; i++) { + ret[i] = bytes.get(i); + } + return ret; + } + + private TrafficDescriptor convertToTrafficDescriptor( + android.hardware.radio.V1_6.TrafficDescriptor td) { + String dnn = td.dnn.getDiscriminator() == OptionalDnn.hidl_discriminator.noinit + ? null : td.dnn.value(); + String osAppId = td.osAppId.getDiscriminator() == OptionalOsAppId.hidl_discriminator.noinit + ? null : new String(arrayListToPrimitiveArray(td.osAppId.value().osAppId)); + TrafficDescriptor.Builder builder = new TrafficDescriptor.Builder(); + if (dnn != null) { + builder.setDataNetworkName(dnn); + } + if (osAppId != null) { + builder.setOsAppId(osAppId); + } + return builder.build(); + } + + private UrspRule(Parcel p) { + mPrecedence = p.readInt(); + mTrafficDescriptors = p.createTypedArrayList(TrafficDescriptor.CREATOR); + mRouteSelectionDescriptor = p.createTypedArrayList(RouteSelectionDescriptor.CREATOR); + } + + /** + * Precedence value in the range of 0 to 255. Higher value has lower precedence. + * @return the precedence value for this URSP rule. + */ + @IntRange(from = MIN_URSP_PRECEDENCE, to = MAX_URSP_PRECEDENCE) + public int getPrecedence() { + return mPrecedence; + } + + /** + * These traffic descriptors are used as a matcher for network requests. + * @return the traffic descriptors which are associated to this URSP rule. + */ + public @NonNull List getTrafficDescriptors() { + return mTrafficDescriptors; + } + + /** + * List of routes (connection parameters) that must be used by the device for requests matching + * a traffic descriptor. + * @return the route selection descriptors which are associated to this URSP rule. + */ + public @NonNull List getRouteSelectionDescriptor() { + return mRouteSelectionDescriptor; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mPrecedence); + dest.writeTypedList(mTrafficDescriptors, flags); + dest.writeTypedList(mRouteSelectionDescriptor, flags); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public UrspRule createFromParcel(Parcel source) { + return new UrspRule(source); + } + + @Override + public UrspRule[] newArray(int size) { + return new UrspRule[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public boolean equals(@Nullable Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UrspRule that = (UrspRule) o; + return mPrecedence == that.mPrecedence + && mTrafficDescriptors.size() == that.mTrafficDescriptors.size() + && mTrafficDescriptors.containsAll(that.mTrafficDescriptors) + && mRouteSelectionDescriptor.size() == that.mRouteSelectionDescriptor.size() + && mRouteSelectionDescriptor.containsAll(that.mRouteSelectionDescriptor); + } + + @Override + public int hashCode() { + return Objects.hash(mPrecedence, mTrafficDescriptors, mRouteSelectionDescriptor); + } + + @Override + public String toString() { + return "{.precedence = " + mPrecedence + ", .trafficDescriptors = " + mTrafficDescriptors + + ", .routeSelectionDescriptor = " + mRouteSelectionDescriptor + "}"; + } +} diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index ae5f997360cd2..d812b4641748c 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2447,4 +2447,10 @@ interface ITelephony { * Gets the current phone capability. */ PhoneCapability getPhoneCapability(); + + /** + * Request to get the current slicing configuration including URSP rules and + * NSSAIs (configured, allowed and rejected). + */ + void getSlicingConfig(in ResultReceiver callback); } diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 822fc44146d66..fe8e6715fe353 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -527,6 +527,7 @@ public interface RILConstants { int RIL_REQUEST_SET_DATA_THROTTLING = 221; int RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP = 222; int RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP = 223; + int RIL_REQUEST_GET_SLICING_CONFIG = 224; /* Responses begin */ int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;