1 // Copyright 2014 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package android.net.http; 6 7 import android.annotation.IntDef; 8 import android.annotation.SuppressLint; 9 import android.net.Network; 10 11 import androidx.annotation.NonNull; 12 import androidx.annotation.Nullable; 13 14 import java.lang.annotation.Retention; 15 import java.lang.annotation.RetentionPolicy; 16 import java.nio.ByteBuffer; 17 import java.util.List; 18 import java.util.Map; 19 import java.util.concurrent.Executor; 20 21 /** 22 * Controls an HTTP request (GET, PUT, POST etc). 23 * Created by {@link UrlRequest.Builder}, which can be obtained by calling 24 * {@link HttpEngine#newUrlRequestBuilder}. 25 * Note: All methods must be called on the {@link Executor} passed to 26 * {@link HttpEngine#newUrlRequestBuilder}. 27 */ 28 public abstract class UrlRequest { 29 UrlRequest()30 UrlRequest() {} 31 32 /** 33 * Lowest request priority. Passed to {@link Builder#setPriority}. 34 */ 35 public static final int REQUEST_PRIORITY_IDLE = 0; 36 /** 37 * Very low request priority. Passed to {@link Builder#setPriority}. 38 */ 39 public static final int REQUEST_PRIORITY_LOWEST = 1; 40 /** 41 * Low request priority. Passed to {@link Builder#setPriority}. 42 */ 43 public static final int REQUEST_PRIORITY_LOW = 2; 44 /** 45 * Medium request priority. Passed to {@link Builder#setPriority}. This is the 46 * default priority given to the request. 47 */ 48 public static final int REQUEST_PRIORITY_MEDIUM = 3; 49 /** 50 * Highest request priority. Passed to {@link Builder#setPriority}. 51 */ 52 public static final int REQUEST_PRIORITY_HIGHEST = 4; 53 54 /** 55 * Builder for {@link UrlRequest}s. Allows configuring requests before constructing them 56 * with {@link Builder#build}. The builder can be created by calling 57 * {@link HttpEngine#newUrlRequestBuilder}. 58 */ 59 // SuppressLint: Builder can not be final since this is abstract and inherited 60 // e.g. ExperimentalUrlRequest.Builder 61 @SuppressLint("StaticFinalBuilder") 62 public abstract static class Builder { 63 Builder()64 Builder() {} 65 66 /** 67 * Sets the HTTP method verb to use for this request. 68 * 69 * <p>The default when this method is not called is "GET" if the request has 70 * no body or "POST" if it does. 71 * 72 * @param method "GET", "HEAD", "DELETE", "POST" or "PUT". 73 * @return the builder to facilitate chaining. 74 */ 75 @NonNull setHttpMethod(@onNull String method)76 public abstract Builder setHttpMethod(@NonNull String method); 77 78 /** 79 * Adds a request header. 80 * 81 * @param header header name. 82 * @param value header value. 83 * @return the builder to facilitate chaining. 84 */ 85 @NonNull addHeader(@onNull String header, @NonNull String value)86 public abstract Builder addHeader(@NonNull String header, @NonNull String value); 87 88 /** 89 * Whether to disable cache for the request. If the engine is not set up to use cache, 90 * this call has no effect. 91 * @param disableCache {@code true} to disable cache, {@code false} otherwise. 92 * @return the builder to facilitate chaining. 93 */ 94 @NonNull setCacheDisabled(boolean disableCache)95 public abstract Builder setCacheDisabled(boolean disableCache); 96 97 /** 98 * Sets priority of the request which should be one of the {@link #REQUEST_PRIORITY_IDLE 99 * REQUEST_PRIORITY_*} values. The request is given {@link #REQUEST_PRIORITY_MEDIUM} 100 * priority if this method is not called. 101 * 102 * @param priority priority of the request which should be one of the {@link 103 * #REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*} values. 104 * @return the builder to facilitate chaining. 105 */ 106 @NonNull setPriority(int priority)107 public abstract Builder setPriority(int priority); 108 109 /** 110 * Sets upload data provider. Switches method to "POST" if not explicitly set. Starting the 111 * request will throw an exception if a Content-Type header is not set. 112 * 113 * @param uploadDataProvider responsible for providing the upload data. 114 * @param executor All {@code uploadDataProvider} methods will be invoked using this {@code 115 * Executor}. May optionally be the same {@code Executor} the request itself is using. 116 * @return the builder to facilitate chaining. 117 */ 118 // SuppressLint: UploadDataProvider is wrapped by other classes after set. 119 // Also, UploadDataProvider is a class to provide an upload body and getter is not useful 120 @NonNull @SuppressLint("MissingGetterMatchingBuilder") setUploadDataProvider( @onNull UploadDataProvider uploadDataProvider, @NonNull Executor executor)121 public abstract Builder setUploadDataProvider( 122 @NonNull UploadDataProvider uploadDataProvider, @NonNull Executor executor); 123 124 /** 125 * Marks whether the executors this request will use to notify callbacks (for 126 * {@code UploadDataProvider}s and {@code UrlRequest.Callback}s) is intentionally performing 127 * inline execution, like Guava's directExecutor or 128 * {@link java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy}. 129 * 130 * <p><b>Warning:</b> If set to true: This option makes it easy to accidentally block the 131 * network thread. This should not be done if your callbacks perform disk I/O, acquire 132 * locks, or call into other code you don't carefully control and audit. 133 * 134 * @param allowDirectExecutor {@code true} to allow executors performing inline execution, 135 * {@code false} otherwise. 136 * @return the builder to facilitate chaining. 137 */ 138 @NonNull setDirectExecutorAllowed(boolean allowDirectExecutor)139 public abstract Builder setDirectExecutorAllowed(boolean allowDirectExecutor); 140 141 /** 142 * Binds the request to the specified network. The HTTP stack will send this request 143 * only using the network associated to this handle. If this network disconnects the request 144 * will fail, the exact error will depend on the stage of request processing when 145 * the network disconnects. 146 * 147 * @param network the network to bind the request to. Specify {@code null} to unbind. 148 * @return the builder to facilitate chaining. 149 */ 150 @NonNull @SuppressLint("BuilderSetStyle") bindToNetwork(@ullable Network network)151 public abstract Builder bindToNetwork(@Nullable Network network); 152 153 /** 154 * Sets {@link android.net.TrafficStats} tag to use when accounting socket traffic caused by 155 * this request. See {@link android.net.TrafficStats} for more information. If no tag is 156 * set (e.g. this method isn't called), then Android accounts for the socket traffic caused 157 * by this request as if the tag value were set to 0. 158 * <p> 159 * <b>NOTE:</b>Setting a tag disallows sharing of sockets with requests 160 * with other tags, which may adversely effect performance by prohibiting 161 * connection sharing. In other words use of multiplexed sockets (e.g. HTTP/2 162 * and QUIC) will only be allowed if all requests have the same socket tag. 163 * 164 * @param tag the tag value used to when accounting for socket traffic caused by this 165 * request. Tags between 0xFFFFFF00 and 0xFFFFFFFF are reserved and used 166 * internally by system services like {@link android.app.DownloadManager} when 167 * performing traffic on behalf of an application. 168 * @return the builder to facilitate chaining. 169 */ 170 @NonNull setTrafficStatsTag(int tag)171 public abstract Builder setTrafficStatsTag(int tag); 172 173 /** 174 * Sets specific UID to use when accounting socket traffic caused by this request. See 175 * {@link android.net.TrafficStats} for more information. Designed for use when performing 176 * an operation on behalf of another application. Caller must hold 177 * {@link android.Manifest.permission#MODIFY_NETWORK_ACCOUNTING} permission. By default 178 * traffic is attributed to UID of caller. 179 * <p> 180 * <b>NOTE:</b>Setting a UID disallows sharing of sockets with requests 181 * with other UIDs, which may adversely effect performance by prohibiting 182 * connection sharing. In other words use of multiplexed sockets (e.g. HTTP/2 183 * and QUIC) will only be allowed if all requests have the same UID set. 184 * 185 * @param uid the UID to attribute socket traffic caused by this request. 186 * @return the builder to facilitate chaining. 187 */ 188 @NonNull setTrafficStatsUid(int uid)189 public abstract Builder setTrafficStatsUid(int uid); 190 191 /** 192 * Associates the annotation object with this request. May add more than one. Passed through 193 * to a {@link RequestFinishedInfo.Listener}, see {@link 194 * RequestFinishedInfo#getAnnotations}. 195 * 196 * @param annotation an object to pass on to the {@link RequestFinishedInfo.Listener} with a 197 * {@link RequestFinishedInfo}. 198 * @return the builder to facilitate chaining. 199 * 200 * {@hide} 201 */ addRequestAnnotation(Object annotation)202 public Builder addRequestAnnotation(Object annotation) { 203 return this; 204 } 205 206 /** 207 * Sets a listener that gets invoked after {@link Callback#onCanceled onCanceled()}, {@link 208 * Callback#onFailed onFailed()} or {@link Callback#onSucceeded onSucceeded()} return. 209 * 210 * <p>The listener is invoked with the request finished info on an 211 * {@link java.util.concurrent.Executor} provided by {@link 212 * RequestFinishedInfo.Listener#getExecutor getExecutor()}. 213 * 214 * @param listener the listener for finished requests. 215 * @return the builder to facilitate chaining. 216 * 217 * {@hide} 218 */ setRequestFinishedListener(RequestFinishedInfo.Listener listener)219 public Builder setRequestFinishedListener(RequestFinishedInfo.Listener listener) { 220 return this; 221 } 222 223 /** 224 * Creates a {@link UrlRequest} using configuration within this {@link Builder}. The 225 * returned 226 * {@code UrlRequest} can then be started by calling {@link UrlRequest#start}. 227 * 228 * @return constructed {@link UrlRequest} using configuration within this {@link Builder}. 229 */ 230 @NonNull build()231 public abstract UrlRequest build(); 232 } 233 234 /** 235 * Users of the HTTP stack extend this class to receive callbacks indicating the 236 * progress of a {@link UrlRequest} being processed. An instance of this class 237 * is passed in to {@link UrlRequest.Builder}'s constructor when 238 * constructing the {@code UrlRequest}. 239 * <p> 240 * Note: All methods will be invoked on the thread of the {@link java.util.concurrent.Executor} 241 * used during construction of the {@code UrlRequest}. 242 */ 243 public interface Callback { 244 /** 245 * Invoked whenever a redirect is encountered. This will only be invoked between the call to 246 * {@link UrlRequest#start} and {@link Callback#onResponseStarted onResponseStarted()}. The 247 * body of the redirect response, if it has one, will be ignored. 248 * 249 * The redirect will not be followed until the URLRequest's {@link 250 * UrlRequest#followRedirect} method is called, either synchronously or asynchronously. 251 * 252 * @param request Request being redirected. 253 * @param info Response information. 254 * @param newLocationUrl Location where request is redirected. 255 * @throws Exception if an error occurs while processing a redirect. {@link #onFailed} will 256 * be 257 * called with the thrown exception set as the cause of the {@link CallbackException}. 258 */ 259 // SuppressLint: Exception will be wrapped and passed to #onFailed, see above javadoc 260 @SuppressLint("GenericException") onRedirectReceived(@onNull UrlRequest request, @NonNull UrlResponseInfo info, @NonNull String newLocationUrl)261 void onRedirectReceived(@NonNull UrlRequest request, 262 @NonNull UrlResponseInfo info, @NonNull String newLocationUrl) throws Exception; 263 264 /** 265 * Invoked when the final set of headers, after all redirects, is received. Will only be 266 * invoked once for each request. 267 * 268 * With the exception of {@link Callback#onCanceled onCanceled()}, no other {@link Callback} 269 * method will be invoked for the request, including {@link Callback#onSucceeded 270 * onSucceeded()} and {@link Callback#onFailed onFailed()}, until {@link UrlRequest#read 271 * UrlRequest.read()} is called to attempt to start reading the response body. 272 * 273 * @param request Request that started to get response. 274 * @param info Response information. 275 * @throws Exception if an error occurs while processing response start. {@link #onFailed} 276 * will 277 * be called with the thrown exception set as the cause of the {@link CallbackException}. 278 */ 279 // SuppressLint: Exception will be wrapped and passed to #onFailed, see above javadoc 280 @SuppressLint("GenericException") onResponseStarted(@onNull UrlRequest request, @NonNull UrlResponseInfo info)281 void onResponseStarted(@NonNull UrlRequest request, 282 @NonNull UrlResponseInfo info) throws Exception; 283 284 /** 285 * Invoked whenever part of the response body has been read. Only part of the buffer may be 286 * populated, even if the entire response body has not yet been consumed. 287 * 288 * With the exception of {@link Callback#onCanceled onCanceled()}, no other {@link Callback} 289 * method will be invoked for the request, including {@link Callback#onSucceeded 290 * onSucceeded()} and {@link Callback#onFailed onFailed()}, until {@link UrlRequest#read 291 * UrlRequest.read()} is called to attempt to continue reading the response body. 292 * 293 * @param request Request that received data. 294 * @param info Response information. 295 * @param byteBuffer The buffer that was passed in to {@link UrlRequest#read 296 * UrlRequest.read()}, 297 * now containing the received data. The buffer's position is updated to the end of the 298 * received data. The buffer's limit is not changed. 299 * @throws Exception if an error occurs while processing a read completion. {@link 300 * #onFailed} 301 * will be called with the thrown exception set as the cause of the {@link 302 * CallbackException}. 303 */ 304 // SuppressLint: Exception will be wrapped and passed to #onFailed, see above javadoc 305 @SuppressLint("GenericException") onReadCompleted(@onNull UrlRequest request, @NonNull UrlResponseInfo info, @NonNull ByteBuffer byteBuffer)306 void onReadCompleted(@NonNull UrlRequest request, 307 @NonNull UrlResponseInfo info, @NonNull ByteBuffer byteBuffer) throws Exception; 308 309 /** 310 * Invoked when request is completed successfully. Once invoked, no other {@link Callback} 311 * methods will be invoked. 312 * 313 * @param request Request that succeeded. 314 * @param info Response information. 315 */ onSucceeded( @onNull UrlRequest request, @NonNull UrlResponseInfo info)316 void onSucceeded( 317 @NonNull UrlRequest request, @NonNull UrlResponseInfo info); 318 319 /** 320 * Invoked if request failed for any reason after {@link UrlRequest#start}. Once invoked, no 321 * other {@link Callback} methods will be invoked. {@code error} provides information about 322 * the failure. 323 * 324 * @param request Request that failed. 325 * @param info Response information. May be {@code null} if no response was received. 326 * @param error information about error. 327 */ onFailed(@onNull UrlRequest request, @Nullable UrlResponseInfo info, @NonNull HttpException error)328 void onFailed(@NonNull UrlRequest request, 329 @Nullable UrlResponseInfo info, @NonNull HttpException error); 330 331 /** 332 * Invoked if request was canceled via {@link UrlRequest#cancel}. Once invoked, no other 333 * {@link Callback} methods will be invoked. Default implementation takes no action. 334 * 335 * @param request Request that was canceled. 336 * @param info Response information. May be {@code null} if no response was received. 337 */ onCanceled(@onNull UrlRequest request, @Nullable UrlResponseInfo info)338 void onCanceled(@NonNull UrlRequest request, @Nullable UrlResponseInfo info); 339 } 340 341 /** @hide */ 342 @Retention(RetentionPolicy.SOURCE) 343 @IntDef({ 344 Status.INVALID, 345 Status.IDLE, 346 Status.WAITING_FOR_STALLED_SOCKET_POOL, 347 Status.WAITING_FOR_AVAILABLE_SOCKET, 348 Status.WAITING_FOR_DELEGATE, 349 Status.WAITING_FOR_CACHE, 350 Status.DOWNLOADING_PAC_FILE, 351 Status.RESOLVING_PROXY_FOR_URL, 352 Status.RESOLVING_PROXY_FOR_URL, 353 Status.RESOLVING_HOST_IN_PAC_FILE, 354 Status.ESTABLISHING_PROXY_TUNNEL, 355 Status.RESOLVING_HOST, 356 Status.CONNECTING, 357 Status.SSL_HANDSHAKE, 358 Status.SENDING_REQUEST, 359 Status.WAITING_FOR_RESPONSE, 360 Status.READING_RESPONSE}) 361 public @interface UrlRequestStatus {} 362 363 /** 364 * Request status values returned by {@link #getStatus}. 365 */ 366 public static class Status { 367 /** 368 * This state indicates that the request is completed, canceled, or is not started. 369 */ 370 public static final int INVALID = -1; 371 /** 372 * This state corresponds to a resource load that has either not yet begun or is idle 373 * waiting for the consumer to do something to move things along (e.g. when the consumer of 374 * a {@link UrlRequest} has not called {@link UrlRequest#read read()} yet). 375 */ 376 public static final int IDLE = 0; 377 /** 378 * When a socket pool group is below the maximum number of sockets allowed per group, but a 379 * new socket cannot be created due to the per-pool socket limit, this state is returned by 380 * all requests for the group waiting on an idle connection, except those that may be 381 * serviced by a pending new connection. 382 */ 383 public static final int WAITING_FOR_STALLED_SOCKET_POOL = 1; 384 /** 385 * When a socket pool group has reached the maximum number of sockets allowed per group, 386 * this state is returned for all requests that don't have a socket, except those that 387 * correspond to a pending new connection. 388 */ 389 public static final int WAITING_FOR_AVAILABLE_SOCKET = 2; 390 /** 391 * This state indicates that the URLRequest delegate has chosen to block this request before 392 * it was sent over the network. 393 */ 394 public static final int WAITING_FOR_DELEGATE = 3; 395 /** 396 * This state corresponds to a resource load that is blocked waiting for access to a 397 * resource in the cache. If multiple requests are made for the same resource, the first 398 * request will be responsible for writing (or updating) the cache entry and the second 399 * request will be deferred until the first completes. This may be done to optimize for 400 * cache reuse. 401 */ 402 public static final int WAITING_FOR_CACHE = 4; 403 /** 404 * This state corresponds to a resource being blocked waiting for the PAC script to be 405 * downloaded. 406 */ 407 public static final int DOWNLOADING_PAC_FILE = 5; 408 /** 409 * This state corresponds to a resource load that is blocked waiting for a proxy autoconfig 410 * script to return a proxy server to use. 411 */ 412 public static final int RESOLVING_PROXY_FOR_URL = 6; 413 /** 414 * This state corresponds to a resource load that is blocked waiting for a proxy autoconfig 415 * script to return a proxy server to use, but that proxy script is busy resolving the IP 416 * address of a host. 417 */ 418 public static final int RESOLVING_HOST_IN_PAC_FILE = 7; 419 /** 420 * This state indicates that we're in the process of establishing a tunnel through the proxy 421 * server. 422 */ 423 public static final int ESTABLISHING_PROXY_TUNNEL = 8; 424 /** 425 * This state corresponds to a resource load that is blocked waiting for a host name to be 426 * resolved. This could either indicate resolution of the origin server corresponding to the 427 * resource or to the host name of a proxy server used to fetch the resource. 428 */ 429 public static final int RESOLVING_HOST = 9; 430 /** 431 * This state corresponds to a resource load that is blocked waiting for a TCP connection 432 * (or other network connection) to be established. HTTP requests that reuse a keep-alive 433 * connection skip this state. 434 */ 435 public static final int CONNECTING = 10; 436 /** 437 * This state corresponds to a resource load that is blocked waiting for the SSL handshake 438 * to complete. 439 */ 440 public static final int SSL_HANDSHAKE = 11; 441 /** 442 * This state corresponds to a resource load that is blocked waiting to completely upload a 443 * request to a server. In the case of a HTTP POST request, this state includes the period 444 * of time during which the message body is being uploaded. 445 */ 446 public static final int SENDING_REQUEST = 12; 447 /** 448 * This state corresponds to a resource load that is blocked waiting for the response to a 449 * network request. In the case of a HTTP transaction, this corresponds to the period after 450 * the request is sent and before all of the response headers have been received. 451 */ 452 public static final int WAITING_FOR_RESPONSE = 13; 453 /** 454 * This state corresponds to a resource load that is blocked waiting for a read to complete. 455 * In the case of a HTTP transaction, this corresponds to the period after the response 456 * headers have been received and before all of the response body has been downloaded. 457 * (NOTE: This state only applies for an {@link UrlRequest} while there is an outstanding 458 * {@link UrlRequest#read read()} operation.) 459 */ 460 public static final int READING_RESPONSE = 14; 461 Status()462 private Status() {} 463 } 464 465 /** 466 * Listener interface used with {@link #getStatus} to receive the status of a 467 * {@link UrlRequest}. 468 */ 469 public interface StatusListener { 470 /** 471 * Invoked on {@link UrlRequest}'s {@link Executor}'s thread when request status is 472 * obtained. 473 * 474 * @param status integer representing the status of the request. It is one of the values 475 * defined 476 * in {@link Status}. 477 */ onStatus(@rlRequestStatus int status)478 void onStatus(@UrlRequestStatus int status); 479 } 480 481 /** 482 * See {@link UrlRequest.Builder#setHttpMethod(String)}. 483 */ 484 @Nullable getHttpMethod()485 public abstract String getHttpMethod(); 486 487 /** 488 * See {@link UrlRequest.Builder#addHeader(String, String)} 489 */ 490 @NonNull getHeaders()491 public abstract HeaderBlock getHeaders(); 492 493 /** 494 * See {@link Builder#setCacheDisabled(boolean)} 495 */ isCacheDisabled()496 public abstract boolean isCacheDisabled(); 497 498 /** 499 * See {@link UrlRequest.Builder#setDirectExecutorAllowed(boolean)} 500 */ isDirectExecutorAllowed()501 public abstract boolean isDirectExecutorAllowed(); 502 503 /** 504 * See {@link Builder#setPriority(int)} 505 */ getPriority()506 public abstract int getPriority(); 507 508 /** 509 * See {@link Builder#setTrafficStatsTag(int)} 510 */ hasTrafficStatsTag()511 public abstract boolean hasTrafficStatsTag(); 512 513 /** 514 * See {@link Builder#setTrafficStatsTag(int)} 515 */ getTrafficStatsTag()516 public abstract int getTrafficStatsTag(); 517 518 /** 519 * See {@link Builder#setTrafficStatsUid(int)} 520 */ hasTrafficStatsUid()521 public abstract boolean hasTrafficStatsUid(); 522 523 /** 524 * See {@link Builder#setTrafficStatsUid(int)} 525 */ getTrafficStatsUid()526 public abstract int getTrafficStatsUid(); 527 528 /** 529 * Starts the request, all callbacks go to {@link Callback}. May only be called 530 * once. May not be called if {@link #cancel} has been called. 531 */ start()532 public abstract void start(); 533 534 /** 535 * Follows a pending redirect. Must only be called at most once for each invocation of {@link 536 * Callback#onRedirectReceived onRedirectReceived()}. 537 */ followRedirect()538 public abstract void followRedirect(); 539 540 /** 541 * Attempts to read part of the response body into the provided buffer. Must only be called at 542 * most once in response to each invocation of the {@link Callback#onResponseStarted 543 * onResponseStarted()} and {@link Callback#onReadCompleted onReadCompleted()} methods of the 544 * {@link Callback}. Each call will result in an asynchronous call to either the {@link Callback 545 * Callback's} {@link Callback#onReadCompleted onReadCompleted()} method if data is read, its 546 * {@link Callback#onSucceeded onSucceeded()} method if there's no more data to read, or its 547 * {@link Callback#onFailed onFailed()} method if there's an error. 548 * 549 * @param buffer {@link ByteBuffer} to write response body to. Must be a direct ByteBuffer. The 550 * embedder must not read or modify buffer's position, limit, or data between its position and 551 * limit until the request calls back into the {@link Callback}. 552 */ read(@onNull ByteBuffer buffer)553 public abstract void read(@NonNull ByteBuffer buffer); 554 555 /** 556 * Cancels the request. Can be called at any time. {@link Callback#onCanceled onCanceled()} will 557 * be invoked when cancellation is complete and no further callback methods will be invoked. If 558 * the request has completed or has not started, calling {@code cancel()} has no effect and 559 * {@code onCanceled()} will not be invoked. If the {@link Executor} passed in during {@code 560 * UrlRequest} construction runs tasks on a single thread, and {@code cancel()} is called on 561 * that thread, no callback methods (besides {@code onCanceled()}) will be invoked after {@code 562 * cancel()} is called. Otherwise, at most one callback method may be invoked after {@code 563 * cancel()} has completed. 564 */ cancel()565 public abstract void cancel(); 566 567 /** 568 * Returns {@code true} if the request was successfully started and is now finished (completed, 569 * canceled, or failed). 570 * 571 * @return {@code true} if the request was successfully started and is now finished (completed, 572 * canceled, or failed). 573 */ isDone()574 public abstract boolean isDone(); 575 576 /** 577 * Queries the status of the request. 578 * 579 * <p>This is most useful to query the status of the request before any of the 580 * {@link UrlRequest.Callback} methods are called by Cronet. 581 * 582 * <p>The {@code listener} will be invoked back on the {@link Executor} passed in when 583 * the request was created. While you can assume the callback will be invoked in a timely 584 * fashion, the API doesn't make any guarantees about the latency, nor does it specify the 585 * order in which the listener and other callbacks will be invoked. 586 * 587 * @param listener a {@link StatusListener} that will be invoked with 588 * the request's current status. 589 */ 590 // SuppressLint: The listener will be invoked back on the Executor passed in when the request 591 // was created. 592 @SuppressLint("ExecutorRegistration") getStatus(@onNull final StatusListener listener)593 public abstract void getStatus(@NonNull final StatusListener listener); 594 595 // Note: There are deliberately no accessors for the results of the request 596 // here. Having none removes any ambiguity over when they are populated, 597 // particularly in the redirect case. 598 } 599