Loading core/api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -44755,10 +44755,16 @@ package android.telephony { method public int getLastCauseCode(); method @Nullable public android.net.LinkProperties getLinkProperties(); method public int getNetworkType(); method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public int getNetworkValidationStatus(); method public int getState(); method public int getTransportType(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR; field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_FAILURE = 4; // 0x4 field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_IN_PROGRESS = 2; // 0x2 field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1; // 0x1 field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_SUCCESS = 3; // 0x3 field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_UNSUPPORTED = 0; // 0x0 } public final class RadioAccessSpecifier implements android.os.Parcelable { core/api/system-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -14837,6 +14837,7 @@ package android.telephony.data { method @Deprecated public int getMtu(); method public int getMtuV4(); method public int getMtuV6(); method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public int getNetworkValidationStatus(); method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses(); method public int getPduSessionId(); method public int getProtocolType(); Loading Loading @@ -14873,6 +14874,7 @@ package android.telephony.data { method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setMtu(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV4(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int); method @FlaggedApi("com.android.internal.telephony.flags.network_validation") @NonNull public android.telephony.data.DataCallResponse.Builder setNetworkValidationStatus(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>); method @NonNull public android.telephony.data.DataCallResponse.Builder setPduSessionId(@IntRange(from=android.telephony.data.DataCallResponse.PDU_SESSION_ID_NOT_SET, to=15) int); method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int); Loading Loading @@ -14952,6 +14954,7 @@ package android.telephony.data { method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>); method public final void notifyDataProfileUnthrottled(@NonNull android.telephony.data.DataProfile); method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback); method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public void requestValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @NonNull android.telephony.data.DataServiceCallback); method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @NonNull android.telephony.data.DataServiceCallback); method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @NonNull android.telephony.data.DataServiceCallback); Loading Loading @@ -15013,6 +15016,7 @@ package android.telephony.data { method public final int getSlotIndex(); method public void reportEmergencyDataNetworkPreferredTransportChanged(int); method public void reportThrottleStatusChanged(@NonNull java.util.List<android.telephony.data.ThrottleStatus>); method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public void requestNetworkValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List<java.lang.Integer>); } telephony/java/android/telephony/PreciseDataConnectionState.java +113 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.telephony; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; Loading @@ -37,8 +39,11 @@ import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; import android.telephony.data.Qos; import com.android.internal.telephony.flags.Flags; import com.android.internal.telephony.util.TelephonyUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; Loading Loading @@ -66,6 +71,53 @@ public final class PreciseDataConnectionState implements Parcelable { private final LinkProperties mLinkProperties; private final ApnSetting mApnSetting; private final Qos mDefaultQos; private final @NetworkValidationStatus int mNetworkValidationStatus; /** @hide */ @IntDef(prefix = "NETWORK_VALIDATION_", value = { NETWORK_VALIDATION_UNSUPPORTED, NETWORK_VALIDATION_NOT_REQUESTED, NETWORK_VALIDATION_IN_PROGRESS, NETWORK_VALIDATION_SUCCESS, NETWORK_VALIDATION_FAILURE, }) @Retention(RetentionPolicy.SOURCE) public @interface NetworkValidationStatus {} /** * Unsupported. The unsupported state is used when the data network cannot support the network * validation function for the current data connection state. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_UNSUPPORTED = 0; /** * Not Requested. The not requested status is used when the data network supports the network * validation function, but no network validation is being performed yet. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1; /** * In progress. The in progress state is used when the network validation process for the data * network is in progress. This state is followed by either success or failure. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_IN_PROGRESS = 2; /** * Success. The Success status is used when network validation has been completed for the data * network and the result is successful. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_SUCCESS = 3; /** * Failure. The Failure status is used when network validation has been completed for the data * network and the result is failure. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_FAILURE = 4; /** * Constructor Loading @@ -87,7 +139,7 @@ public final class PreciseDataConnectionState implements Parcelable { .setApnTypeBitmask(apnTypes) .setApnName(apn) .setEntryName(apn) .build(), null); .build(), null, NETWORK_VALIDATION_UNSUPPORTED); } Loading @@ -109,7 +161,8 @@ public final class PreciseDataConnectionState implements Parcelable { private PreciseDataConnectionState(@TransportType int transportType, int id, @DataState int state, @NetworkType int networkType, @Nullable LinkProperties linkProperties, @DataFailureCause int failCause, @Nullable ApnSetting apnSetting, @Nullable Qos defaultQos) { @Nullable ApnSetting apnSetting, @Nullable Qos defaultQos, @NetworkValidationStatus int networkValidationStatus) { mTransportType = transportType; mId = id; mState = state; Loading @@ -118,6 +171,7 @@ public final class PreciseDataConnectionState implements Parcelable { mFailCause = failCause; mApnSetting = apnSetting; mDefaultQos = defaultQos; mNetworkValidationStatus = networkValidationStatus; } /** Loading @@ -140,6 +194,7 @@ public final class PreciseDataConnectionState implements Parcelable { mDefaultQos = in.readParcelable( Qos.class.getClassLoader(), android.telephony.data.Qos.class); mNetworkValidationStatus = in.readInt(); } /** Loading Loading @@ -289,6 +344,16 @@ public final class PreciseDataConnectionState implements Parcelable { return mDefaultQos; } /** * Returns the network validation state. * * @return the network validation status of the data call */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @NetworkValidationStatus int getNetworkValidationStatus() { return mNetworkValidationStatus; } @Override public int describeContents() { return 0; Loading @@ -304,6 +369,7 @@ public final class PreciseDataConnectionState implements Parcelable { out.writeInt(mFailCause); out.writeParcelable(mApnSetting, flags); out.writeParcelable(mDefaultQos, flags); out.writeInt(mNetworkValidationStatus); } public static final @NonNull Parcelable.Creator<PreciseDataConnectionState> CREATOR Loading @@ -321,7 +387,7 @@ public final class PreciseDataConnectionState implements Parcelable { @Override public int hashCode() { return Objects.hash(mTransportType, mId, mState, mNetworkType, mFailCause, mLinkProperties, mApnSetting, mDefaultQos); mLinkProperties, mApnSetting, mDefaultQos, mNetworkValidationStatus); } Loading @@ -337,7 +403,8 @@ public final class PreciseDataConnectionState implements Parcelable { && mFailCause == that.mFailCause && Objects.equals(mLinkProperties, that.mLinkProperties) && Objects.equals(mApnSetting, that.mApnSetting) && Objects.equals(mDefaultQos, that.mDefaultQos); && Objects.equals(mDefaultQos, that.mDefaultQos) && mNetworkValidationStatus == that.mNetworkValidationStatus; } @NonNull Loading @@ -354,10 +421,33 @@ public final class PreciseDataConnectionState implements Parcelable { sb.append(", link properties: " + mLinkProperties); sb.append(", default QoS: " + mDefaultQos); sb.append(", fail cause: " + DataFailCause.toString(mFailCause)); sb.append(", network validation status: " + networkValidationStatusToString(mNetworkValidationStatus)); return sb.toString(); } /** * Convert a network validation status to string. * * @param networkValidationStatus network validation status. * @return string of validation status. * * @hide */ @NonNull public static String networkValidationStatusToString( @NetworkValidationStatus int networkValidationStatus) { switch (networkValidationStatus) { case NETWORK_VALIDATION_UNSUPPORTED: return "unsupported"; case NETWORK_VALIDATION_NOT_REQUESTED: return "not requested"; case NETWORK_VALIDATION_IN_PROGRESS: return "in progress"; case NETWORK_VALIDATION_SUCCESS: return "success"; case NETWORK_VALIDATION_FAILURE: return "failure"; default: return Integer.toString(networkValidationStatus); } } /** * {@link PreciseDataConnectionState} builder * Loading Loading @@ -394,6 +484,10 @@ public final class PreciseDataConnectionState implements Parcelable { /** The Default QoS for this EPS/5GS bearer or null otherwise */ private @Nullable Qos mDefaultQos; /** The network validation status for the data connection. */ private @NetworkValidationStatus int mNetworkValidationStatus = NETWORK_VALIDATION_UNSUPPORTED; /** * Set the transport type of the data connection. * Loading Loading @@ -485,6 +579,19 @@ public final class PreciseDataConnectionState implements Parcelable { return this; } /** * Set the network validation state for the data connection. * * @param networkValidationStatus the network validation status of the data call * @return The builder */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @NonNull Builder setNetworkValidationStatus( @NetworkValidationStatus int networkValidationStatus) { mNetworkValidationStatus = networkValidationStatus; return this; } /** * Build the {@link PreciseDataConnectionState} instance. * Loading @@ -492,7 +599,8 @@ public final class PreciseDataConnectionState implements Parcelable { */ public PreciseDataConnectionState build() { return new PreciseDataConnectionState(mTransportType, mId, mState, mNetworkType, mLinkProperties, mFailCause, mApnSetting, mDefaultQos); mLinkProperties, mFailCause, mApnSetting, mDefaultQos, mNetworkValidationStatus); } } } telephony/java/android/telephony/data/DataCallResponse.java +46 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.telephony.data; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; Loading @@ -27,9 +28,11 @@ import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.DataFailureCause; import android.telephony.DataFailCause; import android.telephony.PreciseDataConnectionState; import android.telephony.data.ApnSetting.ProtocolType; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.flags.Flags; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; Loading Loading @@ -123,7 +126,6 @@ public final class DataCallResponse implements Parcelable { * Indicates that the pdu session id is not set. */ public static final int PDU_SESSION_ID_NOT_SET = 0; private final @DataFailureCause int mCause; private final long mSuggestedRetryTime; private final int mId; Loading @@ -143,6 +145,7 @@ public final class DataCallResponse implements Parcelable { private final List<QosBearerSession> mQosBearerSessions; private final NetworkSliceInfo mSliceInfo; private final List<TrafficDescriptor> mTrafficDescriptors; private final @PreciseDataConnectionState.NetworkValidationStatus int mNetworkValidationStatus; /** * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error. Loading Loading @@ -185,7 +188,8 @@ public final class DataCallResponse implements Parcelable { HANDOVER_FAILURE_MODE_LEGACY, PDU_SESSION_ID_NOT_SET, null /* defaultQos */, Collections.emptyList() /* qosBearerSessions */, null /* sliceInfo */, Collections.emptyList() /* trafficDescriptors */); Collections.emptyList(), /* trafficDescriptors */ PreciseDataConnectionState.NETWORK_VALIDATION_UNSUPPORTED); } private DataCallResponse(@DataFailureCause int cause, long suggestedRetryTime, int id, Loading @@ -196,7 +200,8 @@ public final class DataCallResponse implements Parcelable { @HandoverFailureMode int handoverFailureMode, int pduSessionId, @Nullable Qos defaultQos, @NonNull List<QosBearerSession> qosBearerSessions, @Nullable NetworkSliceInfo sliceInfo, @NonNull List<TrafficDescriptor> trafficDescriptors) { @NonNull List<TrafficDescriptor> trafficDescriptors, @PreciseDataConnectionState.NetworkValidationStatus int networkValidationStatus) { mCause = cause; mSuggestedRetryTime = suggestedRetryTime; mId = id; Loading @@ -216,6 +221,7 @@ public final class DataCallResponse implements Parcelable { mQosBearerSessions = new ArrayList<>(qosBearerSessions); mSliceInfo = sliceInfo; mTrafficDescriptors = new ArrayList<>(trafficDescriptors); mNetworkValidationStatus = networkValidationStatus; if (mLinkStatus == LINK_STATUS_ACTIVE || mLinkStatus == LINK_STATUS_DORMANT) { Loading Loading @@ -270,6 +276,7 @@ public final class DataCallResponse implements Parcelable { source.readList(mTrafficDescriptors, TrafficDescriptor.class.getClassLoader(), android.telephony.data.TrafficDescriptor.class); mNetworkValidationStatus = source.readInt(); } /** Loading Loading @@ -442,6 +449,17 @@ public final class DataCallResponse implements Parcelable { return Collections.unmodifiableList(mTrafficDescriptors); } /** * Return the network validation status that was initiated by {@link * DataService.DataServiceProvider#requestValidation} * * @return The network validation status of data connection. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @PreciseDataConnectionState.NetworkValidationStatus int getNetworkValidationStatus() { return mNetworkValidationStatus; } @NonNull @Override public String toString() { Loading @@ -466,6 +484,8 @@ public final class DataCallResponse implements Parcelable { .append(" qosBearerSessions=").append(mQosBearerSessions) .append(" sliceInfo=").append(mSliceInfo) .append(" trafficDescriptors=").append(mTrafficDescriptors) .append(" networkValidationStatus=").append(PreciseDataConnectionState .networkValidationStatusToString(mNetworkValidationStatus)) .append("}"); return sb.toString(); } Loading Loading @@ -504,7 +524,8 @@ public final class DataCallResponse implements Parcelable { && mQosBearerSessions.containsAll(other.mQosBearerSessions) // non-null && Objects.equals(mSliceInfo, other.mSliceInfo) && mTrafficDescriptors.size() == other.mTrafficDescriptors.size() // non-null && mTrafficDescriptors.containsAll(other.mTrafficDescriptors); // non-null && mTrafficDescriptors.containsAll(other.mTrafficDescriptors) // non-null && mNetworkValidationStatus == other.mNetworkValidationStatus; } @Override Loading @@ -513,7 +534,7 @@ public final class DataCallResponse implements Parcelable { mInterfaceName, Set.copyOf(mAddresses), Set.copyOf(mDnsAddresses), Set.copyOf(mGatewayAddresses), Set.copyOf(mPcscfAddresses), mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, mDefaultQos, Set.copyOf(mQosBearerSessions), mSliceInfo, Set.copyOf(mTrafficDescriptors)); mSliceInfo, Set.copyOf(mTrafficDescriptors), mNetworkValidationStatus); } @Override Loading Loading @@ -542,6 +563,7 @@ public final class DataCallResponse implements Parcelable { dest.writeList(mQosBearerSessions); dest.writeParcelable(mSliceInfo, flags); dest.writeList(mTrafficDescriptors); dest.writeInt(mNetworkValidationStatus); } public static final @android.annotation.NonNull Parcelable.Creator<DataCallResponse> CREATOR = Loading Loading @@ -629,6 +651,9 @@ public final class DataCallResponse implements Parcelable { private List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>(); private @PreciseDataConnectionState.NetworkValidationStatus int mNetworkValidationStatus = PreciseDataConnectionState.NETWORK_VALIDATION_UNSUPPORTED; /** * Default constructor for Builder. */ Loading Loading @@ -904,6 +929,20 @@ public final class DataCallResponse implements Parcelable { return this; } /** * Set the network validation status that corresponds to the state of the network validation * request started by {@link DataService.DataServiceProvider#requestValidation} * * @param status The network validation status. * @return The same instance of the builder. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @NonNull Builder setNetworkValidationStatus( @PreciseDataConnectionState.NetworkValidationStatus int status) { mNetworkValidationStatus = status; return this; } /** * Build the DataCallResponse. * Loading @@ -913,7 +952,8 @@ public final class DataCallResponse implements Parcelable { return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, mDefaultQos, mQosBearerSessions, mSliceInfo, mTrafficDescriptors); mDefaultQos, mQosBearerSessions, mSliceInfo, mTrafficDescriptors, mNetworkValidationStatus); } } } telephony/java/android/telephony/data/DataService.java +81 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.telephony.data; import android.annotation.CallbackExecutor; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; Loading @@ -26,6 +28,7 @@ import android.app.Service; import android.content.Intent; import android.net.LinkProperties; import android.os.Handler; import android.os.HandlerExecutor; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; Loading @@ -36,6 +39,9 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IIntegerConsumer; import com.android.internal.telephony.flags.Flags; import com.android.internal.util.FunctionalUtils; import com.android.telephony.Rlog; import java.lang.annotation.Retention; Loading @@ -44,6 +50,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.Consumer; /** * Base class of data service. Services that extend DataService must register the service in Loading Loading @@ -113,11 +121,14 @@ public abstract class DataService extends Service { private static final int DATA_SERVICE_REQUEST_REGISTER_APN_UNTHROTTLED = 14; private static final int DATA_SERVICE_REQUEST_UNREGISTER_APN_UNTHROTTLED = 15; private static final int DATA_SERVICE_INDICATION_APN_UNTHROTTLED = 16; private static final int DATA_SERVICE_REQUEST_VALIDATION = 17; private final HandlerThread mHandlerThread; private final DataServiceHandler mHandler; private final Executor mHandlerExecutor; private final SparseArray<DataServiceProvider> mServiceMap = new SparseArray<>(); /** @hide */ Loading Loading @@ -379,6 +390,43 @@ public abstract class DataService extends Service { } } /** * Request validation check to see if the network is working properly for a given data call. * * <p>This request is completed immediately after submitting the request to the data service * provider and receiving {@link DataServiceCallback.ResultCode}, and progress status or * validation results are notified through {@link * DataCallResponse#getNetworkValidationStatus}. * * <p> If the network validation request is submitted successfully, {@link * DataServiceCallback#RESULT_SUCCESS} is passed to {@code resultCodeCallback}. If the * network validation feature is not supported by the data service provider itself, {@link * DataServiceCallback#RESULT_ERROR_UNSUPPORTED} is passed to {@code resultCodeCallback}. * See {@link DataServiceCallback.ResultCode} for the type of response that indicates * whether the request was successfully submitted or had an error. * * <p>In response to this network validation request, providers can validate the data call * in their own way. For example, in IWLAN, the DPD (Dead Peer Detection) can be used as a * tool to check whether a data call is alive. * * @param cid The identifier of the data call which is provided in {@link DataCallResponse} * @param executor The callback executor for the response. * @param resultCodeCallback Listener for the {@link DataServiceCallback.ResultCode} that * request validation to the DataService and checks if the request has been submitted. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public void requestValidation(int cid, @NonNull @CallbackExecutor Executor executor, @NonNull @DataServiceCallback.ResultCode Consumer<Integer> resultCodeCallback) { Objects.requireNonNull(executor, "executor cannot be null"); Objects.requireNonNull(resultCodeCallback, "resultCodeCallback cannot be null"); Log.d(TAG, "requestValidation: " + cid); // The default implementation is to return unsupported. executor.execute(() -> resultCodeCallback .accept(DataServiceCallback.RESULT_ERROR_UNSUPPORTED)); } /** * Notify the system that current data call list changed. Data service must invoke this Loading Loading @@ -537,6 +585,17 @@ public abstract class DataService extends Service { } } private static final class ValidationRequest { public final int cid; public final Executor executor; public final IIntegerConsumer callback; ValidationRequest(int cid, Executor executor, IIntegerConsumer callback) { this.cid = cid; this.executor = executor; this.callback = callback; } } private class DataServiceHandler extends Handler { DataServiceHandler(Looper looper) { Loading Loading @@ -679,6 +738,15 @@ public abstract class DataService extends Service { loge("Failed to call onApnUnthrottled. " + e); } break; case DATA_SERVICE_REQUEST_VALIDATION: if (serviceProvider == null) break; ValidationRequest validationRequest = (ValidationRequest) message.obj; serviceProvider.requestValidation( validationRequest.cid, validationRequest.executor, FunctionalUtils .ignoreRemoteException(validationRequest.callback::accept)); break; } } } Loading @@ -691,6 +759,7 @@ public abstract class DataService extends Service { mHandlerThread.start(); mHandler = new DataServiceHandler(mHandlerThread.getLooper()); mHandlerExecutor = new HandlerExecutor(mHandler); log("Data service created"); } Loading Loading @@ -853,6 +922,18 @@ public abstract class DataService extends Service { mHandler.obtainMessage(DATA_SERVICE_REQUEST_UNREGISTER_APN_UNTHROTTLED, slotIndex, 0, callback).sendToTarget(); } @Override public void requestValidation(int slotIndex, int cid, IIntegerConsumer resultCodeCallback) { if (resultCodeCallback == null) { loge("requestValidation: resultCodeCallback is null"); return; } ValidationRequest validationRequest = new ValidationRequest(cid, mHandlerExecutor, resultCodeCallback); mHandler.obtainMessage(DATA_SERVICE_REQUEST_VALIDATION, slotIndex, 0, validationRequest).sendToTarget(); } } private void log(String s) { Loading Loading
core/api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -44755,10 +44755,16 @@ package android.telephony { method public int getLastCauseCode(); method @Nullable public android.net.LinkProperties getLinkProperties(); method public int getNetworkType(); method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public int getNetworkValidationStatus(); method public int getState(); method public int getTransportType(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR; field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_FAILURE = 4; // 0x4 field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_IN_PROGRESS = 2; // 0x2 field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1; // 0x1 field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_SUCCESS = 3; // 0x3 field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_UNSUPPORTED = 0; // 0x0 } public final class RadioAccessSpecifier implements android.os.Parcelable {
core/api/system-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -14837,6 +14837,7 @@ package android.telephony.data { method @Deprecated public int getMtu(); method public int getMtuV4(); method public int getMtuV6(); method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public int getNetworkValidationStatus(); method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses(); method public int getPduSessionId(); method public int getProtocolType(); Loading Loading @@ -14873,6 +14874,7 @@ package android.telephony.data { method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setMtu(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV4(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int); method @FlaggedApi("com.android.internal.telephony.flags.network_validation") @NonNull public android.telephony.data.DataCallResponse.Builder setNetworkValidationStatus(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>); method @NonNull public android.telephony.data.DataCallResponse.Builder setPduSessionId(@IntRange(from=android.telephony.data.DataCallResponse.PDU_SESSION_ID_NOT_SET, to=15) int); method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int); Loading Loading @@ -14952,6 +14954,7 @@ package android.telephony.data { method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>); method public final void notifyDataProfileUnthrottled(@NonNull android.telephony.data.DataProfile); method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback); method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public void requestValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @NonNull android.telephony.data.DataServiceCallback); method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @NonNull android.telephony.data.DataServiceCallback); method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @NonNull android.telephony.data.DataServiceCallback); Loading Loading @@ -15013,6 +15016,7 @@ package android.telephony.data { method public final int getSlotIndex(); method public void reportEmergencyDataNetworkPreferredTransportChanged(int); method public void reportThrottleStatusChanged(@NonNull java.util.List<android.telephony.data.ThrottleStatus>); method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public void requestNetworkValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List<java.lang.Integer>); }
telephony/java/android/telephony/PreciseDataConnectionState.java +113 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.telephony; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; Loading @@ -37,8 +39,11 @@ import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; import android.telephony.data.Qos; import com.android.internal.telephony.flags.Flags; import com.android.internal.telephony.util.TelephonyUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; Loading Loading @@ -66,6 +71,53 @@ public final class PreciseDataConnectionState implements Parcelable { private final LinkProperties mLinkProperties; private final ApnSetting mApnSetting; private final Qos mDefaultQos; private final @NetworkValidationStatus int mNetworkValidationStatus; /** @hide */ @IntDef(prefix = "NETWORK_VALIDATION_", value = { NETWORK_VALIDATION_UNSUPPORTED, NETWORK_VALIDATION_NOT_REQUESTED, NETWORK_VALIDATION_IN_PROGRESS, NETWORK_VALIDATION_SUCCESS, NETWORK_VALIDATION_FAILURE, }) @Retention(RetentionPolicy.SOURCE) public @interface NetworkValidationStatus {} /** * Unsupported. The unsupported state is used when the data network cannot support the network * validation function for the current data connection state. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_UNSUPPORTED = 0; /** * Not Requested. The not requested status is used when the data network supports the network * validation function, but no network validation is being performed yet. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1; /** * In progress. The in progress state is used when the network validation process for the data * network is in progress. This state is followed by either success or failure. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_IN_PROGRESS = 2; /** * Success. The Success status is used when network validation has been completed for the data * network and the result is successful. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_SUCCESS = 3; /** * Failure. The Failure status is used when network validation has been completed for the data * network and the result is failure. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_FAILURE = 4; /** * Constructor Loading @@ -87,7 +139,7 @@ public final class PreciseDataConnectionState implements Parcelable { .setApnTypeBitmask(apnTypes) .setApnName(apn) .setEntryName(apn) .build(), null); .build(), null, NETWORK_VALIDATION_UNSUPPORTED); } Loading @@ -109,7 +161,8 @@ public final class PreciseDataConnectionState implements Parcelable { private PreciseDataConnectionState(@TransportType int transportType, int id, @DataState int state, @NetworkType int networkType, @Nullable LinkProperties linkProperties, @DataFailureCause int failCause, @Nullable ApnSetting apnSetting, @Nullable Qos defaultQos) { @Nullable ApnSetting apnSetting, @Nullable Qos defaultQos, @NetworkValidationStatus int networkValidationStatus) { mTransportType = transportType; mId = id; mState = state; Loading @@ -118,6 +171,7 @@ public final class PreciseDataConnectionState implements Parcelable { mFailCause = failCause; mApnSetting = apnSetting; mDefaultQos = defaultQos; mNetworkValidationStatus = networkValidationStatus; } /** Loading @@ -140,6 +194,7 @@ public final class PreciseDataConnectionState implements Parcelable { mDefaultQos = in.readParcelable( Qos.class.getClassLoader(), android.telephony.data.Qos.class); mNetworkValidationStatus = in.readInt(); } /** Loading Loading @@ -289,6 +344,16 @@ public final class PreciseDataConnectionState implements Parcelable { return mDefaultQos; } /** * Returns the network validation state. * * @return the network validation status of the data call */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @NetworkValidationStatus int getNetworkValidationStatus() { return mNetworkValidationStatus; } @Override public int describeContents() { return 0; Loading @@ -304,6 +369,7 @@ public final class PreciseDataConnectionState implements Parcelable { out.writeInt(mFailCause); out.writeParcelable(mApnSetting, flags); out.writeParcelable(mDefaultQos, flags); out.writeInt(mNetworkValidationStatus); } public static final @NonNull Parcelable.Creator<PreciseDataConnectionState> CREATOR Loading @@ -321,7 +387,7 @@ public final class PreciseDataConnectionState implements Parcelable { @Override public int hashCode() { return Objects.hash(mTransportType, mId, mState, mNetworkType, mFailCause, mLinkProperties, mApnSetting, mDefaultQos); mLinkProperties, mApnSetting, mDefaultQos, mNetworkValidationStatus); } Loading @@ -337,7 +403,8 @@ public final class PreciseDataConnectionState implements Parcelable { && mFailCause == that.mFailCause && Objects.equals(mLinkProperties, that.mLinkProperties) && Objects.equals(mApnSetting, that.mApnSetting) && Objects.equals(mDefaultQos, that.mDefaultQos); && Objects.equals(mDefaultQos, that.mDefaultQos) && mNetworkValidationStatus == that.mNetworkValidationStatus; } @NonNull Loading @@ -354,10 +421,33 @@ public final class PreciseDataConnectionState implements Parcelable { sb.append(", link properties: " + mLinkProperties); sb.append(", default QoS: " + mDefaultQos); sb.append(", fail cause: " + DataFailCause.toString(mFailCause)); sb.append(", network validation status: " + networkValidationStatusToString(mNetworkValidationStatus)); return sb.toString(); } /** * Convert a network validation status to string. * * @param networkValidationStatus network validation status. * @return string of validation status. * * @hide */ @NonNull public static String networkValidationStatusToString( @NetworkValidationStatus int networkValidationStatus) { switch (networkValidationStatus) { case NETWORK_VALIDATION_UNSUPPORTED: return "unsupported"; case NETWORK_VALIDATION_NOT_REQUESTED: return "not requested"; case NETWORK_VALIDATION_IN_PROGRESS: return "in progress"; case NETWORK_VALIDATION_SUCCESS: return "success"; case NETWORK_VALIDATION_FAILURE: return "failure"; default: return Integer.toString(networkValidationStatus); } } /** * {@link PreciseDataConnectionState} builder * Loading Loading @@ -394,6 +484,10 @@ public final class PreciseDataConnectionState implements Parcelable { /** The Default QoS for this EPS/5GS bearer or null otherwise */ private @Nullable Qos mDefaultQos; /** The network validation status for the data connection. */ private @NetworkValidationStatus int mNetworkValidationStatus = NETWORK_VALIDATION_UNSUPPORTED; /** * Set the transport type of the data connection. * Loading Loading @@ -485,6 +579,19 @@ public final class PreciseDataConnectionState implements Parcelable { return this; } /** * Set the network validation state for the data connection. * * @param networkValidationStatus the network validation status of the data call * @return The builder */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @NonNull Builder setNetworkValidationStatus( @NetworkValidationStatus int networkValidationStatus) { mNetworkValidationStatus = networkValidationStatus; return this; } /** * Build the {@link PreciseDataConnectionState} instance. * Loading @@ -492,7 +599,8 @@ public final class PreciseDataConnectionState implements Parcelable { */ public PreciseDataConnectionState build() { return new PreciseDataConnectionState(mTransportType, mId, mState, mNetworkType, mLinkProperties, mFailCause, mApnSetting, mDefaultQos); mLinkProperties, mFailCause, mApnSetting, mDefaultQos, mNetworkValidationStatus); } } }
telephony/java/android/telephony/data/DataCallResponse.java +46 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.telephony.data; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; Loading @@ -27,9 +28,11 @@ import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.DataFailureCause; import android.telephony.DataFailCause; import android.telephony.PreciseDataConnectionState; import android.telephony.data.ApnSetting.ProtocolType; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.flags.Flags; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; Loading Loading @@ -123,7 +126,6 @@ public final class DataCallResponse implements Parcelable { * Indicates that the pdu session id is not set. */ public static final int PDU_SESSION_ID_NOT_SET = 0; private final @DataFailureCause int mCause; private final long mSuggestedRetryTime; private final int mId; Loading @@ -143,6 +145,7 @@ public final class DataCallResponse implements Parcelable { private final List<QosBearerSession> mQosBearerSessions; private final NetworkSliceInfo mSliceInfo; private final List<TrafficDescriptor> mTrafficDescriptors; private final @PreciseDataConnectionState.NetworkValidationStatus int mNetworkValidationStatus; /** * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error. Loading Loading @@ -185,7 +188,8 @@ public final class DataCallResponse implements Parcelable { HANDOVER_FAILURE_MODE_LEGACY, PDU_SESSION_ID_NOT_SET, null /* defaultQos */, Collections.emptyList() /* qosBearerSessions */, null /* sliceInfo */, Collections.emptyList() /* trafficDescriptors */); Collections.emptyList(), /* trafficDescriptors */ PreciseDataConnectionState.NETWORK_VALIDATION_UNSUPPORTED); } private DataCallResponse(@DataFailureCause int cause, long suggestedRetryTime, int id, Loading @@ -196,7 +200,8 @@ public final class DataCallResponse implements Parcelable { @HandoverFailureMode int handoverFailureMode, int pduSessionId, @Nullable Qos defaultQos, @NonNull List<QosBearerSession> qosBearerSessions, @Nullable NetworkSliceInfo sliceInfo, @NonNull List<TrafficDescriptor> trafficDescriptors) { @NonNull List<TrafficDescriptor> trafficDescriptors, @PreciseDataConnectionState.NetworkValidationStatus int networkValidationStatus) { mCause = cause; mSuggestedRetryTime = suggestedRetryTime; mId = id; Loading @@ -216,6 +221,7 @@ public final class DataCallResponse implements Parcelable { mQosBearerSessions = new ArrayList<>(qosBearerSessions); mSliceInfo = sliceInfo; mTrafficDescriptors = new ArrayList<>(trafficDescriptors); mNetworkValidationStatus = networkValidationStatus; if (mLinkStatus == LINK_STATUS_ACTIVE || mLinkStatus == LINK_STATUS_DORMANT) { Loading Loading @@ -270,6 +276,7 @@ public final class DataCallResponse implements Parcelable { source.readList(mTrafficDescriptors, TrafficDescriptor.class.getClassLoader(), android.telephony.data.TrafficDescriptor.class); mNetworkValidationStatus = source.readInt(); } /** Loading Loading @@ -442,6 +449,17 @@ public final class DataCallResponse implements Parcelable { return Collections.unmodifiableList(mTrafficDescriptors); } /** * Return the network validation status that was initiated by {@link * DataService.DataServiceProvider#requestValidation} * * @return The network validation status of data connection. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @PreciseDataConnectionState.NetworkValidationStatus int getNetworkValidationStatus() { return mNetworkValidationStatus; } @NonNull @Override public String toString() { Loading @@ -466,6 +484,8 @@ public final class DataCallResponse implements Parcelable { .append(" qosBearerSessions=").append(mQosBearerSessions) .append(" sliceInfo=").append(mSliceInfo) .append(" trafficDescriptors=").append(mTrafficDescriptors) .append(" networkValidationStatus=").append(PreciseDataConnectionState .networkValidationStatusToString(mNetworkValidationStatus)) .append("}"); return sb.toString(); } Loading Loading @@ -504,7 +524,8 @@ public final class DataCallResponse implements Parcelable { && mQosBearerSessions.containsAll(other.mQosBearerSessions) // non-null && Objects.equals(mSliceInfo, other.mSliceInfo) && mTrafficDescriptors.size() == other.mTrafficDescriptors.size() // non-null && mTrafficDescriptors.containsAll(other.mTrafficDescriptors); // non-null && mTrafficDescriptors.containsAll(other.mTrafficDescriptors) // non-null && mNetworkValidationStatus == other.mNetworkValidationStatus; } @Override Loading @@ -513,7 +534,7 @@ public final class DataCallResponse implements Parcelable { mInterfaceName, Set.copyOf(mAddresses), Set.copyOf(mDnsAddresses), Set.copyOf(mGatewayAddresses), Set.copyOf(mPcscfAddresses), mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, mDefaultQos, Set.copyOf(mQosBearerSessions), mSliceInfo, Set.copyOf(mTrafficDescriptors)); mSliceInfo, Set.copyOf(mTrafficDescriptors), mNetworkValidationStatus); } @Override Loading Loading @@ -542,6 +563,7 @@ public final class DataCallResponse implements Parcelable { dest.writeList(mQosBearerSessions); dest.writeParcelable(mSliceInfo, flags); dest.writeList(mTrafficDescriptors); dest.writeInt(mNetworkValidationStatus); } public static final @android.annotation.NonNull Parcelable.Creator<DataCallResponse> CREATOR = Loading Loading @@ -629,6 +651,9 @@ public final class DataCallResponse implements Parcelable { private List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>(); private @PreciseDataConnectionState.NetworkValidationStatus int mNetworkValidationStatus = PreciseDataConnectionState.NETWORK_VALIDATION_UNSUPPORTED; /** * Default constructor for Builder. */ Loading Loading @@ -904,6 +929,20 @@ public final class DataCallResponse implements Parcelable { return this; } /** * Set the network validation status that corresponds to the state of the network validation * request started by {@link DataService.DataServiceProvider#requestValidation} * * @param status The network validation status. * @return The same instance of the builder. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @NonNull Builder setNetworkValidationStatus( @PreciseDataConnectionState.NetworkValidationStatus int status) { mNetworkValidationStatus = status; return this; } /** * Build the DataCallResponse. * Loading @@ -913,7 +952,8 @@ public final class DataCallResponse implements Parcelable { return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, mDefaultQos, mQosBearerSessions, mSliceInfo, mTrafficDescriptors); mDefaultQos, mQosBearerSessions, mSliceInfo, mTrafficDescriptors, mNetworkValidationStatus); } } }
telephony/java/android/telephony/data/DataService.java +81 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.telephony.data; import android.annotation.CallbackExecutor; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; Loading @@ -26,6 +28,7 @@ import android.app.Service; import android.content.Intent; import android.net.LinkProperties; import android.os.Handler; import android.os.HandlerExecutor; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; Loading @@ -36,6 +39,9 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IIntegerConsumer; import com.android.internal.telephony.flags.Flags; import com.android.internal.util.FunctionalUtils; import com.android.telephony.Rlog; import java.lang.annotation.Retention; Loading @@ -44,6 +50,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.Consumer; /** * Base class of data service. Services that extend DataService must register the service in Loading Loading @@ -113,11 +121,14 @@ public abstract class DataService extends Service { private static final int DATA_SERVICE_REQUEST_REGISTER_APN_UNTHROTTLED = 14; private static final int DATA_SERVICE_REQUEST_UNREGISTER_APN_UNTHROTTLED = 15; private static final int DATA_SERVICE_INDICATION_APN_UNTHROTTLED = 16; private static final int DATA_SERVICE_REQUEST_VALIDATION = 17; private final HandlerThread mHandlerThread; private final DataServiceHandler mHandler; private final Executor mHandlerExecutor; private final SparseArray<DataServiceProvider> mServiceMap = new SparseArray<>(); /** @hide */ Loading Loading @@ -379,6 +390,43 @@ public abstract class DataService extends Service { } } /** * Request validation check to see if the network is working properly for a given data call. * * <p>This request is completed immediately after submitting the request to the data service * provider and receiving {@link DataServiceCallback.ResultCode}, and progress status or * validation results are notified through {@link * DataCallResponse#getNetworkValidationStatus}. * * <p> If the network validation request is submitted successfully, {@link * DataServiceCallback#RESULT_SUCCESS} is passed to {@code resultCodeCallback}. If the * network validation feature is not supported by the data service provider itself, {@link * DataServiceCallback#RESULT_ERROR_UNSUPPORTED} is passed to {@code resultCodeCallback}. * See {@link DataServiceCallback.ResultCode} for the type of response that indicates * whether the request was successfully submitted or had an error. * * <p>In response to this network validation request, providers can validate the data call * in their own way. For example, in IWLAN, the DPD (Dead Peer Detection) can be used as a * tool to check whether a data call is alive. * * @param cid The identifier of the data call which is provided in {@link DataCallResponse} * @param executor The callback executor for the response. * @param resultCodeCallback Listener for the {@link DataServiceCallback.ResultCode} that * request validation to the DataService and checks if the request has been submitted. */ @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public void requestValidation(int cid, @NonNull @CallbackExecutor Executor executor, @NonNull @DataServiceCallback.ResultCode Consumer<Integer> resultCodeCallback) { Objects.requireNonNull(executor, "executor cannot be null"); Objects.requireNonNull(resultCodeCallback, "resultCodeCallback cannot be null"); Log.d(TAG, "requestValidation: " + cid); // The default implementation is to return unsupported. executor.execute(() -> resultCodeCallback .accept(DataServiceCallback.RESULT_ERROR_UNSUPPORTED)); } /** * Notify the system that current data call list changed. Data service must invoke this Loading Loading @@ -537,6 +585,17 @@ public abstract class DataService extends Service { } } private static final class ValidationRequest { public final int cid; public final Executor executor; public final IIntegerConsumer callback; ValidationRequest(int cid, Executor executor, IIntegerConsumer callback) { this.cid = cid; this.executor = executor; this.callback = callback; } } private class DataServiceHandler extends Handler { DataServiceHandler(Looper looper) { Loading Loading @@ -679,6 +738,15 @@ public abstract class DataService extends Service { loge("Failed to call onApnUnthrottled. " + e); } break; case DATA_SERVICE_REQUEST_VALIDATION: if (serviceProvider == null) break; ValidationRequest validationRequest = (ValidationRequest) message.obj; serviceProvider.requestValidation( validationRequest.cid, validationRequest.executor, FunctionalUtils .ignoreRemoteException(validationRequest.callback::accept)); break; } } } Loading @@ -691,6 +759,7 @@ public abstract class DataService extends Service { mHandlerThread.start(); mHandler = new DataServiceHandler(mHandlerThread.getLooper()); mHandlerExecutor = new HandlerExecutor(mHandler); log("Data service created"); } Loading Loading @@ -853,6 +922,18 @@ public abstract class DataService extends Service { mHandler.obtainMessage(DATA_SERVICE_REQUEST_UNREGISTER_APN_UNTHROTTLED, slotIndex, 0, callback).sendToTarget(); } @Override public void requestValidation(int slotIndex, int cid, IIntegerConsumer resultCodeCallback) { if (resultCodeCallback == null) { loge("requestValidation: resultCodeCallback is null"); return; } ValidationRequest validationRequest = new ValidationRequest(cid, mHandlerExecutor, resultCodeCallback); mHandler.obtainMessage(DATA_SERVICE_REQUEST_VALIDATION, slotIndex, 0, validationRequest).sendToTarget(); } } private void log(String s) { Loading