1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.telephony.data; 18 19 import android.annotation.ElapsedRealtimeLong; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.SuppressLint; 23 import android.annotation.SystemApi; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 import android.os.SystemClock; 27 import android.telephony.AccessNetworkConstants; 28 import android.telephony.Annotation; 29 30 import java.lang.annotation.Retention; 31 import java.lang.annotation.RetentionPolicy; 32 import java.util.Objects; 33 34 /** 35 * Status information regarding the throttle status of an APN type. 36 * 37 * @hide 38 */ 39 @SystemApi 40 public final class ThrottleStatus implements Parcelable { 41 /** 42 * The APN type is not throttled. 43 */ 44 public static final int THROTTLE_TYPE_NONE = 1; 45 46 /** 47 * The APN type is throttled until {@link android.os.SystemClock#elapsedRealtime()} 48 * has reached {@link ThrottleStatus#getThrottleExpiryTimeMillis} 49 */ 50 public static final int THROTTLE_TYPE_ELAPSED_TIME = 2; 51 52 /** {@hide} */ 53 @IntDef(flag = true, prefix = {"THROTTLE_TYPE_"}, value = { 54 ThrottleStatus.THROTTLE_TYPE_NONE, 55 ThrottleStatus.THROTTLE_TYPE_ELAPSED_TIME, 56 }) 57 @Retention(RetentionPolicy.SOURCE) 58 public @interface ThrottleType { 59 } 60 61 /** 62 * The framework will not retry the APN type. 63 */ 64 public static final int RETRY_TYPE_NONE = 1; 65 66 /** 67 * The next time the framework retries, it will attempt to establish a new connection. 68 */ 69 public static final int RETRY_TYPE_NEW_CONNECTION = 2; 70 71 /** 72 * The next time the framework retires, it will retry to handover. 73 */ 74 public static final int RETRY_TYPE_HANDOVER = 3; 75 76 /** {@hide} */ 77 @IntDef(flag = true, prefix = {"RETRY_TYPE_"}, value = { 78 ThrottleStatus.RETRY_TYPE_NONE, 79 ThrottleStatus.RETRY_TYPE_NEW_CONNECTION, 80 ThrottleStatus.RETRY_TYPE_HANDOVER, 81 }) 82 @Retention(RetentionPolicy.SOURCE) 83 public @interface RetryType { 84 } 85 86 private final int mSlotIndex; 87 private final @AccessNetworkConstants.TransportType int mTransportType; 88 private final @Annotation.ApnType int mApnType; 89 private final long mThrottleExpiryTimeMillis; 90 private final @RetryType int mRetryType; 91 private final @ThrottleType int mThrottleType; 92 93 /** 94 * The slot index that the status applies to. 95 * 96 * @return the slot index 97 */ getSlotIndex()98 public int getSlotIndex() { 99 return mSlotIndex; 100 } 101 102 /** 103 * The type of transport that the status applies to. 104 * 105 * @return the transport type 106 */ 107 @AccessNetworkConstants.TransportType getTransportType()108 public int getTransportType() { 109 return mTransportType; 110 } 111 112 /** 113 * The APN type that the status applies to. 114 * 115 * @return the apn type 116 */ 117 @Annotation.ApnType getApnType()118 public int getApnType() { 119 return mApnType; 120 } 121 122 /** 123 * The type of throttle applied to the APN type. 124 * 125 * @return the throttle type 126 */ 127 @ThrottleType getThrottleType()128 public int getThrottleType() { 129 return mThrottleType; 130 } 131 132 /** 133 * Indicates the type of request that the framework will make the next time it retries 134 * to call {@link IDataService#setupDataCall}. 135 * 136 * @return the retry type 137 */ 138 @RetryType getRetryType()139 public int getRetryType() { 140 return mRetryType; 141 } 142 143 /** 144 * Gets the time at which the throttle expires. The value is based off of 145 * {@link SystemClock#elapsedRealtime}. 146 * 147 * This value only applies when the throttle type is set to 148 * {@link ThrottleStatus#THROTTLE_TYPE_ELAPSED_TIME}. 149 * 150 * A value of {@link Long#MAX_VALUE} implies that the APN type is throttled indefinitely. 151 * 152 * @return the time at which the throttle expires 153 */ 154 @ElapsedRealtimeLong getThrottleExpiryTimeMillis()155 public long getThrottleExpiryTimeMillis() { 156 return mThrottleExpiryTimeMillis; 157 } 158 ThrottleStatus(int slotIndex, @AccessNetworkConstants.TransportType int transportType, @Annotation.ApnType int apnTypes, @ThrottleType int throttleType, long throttleExpiryTimeMillis, @RetryType int retryType)159 private ThrottleStatus(int slotIndex, 160 @AccessNetworkConstants.TransportType int transportType, 161 @Annotation.ApnType int apnTypes, 162 @ThrottleType int throttleType, 163 long throttleExpiryTimeMillis, 164 @RetryType int retryType) { 165 mSlotIndex = slotIndex; 166 mTransportType = transportType; 167 mApnType = apnTypes; 168 mThrottleType = throttleType; 169 mThrottleExpiryTimeMillis = throttleExpiryTimeMillis; 170 mRetryType = retryType; 171 } 172 ThrottleStatus(@onNull Parcel source)173 private ThrottleStatus(@NonNull Parcel source) { 174 mSlotIndex = source.readInt(); 175 mTransportType = source.readInt(); 176 mApnType = source.readInt(); 177 mThrottleExpiryTimeMillis = source.readLong(); 178 mRetryType = source.readInt(); 179 mThrottleType = source.readInt(); 180 } 181 182 @Override writeToParcel(@onNull Parcel dest, int flags)183 public void writeToParcel(@NonNull Parcel dest, int flags) { 184 dest.writeInt(mSlotIndex); 185 dest.writeInt(mTransportType); 186 dest.writeInt(mApnType); 187 dest.writeLong(mThrottleExpiryTimeMillis); 188 dest.writeInt(mRetryType); 189 dest.writeInt(mThrottleType); 190 } 191 192 public static final @NonNull Parcelable.Creator<ThrottleStatus> CREATOR = 193 new Parcelable.Creator<ThrottleStatus>() { 194 @Override 195 public ThrottleStatus createFromParcel(@NonNull Parcel source) { 196 return new ThrottleStatus(source); 197 } 198 199 @Override 200 public ThrottleStatus[] newArray(int size) { 201 return new ThrottleStatus[size]; 202 } 203 }; 204 205 @Override describeContents()206 public int describeContents() { 207 return 0; 208 } 209 210 @Override hashCode()211 public int hashCode() { 212 return Objects.hash(mSlotIndex, mApnType, mRetryType, mThrottleType, 213 mThrottleExpiryTimeMillis, mTransportType); 214 } 215 216 @Override equals(Object obj)217 public boolean equals(Object obj) { 218 if (obj == null) { 219 return false; 220 } else if (obj instanceof ThrottleStatus) { 221 ThrottleStatus other = (ThrottleStatus) obj; 222 return this.mSlotIndex == other.mSlotIndex 223 && this.mApnType == other.mApnType 224 && this.mRetryType == other.mRetryType 225 && this.mThrottleType == other.mThrottleType 226 && this.mThrottleExpiryTimeMillis == other.mThrottleExpiryTimeMillis 227 && this.mTransportType == other.mTransportType; 228 } else { 229 return false; 230 } 231 } 232 233 @Override toString()234 public String toString() { 235 return "ThrottleStatus{" 236 + "mSlotIndex=" + mSlotIndex 237 + ", mTransportType=" + mTransportType 238 + ", mApnType=" + ApnSetting.getApnTypeString(mApnType) 239 + ", mThrottleExpiryTimeMillis=" + mThrottleExpiryTimeMillis 240 + ", mRetryType=" + mRetryType 241 + ", mThrottleType=" + mThrottleType 242 + '}'; 243 } 244 245 /** 246 * Provides a convenient way to set the fields of an {@link ThrottleStatus} when creating a 247 * new instance. 248 * 249 * <p>The example below shows how you might create a new {@code ThrottleStatus}: 250 * 251 * <pre><code> 252 * 253 * ThrottleStatus = new ThrottleStatus.Builder() 254 * .setSlotIndex(1) 255 * .setApnType({@link ApnSetting#TYPE_EMERGENCY}) 256 * .setNoThrottle() 257 * .setRetryType({@link ThrottleStatus#RETRY_TYPE_NEW_CONNECTION}) 258 * .build(); 259 * </code></pre> 260 */ 261 public static final class Builder { 262 private int mSlotIndex; 263 private @AccessNetworkConstants.TransportType int mTransportType; 264 private @Annotation.ApnType int mApnType; 265 private long mThrottleExpiryTimeMillis; 266 private @RetryType int mRetryType; 267 private @ThrottleType int mThrottleType; 268 269 /** 270 * @hide 271 */ 272 public static final long NO_THROTTLE_EXPIRY_TIME = 273 DataCallResponse.RETRY_DURATION_UNDEFINED; 274 275 /** 276 * Default constructor for the Builder. 277 */ Builder()278 public Builder() { 279 } 280 281 /** 282 * Set the slot index. 283 * 284 * @param slotIndex the slot index. 285 * @return The same instance of the builder. 286 */ 287 @NonNull setSlotIndex(int slotIndex)288 public Builder setSlotIndex(int slotIndex) { 289 this.mSlotIndex = slotIndex; 290 return this; 291 } 292 293 /** 294 * Set the transport type. 295 * 296 * @param transportType the transport type. 297 * @return The same instance of the builder. 298 */ 299 @NonNull setTransportType(@ccessNetworkConstants.TransportType int transportType)300 public Builder setTransportType(@AccessNetworkConstants.TransportType 301 int transportType) { 302 this.mTransportType = transportType; 303 return this; 304 } 305 306 /** 307 * Set the APN type. 308 * 309 * @param apnType the APN type. 310 * @return The same instance of the builder. 311 */ 312 @NonNull setApnType(@nnotation.ApnType int apnType)313 public Builder setApnType(@Annotation.ApnType int apnType) { 314 this.mApnType = apnType; 315 return this; 316 } 317 318 /** 319 * Sets the time at which the throttle will expire. The value is based off of 320 * {@link SystemClock#elapsedRealtime}. 321 * 322 * When setting this value, the throttle type is set to 323 * {@link ThrottleStatus#THROTTLE_TYPE_ELAPSED_TIME}. 324 * 325 * A value of {@link Long#MAX_VALUE} implies that the APN type is throttled indefinitely. 326 * 327 * @param throttleExpiryTimeMillis The elapsed time at which the throttle expires. 328 * Throws {@link IllegalArgumentException} for values less 329 * than 0. 330 * @return The same instance of the builder. 331 */ 332 @NonNull setThrottleExpiryTimeMillis( @lapsedRealtimeLong long throttleExpiryTimeMillis)333 public Builder setThrottleExpiryTimeMillis( 334 @ElapsedRealtimeLong long throttleExpiryTimeMillis) { 335 if (throttleExpiryTimeMillis >= 0) { 336 this.mThrottleExpiryTimeMillis = throttleExpiryTimeMillis; 337 this.mThrottleType = THROTTLE_TYPE_ELAPSED_TIME; 338 } else { 339 throw new IllegalArgumentException("throttleExpiryTimeMillis must be greater than " 340 + "or equal to 0"); 341 } 342 return this; 343 } 344 345 /** 346 * Sets the status of the APN type as not being throttled. 347 * 348 * When setting this value, the throttle type is set to 349 * {@link ThrottleStatus#THROTTLE_TYPE_NONE} and the expiry time is set to 350 * {@link Builder#NO_THROTTLE_EXPIRY_TIME}. 351 * 352 * @return The same instance of the builder. 353 */ 354 @SuppressLint("MissingGetterMatchingBuilder") 355 @NonNull setNoThrottle()356 public Builder setNoThrottle() { 357 mThrottleType = THROTTLE_TYPE_NONE; 358 mThrottleExpiryTimeMillis = NO_THROTTLE_EXPIRY_TIME; 359 return this; 360 } 361 362 /** 363 * Set the type of request that the framework will make the next time it retries 364 * to call {@link IDataService#setupDataCall}. 365 * 366 * @param retryType the type of request 367 * @return The same instance of the builder. 368 */ 369 @NonNull setRetryType(@etryType int retryType)370 public Builder setRetryType(@RetryType int retryType) { 371 this.mRetryType = retryType; 372 return this; 373 } 374 375 /** 376 * Build the {@link ThrottleStatus} 377 * 378 * @return the {@link ThrottleStatus} object 379 */ 380 @NonNull build()381 public ThrottleStatus build() { 382 return new ThrottleStatus( 383 mSlotIndex, 384 mTransportType, 385 mApnType, 386 mThrottleType, 387 mThrottleExpiryTimeMillis, 388 mRetryType); 389 } 390 } 391 } 392