Merge changes from topics "apn_throttle", "rename_retry_interval"

* changes:
  Add apn throttle status notifications to QNS
  Renamed retry interval to retry duration
This commit is contained in:
Daniel Bright
2021-01-06 00:43:25 +00:00
committed by Gerrit Code Review
11 changed files with 592 additions and 17 deletions

View File

@@ -10494,6 +10494,35 @@ package android.telephony.cdma {
package android.telephony.data {
public final class ApnThrottleStatus implements android.os.Parcelable {
method public int describeContents();
method public int getApnType();
method public int getRetryType();
method public int getSlotIndex();
method public long getThrottleExpiryTimeMillis();
method public int getThrottleType();
method public int getTransportType();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.ApnThrottleStatus> CREATOR;
field public static final int RETRY_TYPE_HANDOVER = 3; // 0x3
field public static final int RETRY_TYPE_NEW_CONNECTION = 2; // 0x2
field public static final int RETRY_TYPE_NONE = 1; // 0x1
field public static final int THROTTLE_TYPE_ELAPSED_TIME = 2; // 0x2
field public static final int THROTTLE_TYPE_NONE = 1; // 0x1
}
public static final class ApnThrottleStatus.Builder {
ctor public ApnThrottleStatus.Builder();
method @NonNull public android.telephony.data.ApnThrottleStatus build();
method @NonNull public android.telephony.data.ApnThrottleStatus.Builder setApnType(int);
method @NonNull public android.telephony.data.ApnThrottleStatus.Builder setNoThrottle();
method @NonNull public android.telephony.data.ApnThrottleStatus.Builder setRetryType(int);
method @NonNull public android.telephony.data.ApnThrottleStatus.Builder setSlotIndex(int);
method @NonNull public android.telephony.data.ApnThrottleStatus.Builder setThrottleExpiryTimeMillis(long);
method @NonNull public android.telephony.data.ApnThrottleStatus.Builder setTransportType(int);
field public static final long NO_THROTTLE_EXPIRY_TIME = -1L; // 0xffffffffffffffffL
}
public final class DataCallResponse implements android.os.Parcelable {
method public int describeContents();
method @NonNull public java.util.List<android.net.LinkAddress> getAddresses();
@@ -10510,7 +10539,7 @@ package android.telephony.data {
method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses();
method public int getPduSessionId();
method public int getProtocolType();
method public long getRetryIntervalMillis();
method public long getRetryDurationMillis();
method @Deprecated public int getSuggestedRetryTime();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR;
@@ -10524,7 +10553,7 @@ package android.telephony.data {
field public static final int LINK_STATUS_INACTIVE = 0; // 0x0
field public static final int LINK_STATUS_UNKNOWN = -1; // 0xffffffff
field public static final int PDU_SESSION_ID_NOT_SET = 0; // 0x0
field public static final int RETRY_INTERVAL_UNDEFINED = -1; // 0xffffffff
field public static final int RETRY_DURATION_UNDEFINED = -1; // 0xffffffff
}
public static final class DataCallResponse.Builder {
@@ -10544,7 +10573,7 @@ package android.telephony.data {
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(int);
method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int);
method @NonNull public android.telephony.data.DataCallResponse.Builder setRetryIntervalMillis(long);
method @NonNull public android.telephony.data.DataCallResponse.Builder setRetryDurationMillis(long);
method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int);
}
@@ -10611,6 +10640,7 @@ package android.telephony.data {
method public abstract void close();
method public void deactivateDataCall(int, int, @Nullable android.telephony.data.DataServiceCallback);
method public final int getSlotIndex();
method public final void notifyApnUnthrottled(@NonNull String);
method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback);
method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @NonNull android.telephony.data.DataServiceCallback);
@@ -10621,6 +10651,7 @@ package android.telephony.data {
}
public class DataServiceCallback {
method public void onApnUnthrottled(@NonNull String);
method public void onDataCallListChanged(@NonNull java.util.List<android.telephony.data.DataCallResponse>);
method public void onDeactivateDataCallComplete(int);
method public void onHandoverCancelled(int);
@@ -10646,6 +10677,7 @@ package android.telephony.data {
ctor public QualifiedNetworksService.NetworkAvailabilityProvider(int);
method public abstract void close();
method public final int getSlotIndex();
method public void reportApnThrottleStatusChanged(@NonNull java.util.List<android.telephony.data.ApnThrottleStatus>);
method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List<java.lang.Integer>);
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** @hide */
package android.telephony.data;
parcelable ApnThrottleStatus;

View File

@@ -0,0 +1,383 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.telephony.data;
import android.annotation.ElapsedRealtimeLong;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation;
import java.util.Objects;
/**
* Status information regarding the throttle status of an APN type.
*
* @hide
*/
@SystemApi
public final class ApnThrottleStatus implements Parcelable {
/**
* The APN type is not throttled.
*/
public static final int THROTTLE_TYPE_NONE = 1;
/**
* The APN type is throttled until {@link android.os.SystemClock#elapsedRealtime()}
* has reached {@link ApnThrottleStatus#getThrottleExpiryTimeMillis}
*/
public static final int THROTTLE_TYPE_ELAPSED_TIME = 2;
/** {@hide} */
@IntDef(flag = true, prefix = {"THROTTLE_TYPE_"}, value = {
ApnThrottleStatus.THROTTLE_TYPE_NONE,
ApnThrottleStatus.THROTTLE_TYPE_ELAPSED_TIME,
})
public @interface ThrottleType {
}
/**
* The framework will not retry the APN type.
*/
public static final int RETRY_TYPE_NONE = 1;
/**
* The next time the framework retries, it will attempt to establish a new connection.
*/
public static final int RETRY_TYPE_NEW_CONNECTION = 2;
/**
* The next time the framework retires, it will retry to handover.
*/
public static final int RETRY_TYPE_HANDOVER = 3;
/** {@hide} */
@IntDef(flag = true, prefix = {"RETRY_TYPE_"}, value = {
ApnThrottleStatus.RETRY_TYPE_NONE,
ApnThrottleStatus.RETRY_TYPE_NEW_CONNECTION,
ApnThrottleStatus.RETRY_TYPE_HANDOVER,
})
public @interface RetryType {
}
private final int mSlotIndex;
private final @AccessNetworkConstants.TransportType int mTransportType;
private final @Annotation.ApnType int mApnType;
private final long mThrottleExpiryTimeMillis;
private final @RetryType int mRetryType;
private final @ThrottleType int mThrottleType;
/**
* The slot index that the status applies to.
*
* @return the slot index
*/
public int getSlotIndex() {
return mSlotIndex;
}
/**
* The type of transport that the status applies to.
*
* @return the transport type
*/
@AccessNetworkConstants.TransportType
public int getTransportType() {
return mTransportType;
}
/**
* The APN type that the status applies to.
*
* @return the apn type
*/
@Annotation.ApnType
public int getApnType() {
return mApnType;
}
/**
* The type of throttle applied to the APN type.
*
* @return the throttle type
*/
@ThrottleType
public int getThrottleType() {
return mThrottleType;
}
/**
* Indicates the type of request that the framework will make the next time it retries
* to call {@link IDataService#setupDataCall}.
*
* @return the retry type
*/
@RetryType
public int getRetryType() {
return mRetryType;
}
/**
* Gets the time at which the throttle expires. The value is based off of
* {@link SystemClock#elapsedRealtime}.
*
* This value only applies when the throttle type is set to
* {@link ApnThrottleStatus#THROTTLE_TYPE_ELAPSED_TIME}.
*
* A value of {@link Long#MAX_VALUE} implies that the APN type is throttled indefinitely.
*
* @return the time at which the throttle expires
*/
@ElapsedRealtimeLong
public long getThrottleExpiryTimeMillis() {
return mThrottleExpiryTimeMillis;
}
private ApnThrottleStatus(int slotIndex,
@AccessNetworkConstants.TransportType int transportType,
@Annotation.ApnType int apnTypes,
@ThrottleType int throttleType,
long throttleExpiryTimeMillis,
@RetryType int retryType) {
mSlotIndex = slotIndex;
mTransportType = transportType;
mApnType = apnTypes;
mThrottleType = throttleType;
mThrottleExpiryTimeMillis = throttleExpiryTimeMillis;
mRetryType = retryType;
}
private ApnThrottleStatus(@NonNull Parcel source) {
mSlotIndex = source.readInt();
mTransportType = source.readInt();
mApnType = source.readInt();
mThrottleExpiryTimeMillis = source.readLong();
mRetryType = source.readInt();
mThrottleType = source.readInt();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mSlotIndex);
dest.writeInt(mTransportType);
dest.writeInt(mApnType);
dest.writeLong(mThrottleExpiryTimeMillis);
dest.writeInt(mRetryType);
dest.writeInt(mThrottleType);
}
public static final @NonNull Parcelable.Creator<ApnThrottleStatus> CREATOR =
new Parcelable.Creator<ApnThrottleStatus>() {
@Override
public ApnThrottleStatus createFromParcel(@NonNull Parcel source) {
return new ApnThrottleStatus(source);
}
@Override
public ApnThrottleStatus[] newArray(int size) {
return new ApnThrottleStatus[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public int hashCode() {
return Objects.hash(mSlotIndex, mApnType, mRetryType, mThrottleType,
mThrottleExpiryTimeMillis, mTransportType);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
} else if (obj instanceof ApnThrottleStatus) {
ApnThrottleStatus other = (ApnThrottleStatus) obj;
return this.mSlotIndex == other.mSlotIndex
&& this.mApnType == other.mApnType
&& this.mRetryType == other.mRetryType
&& this.mThrottleType == other.mThrottleType
&& this.mThrottleExpiryTimeMillis == other.mThrottleExpiryTimeMillis
&& this.mTransportType == other.mTransportType;
} else {
return false;
}
}
@Override
public String toString() {
return "ApnThrottleStatus{"
+ "mSlotIndex=" + mSlotIndex
+ ", mTransportType=" + mTransportType
+ ", mApnType=" + ApnSetting.getApnTypeString(mApnType)
+ ", mThrottleExpiryTimeMillis=" + mThrottleExpiryTimeMillis
+ ", mRetryType=" + mRetryType
+ ", mThrottleType=" + mThrottleType
+ '}';
}
/**
* Provides a convenient way to set the fields of an {@link ApnThrottleStatus} when creating a
* new instance.
*
* <p>The example below shows how you might create a new {@code ApnThrottleStatus}:
*
* <pre><code>
*
* DataCallResponseApnThrottleStatus = new ApnThrottleStatus.Builder()
* .setSlotIndex(1)
* .setApnType({@link ApnSetting#TYPE_EMERGENCY})
* .setNoThrottle()
* .setRetryType({@link ApnThrottleStatus#RETRY_TYPE_NEW_CONNECTION})
* .build();
* </code></pre>
*/
public static final class Builder {
private int mSlotIndex;
private @AccessNetworkConstants.TransportType int mTransportType;
private @Annotation.ApnType int mApnType;
private long mThrottleExpiryTimeMillis;
private @RetryType int mRetryType;
private @ThrottleType int mThrottleType;
public static final long NO_THROTTLE_EXPIRY_TIME =
DataCallResponse.RETRY_DURATION_UNDEFINED;
/**
* Default constructor for the Builder.
*/
public Builder() {
}
/**
* Set the slot index.
*
* @param slotIndex the slot index.
* @return The same instance of the builder.
*/
@NonNull
public Builder setSlotIndex(int slotIndex) {
this.mSlotIndex = slotIndex;
return this;
}
/**
* Set the transport type.
*
* @param transportType the transport type.
* @return The same instance of the builder.
*/
@NonNull
public Builder setTransportType(@AccessNetworkConstants.TransportType
int transportType) {
this.mTransportType = transportType;
return this;
}
/**
* Set the APN type.
*
* @param apnType the APN type.
* @return The same instance of the builder.
*/
@NonNull
public Builder setApnType(@Annotation.ApnType int apnType) {
this.mApnType = apnType;
return this;
}
/**
* Sets the time at which the throttle will expire. The value is based off of
* {@link SystemClock#elapsedRealtime}.
*
* When setting this value, the throttle type is set to
* {@link ApnThrottleStatus#THROTTLE_TYPE_ELAPSED_TIME}.
*
* A value of {@link Long#MAX_VALUE} implies that the APN type is throttled indefinitely.
*
* @param throttleExpiryTimeMillis The elapsed time at which the throttle expires.
* Throws {@link IllegalArgumentException} for values less
* than 0.
* @return The same instance of the builder.
*/
@NonNull
public Builder setThrottleExpiryTimeMillis(
@ElapsedRealtimeLong long throttleExpiryTimeMillis) {
if (throttleExpiryTimeMillis >= 0) {
this.mThrottleExpiryTimeMillis = throttleExpiryTimeMillis;
this.mThrottleType = THROTTLE_TYPE_ELAPSED_TIME;
} else {
throw new IllegalArgumentException("throttleExpiryTimeMillis must be greater than "
+ "or equal to 0");
}
return this;
}
/**
* Sets the status of the APN type as not being throttled.
*
* When setting this value, the throttle type is set to
* {@link ApnThrottleStatus#THROTTLE_TYPE_NONE} and the expiry time is set to
* {@link Builder#NO_THROTTLE_EXPIRY_TIME}.
*
* @return The same instance of the builder.
*/
@SuppressLint("MissingGetterMatchingBuilder")
@NonNull
public Builder setNoThrottle() {
mThrottleType = THROTTLE_TYPE_NONE;
mThrottleExpiryTimeMillis = NO_THROTTLE_EXPIRY_TIME;
return this;
}
/**
* Set the type of request that the framework will make the next time it retries
* to call {@link IDataService#setupDataCall}.
*
* @param retryType the type of request
* @return The same instance of the builder.
*/
@NonNull
public Builder setRetryType(@RetryType int retryType) {
this.mRetryType = retryType;
return this;
}
/**
* Build the {@link ApnThrottleStatus}
*
* @return the {@link ApnThrottleStatus} object
*/
@NonNull
public ApnThrottleStatus build() {
return new ApnThrottleStatus(
mSlotIndex,
mTransportType,
mApnType,
mThrottleType,
mThrottleExpiryTimeMillis,
mRetryType);
}
}
}

View File

@@ -109,10 +109,10 @@ public final class DataCallResponse implements Parcelable {
public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL = 3;
/**
* Indicates that data retry interval is not specified. Platform can determine when to
* Indicates that data retry duration is not specified. Platform can determine when to
* perform data setup appropriately.
*/
public static final int RETRY_INTERVAL_UNDEFINED = -1;
public static final int RETRY_DURATION_UNDEFINED = -1;
/**
* Indicates that the pdu session id is not set.
@@ -254,19 +254,26 @@ public final class DataCallResponse implements Parcelable {
/**
* @return The suggested data retry time in milliseconds.
*
* @deprecated Use {@link #getRetryIntervalMillis()} instead.
* @deprecated Use {@link #getRetryDurationMillis()} instead.
*/
@Deprecated
public int getSuggestedRetryTime() {
// To match the pre-deprecated getSuggestedRetryTime() behavior.
if (mSuggestedRetryTime == RETRY_DURATION_UNDEFINED) {
return 0;
} else if (mSuggestedRetryTime > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
return (int) mSuggestedRetryTime;
}
/**
* @return The network suggested data retry interval in milliseconds. {@code Long.MAX_VALUE}
* indicates data retry should not occur. {@link #RETRY_INTERVAL_UNDEFINED} indicates network
* did not suggest any retry interval.
* @return The network suggested data retry duration in milliseconds. {@code Long.MAX_VALUE}
* indicates data retry should not occur. {@link #RETRY_DURATION_UNDEFINED} indicates network
* did not suggest any retry duration.
*/
public long getRetryIntervalMillis() {
public long getRetryDurationMillis() {
return mSuggestedRetryTime;
}
@@ -537,7 +544,7 @@ public final class DataCallResponse implements Parcelable {
public static final class Builder {
private @DataFailureCause int mCause;
private long mSuggestedRetryTime = RETRY_INTERVAL_UNDEFINED;
private long mSuggestedRetryTime = RETRY_DURATION_UNDEFINED;
private int mId;
@@ -592,7 +599,7 @@ public final class DataCallResponse implements Parcelable {
* @param suggestedRetryTime The suggested data retry time in milliseconds.
* @return The same instance of the builder.
*
* @deprecated Use {@link #setRetryIntervalMillis(long)} instead.
* @deprecated Use {@link #setRetryDurationMillis(long)} instead.
*/
@Deprecated
public @NonNull Builder setSuggestedRetryTime(int suggestedRetryTime) {
@@ -601,13 +608,13 @@ public final class DataCallResponse implements Parcelable {
}
/**
* Set the network suggested data retry interval.
* Set the network suggested data retry duration.
*
* @param retryIntervalMillis The suggested data retry interval in milliseconds.
* @param retryDurationMillis The suggested data retry duration in milliseconds.
* @return The same instance of the builder.
*/
public @NonNull Builder setRetryIntervalMillis(long retryIntervalMillis) {
mSuggestedRetryTime = retryIntervalMillis;
public @NonNull Builder setRetryDurationMillis(long retryDurationMillis) {
mSuggestedRetryTime = retryDurationMillis;
return this;
}

View File

@@ -107,6 +107,9 @@ public abstract class DataService extends Service {
private static final int DATA_SERVICE_INDICATION_DATA_CALL_LIST_CHANGED = 11;
private static final int DATA_SERVICE_REQUEST_START_HANDOVER = 12;
private static final int DATA_SERVICE_REQUEST_CANCEL_HANDOVER = 13;
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 final HandlerThread mHandlerThread;
@@ -129,6 +132,8 @@ public abstract class DataService extends Service {
private final List<IDataServiceCallback> mDataCallListChangedCallbacks = new ArrayList<>();
private final List<IDataServiceCallback> mApnUnthrottledCallbacks = new ArrayList<>();
/**
* Constructor
* @param slotIndex SIM slot index the data service provider associated with.
@@ -326,6 +331,19 @@ public abstract class DataService extends Service {
}
}
private void registerForApnUnthrottled(IDataServiceCallback callback) {
synchronized (mApnUnthrottledCallbacks) {
mApnUnthrottledCallbacks.add(callback);
}
}
private void unregisterForApnUnthrottled(IDataServiceCallback callback) {
synchronized (mApnUnthrottledCallbacks) {
mApnUnthrottledCallbacks.remove(callback);
}
}
/**
* Notify the system that current data call list changed. Data service must invoke this
* method whenever there is any data call status changed.
@@ -342,6 +360,21 @@ public abstract class DataService extends Service {
}
}
/**
* Notify the system that a given APN was unthrottled.
*
* @param apn Access Point Name defined by the carrier.
*/
public final void notifyApnUnthrottled(@NonNull String apn) {
synchronized (mApnUnthrottledCallbacks) {
for (IDataServiceCallback callback : mApnUnthrottledCallbacks) {
mHandler.obtainMessage(DATA_SERVICE_INDICATION_APN_UNTHROTTLED,
mSlotIndex, 0, new ApnUnthrottledIndication(apn,
callback)).sendToTarget();
}
}
}
/**
* Called when the instance of data service is destroyed (e.g. got unbind or binder died)
* or when the data service provider is removed. The extended class should implement this
@@ -429,6 +462,16 @@ public abstract class DataService extends Service {
}
}
private static final class ApnUnthrottledIndication {
public final String apn;
public final IDataServiceCallback callback;
ApnUnthrottledIndication(String apn,
IDataServiceCallback callback) {
this.apn = apn;
this.callback = callback;
}
}
private class DataServiceHandler extends Handler {
DataServiceHandler(Looper looper) {
@@ -544,6 +587,26 @@ public abstract class DataService extends Service {
(cReq.callback != null)
? new DataServiceCallback(cReq.callback) : null);
break;
case DATA_SERVICE_REQUEST_REGISTER_APN_UNTHROTTLED:
if (serviceProvider == null) break;
serviceProvider.registerForApnUnthrottled((IDataServiceCallback) message.obj);
break;
case DATA_SERVICE_REQUEST_UNREGISTER_APN_UNTHROTTLED:
if (serviceProvider == null) break;
callback = (IDataServiceCallback) message.obj;
serviceProvider.unregisterForApnUnthrottled(callback);
break;
case DATA_SERVICE_INDICATION_APN_UNTHROTTLED:
if (serviceProvider == null) break;
ApnUnthrottledIndication apnUnthrottledIndication =
(ApnUnthrottledIndication) message.obj;
try {
apnUnthrottledIndication.callback
.onApnUnthrottled(apnUnthrottledIndication.apn);
} catch (RemoteException e) {
loge("Failed to call onApnUnthrottled. " + e);
}
break;
}
}
}
@@ -695,6 +758,26 @@ public abstract class DataService extends Service {
mHandler.obtainMessage(DATA_SERVICE_REQUEST_CANCEL_HANDOVER,
slotIndex, 0, req).sendToTarget();
}
@Override
public void registerForUnthrottleApn(int slotIndex, IDataServiceCallback callback) {
if (callback == null) {
loge("registerForUnthrottleApn: callback is null");
return;
}
mHandler.obtainMessage(DATA_SERVICE_REQUEST_REGISTER_APN_UNTHROTTLED, slotIndex,
0, callback).sendToTarget();
}
@Override
public void unregisterForUnthrottleApn(int slotIndex, IDataServiceCallback callback) {
if (callback == null) {
loge("uregisterForUnthrottleApn: callback is null");
return;
}
mHandler.obtainMessage(DATA_SERVICE_REQUEST_UNREGISTER_APN_UNTHROTTLED,
slotIndex, 0, callback).sendToTarget();
}
}
private void log(String s) {

View File

@@ -233,7 +233,7 @@ public class DataServiceCallback {
*/
@NonNull
public static String resultCodeToString(@DataServiceCallback.ResultCode int resultCode) {
switch(resultCode) {
switch (resultCode) {
case RESULT_SUCCESS:
return "RESULT_SUCCESS";
case RESULT_ERROR_UNSUPPORTED:
@@ -248,4 +248,22 @@ public class DataServiceCallback {
return "Missing case for result code=" + resultCode;
}
}
/**
* Indicates that the specified APN is no longer throttled.
*
* @param apn Access Point Name defined by the carrier.
*/
public void onApnUnthrottled(@NonNull String apn) {
if (mCallback != null) {
try {
if (DBG) Rlog.d(TAG, "onApnUnthrottled");
mCallback.onApnUnthrottled(apn);
} catch (RemoteException e) {
Rlog.e(TAG, "onApnUnthrottled: remote exception", e);
}
} else {
Rlog.e(TAG, "onApnUnthrottled: callback is null!");
}
}
}

View File

@@ -40,4 +40,6 @@ oneway interface IDataService
void unregisterForDataCallListChanged(int slotId, IDataServiceCallback callback);
void startHandover(int slotId, int cid, IDataServiceCallback callback);
void cancelHandover(int slotId, int cid, IDataServiceCallback callback);
void registerForUnthrottleApn(int slotIndex, IDataServiceCallback callback);
void unregisterForUnthrottleApn(int slotIndex, IDataServiceCallback callback);
}

View File

@@ -32,4 +32,5 @@ oneway interface IDataServiceCallback
void onDataCallListChanged(in List<DataCallResponse> dataCallList);
void onHandoverStarted(int result);
void onHandoverCancelled(int result);
void onApnUnthrottled(in String apn);
}

View File

@@ -17,6 +17,7 @@
package android.telephony.data;
import android.telephony.data.IQualifiedNetworksServiceCallback;
import android.telephony.data.ApnThrottleStatus;
/**
* {@hide}
@@ -25,4 +26,5 @@ interface IQualifiedNetworksService
{
oneway void createNetworkAvailabilityProvider(int slotId, IQualifiedNetworksServiceCallback callback);
oneway void removeNetworkAvailabilityProvider(int slotId);
oneway void reportApnThrottleStatusChanged(int slotId, in List<ApnThrottleStatus> statuses);
}

View File

@@ -28,6 +28,7 @@ import android.os.Message;
import android.os.RemoteException;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.Annotation.ApnType;
import android.util.Log;
import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
@@ -65,6 +66,7 @@ public abstract class QualifiedNetworksService extends Service {
private static final int QNS_REMOVE_NETWORK_AVAILABILITY_PROVIDER = 2;
private static final int QNS_REMOVE_ALL_NETWORK_AVAILABILITY_PROVIDERS = 3;
private static final int QNS_UPDATE_QUALIFIED_NETWORKS = 4;
private static final int QNS_APN_THROTTLE_STATUS_CHANGED = 5;
private final HandlerThread mHandlerThread;
@@ -159,6 +161,17 @@ public abstract class QualifiedNetworksService extends Service {
}
}
/**
* The framework calls this method when the throttle status of an APN changes.
*
* This method is meant to be overridden.
*
* @param statuses the statuses that have changed
*/
public void reportApnThrottleStatusChanged(@NonNull List<ApnThrottleStatus> statuses) {
Log.d(TAG, "reportApnThrottleStatusChanged: statuses size=" + statuses.size());
}
/**
* Called when the qualified networks provider is removed. The extended class should
* implement this method to perform cleanup works.
@@ -197,6 +210,12 @@ public abstract class QualifiedNetworksService extends Service {
+ slotIndex);
}
break;
case QNS_APN_THROTTLE_STATUS_CHANGED:
if (provider != null) {
List<ApnThrottleStatus> statuses = (List<ApnThrottleStatus>) message.obj;
provider.reportApnThrottleStatusChanged(statuses);
}
break;
case QNS_REMOVE_NETWORK_AVAILABILITY_PROVIDER:
if (provider != null) {
@@ -286,6 +305,13 @@ public abstract class QualifiedNetworksService extends Service {
mHandler.obtainMessage(QNS_REMOVE_NETWORK_AVAILABILITY_PROVIDER, slotIndex, 0)
.sendToTarget();
}
@Override
public void reportApnThrottleStatusChanged(int slotIndex,
List<ApnThrottleStatus> statuses) {
mHandler.obtainMessage(QNS_APN_THROTTLE_STATUS_CHANGED, slotIndex, 0, statuses)
.sendToTarget();
}
}
private void log(String s) {

View File

@@ -113,6 +113,7 @@ public class DctConstants {
public static final int EVENT_NR_TIMER_WATCHDOG = BASE + 53;
public static final int EVENT_CARRIER_CONFIG_CHANGED = BASE + 54;
public static final int EVENT_SIM_STATE_UPDATED = BASE + 55;
public static final int EVENT_APN_UNTHROTTLED = BASE + 56;
/***** Constants *****/