• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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