• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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 androidx.annotation.Nullable;
8 
9 import java.time.Instant;
10 import java.util.Collection;
11 import java.util.concurrent.Executor;
12 
13 /**
14  * Information about a finished request. Passed to {@link RequestFinishedInfo.Listener}.
15  *
16  * <p>To associate the data with the original request, use {@link
17  * UrlRequest.Builder#addRequestAnnotation} to add a unique identifier when creating the
18  * request, and call {@link #getAnnotations} when the {@link RequestFinishedInfo} is received to
19  * retrieve the identifier.
20  *
21  * {@hide}
22  */
23 public abstract class RequestFinishedInfo {
24     /**
25      * Listens for finished requests for the purpose of collecting metrics.
26      *
27      * {@hide}
28      */
29     public abstract static class Listener {
30         private final Executor mExecutor;
31 
Listener(Executor executor)32         public Listener(Executor executor) {
33             if (executor == null) {
34                 throw new IllegalStateException("Executor must not be null");
35             }
36             mExecutor = executor;
37         }
38 
39         /**
40          * Invoked with request info. Will be called in a task submitted to the {@link
41          * java.util.concurrent.Executor} returned by {@link #getExecutor}.
42          *
43          * @param requestInfo {@link RequestFinishedInfo} for finished request.
44          */
onRequestFinished(RequestFinishedInfo requestInfo)45         public abstract void onRequestFinished(RequestFinishedInfo requestInfo);
46 
47         /**
48          * Returns this listener's executor. Can be called on any thread.
49          *
50          * @return this listener's {@link java.util.concurrent.Executor}
51          */
getExecutor()52         public Executor getExecutor() {
53             return mExecutor;
54         }
55     }
56 
57     /**
58      * Metrics collected for a single request. Most of these metrics are timestamps for events
59      * during the lifetime of the request, which can be used to build a detailed timeline for
60      * investigating performance.
61      *
62      * <p>Events happen in this order:
63      *
64      * <ol>
65      *   <li>{@link #getRequestStart request start}
66      *   <li>{@link #getDnsStart DNS start}
67      *   <li>{@link #getDnsEnd DNS end}
68      *   <li>{@link #getConnectStart connect start}
69      *   <li>{@link #getSslStart SSL start}
70      *   <li>{@link #getSslEnd SSL end}
71      *   <li>{@link #getConnectEnd connect end}
72      *   <li>{@link #getSendingStart sending start}
73      *   <li>{@link #getSendingEnd sending end}
74      *   <li>{@link #getResponseStart response start}
75      *   <li>{@link #getRequestEnd request end}
76      * </ol>
77      *
78      * Start times are reported as the time when a request started blocking on event, not when the
79      * event actually occurred, with the exception of push start and end. If a metric is not
80      * meaningful or not available, including cases when a request finished before reaching that
81      * stage, start and end times will be {@code null}. If no time was spent blocking on an event,
82      * start and end will be the same time.
83      *
84      * <p>If the system clock is adjusted during the request, some of the {@link java.util.Date}
85      * values might not match it. Timestamps are recorded using a clock that is guaranteed not to
86      * run backwards. All timestamps are correct relative to the system clock at the time of request
87      * start, and taking the difference between two timestamps will give the correct difference
88      * between the events. In order to preserve this property, timestamps for events other than
89      * request start are not guaranteed to match the system clock at the times they represent.
90      *
91      * <p>Most timing metrics are taken from <a
92      * href="https://cs.chromium.org/chromium/src/net/base/load_timing_info.h">LoadTimingInfo</a>,
93      * which holds the information for <a href="http://w3c.github.io/navigation-timing/"></a> and <a
94      * href="https://www.w3.org/TR/resource-timing/"></a>.
95      *
96      * <p>{@hide} as it's a prototype.
97      */
98     public abstract static class Metrics {
99         /**
100          * Returns time when the request started.
101          *
102          * @return {@link java.util.Date} representing when the native request actually started.
103          *         This
104          *     timestamp will match the system clock at the time it represents.
105          */
106         @Nullable
getRequestStart()107         public abstract Instant getRequestStart();
108 
109         /**
110          * Returns time when DNS lookup started. This and {@link #getDnsEnd} will return non-null
111          * values regardless of whether the result came from a DNS server or the local cache.
112          *
113          * @return {@link java.util.Date} representing when DNS lookup started. {@code null} if the
114          *     socket was reused (see {@link #getSocketReused}).
115          */
116         @Nullable
getDnsStart()117         public abstract Instant getDnsStart();
118 
119         /**
120          * Returns time when DNS lookup finished. This and {@link #getDnsStart} will return non-null
121          * values regardless of whether the result came from a DNS server or the local cache.
122          *
123          * @return {@link java.util.Date} representing when DNS lookup finished. {@code null} if the
124          *     socket was reused (see {@link #getSocketReused}).
125          */
126         @Nullable
getDnsEnd()127         public abstract Instant getDnsEnd();
128 
129         /**
130          * Returns time when connection establishment started.
131          *
132          * @return {@link java.util.Date} representing when connection establishment started,
133          *         typically
134          *     when DNS resolution finishes. {@code null} if the socket was reused (see {@link
135          *     #getSocketReused}).
136          */
137         @Nullable
getConnectStart()138         public abstract Instant getConnectStart();
139 
140         /**
141          * Returns time when connection establishment finished.
142          *
143          * @return {@link java.util.Date} representing when connection establishment finished, after
144          *         TCP
145          *     connection is established and, if using HTTPS, SSL handshake is completed. For QUIC
146          *     0-RTT, this represents the time of handshake confirmation and might happen later than
147          *     {@link #getSendingStart}. {@code null} if the socket was reused (see {@link
148          *     #getSocketReused}).
149          */
150         @Nullable
getConnectEnd()151         public abstract Instant getConnectEnd();
152 
153         /**
154          * Returns time when SSL handshake started. For QUIC, this will be the same time as {@link
155          * #getConnectStart}.
156          *
157          * @return {@link java.util.Date} representing when SSL handshake started. {@code null} if
158          *         SSL
159          *     is not used or if the socket was reused (see {@link #getSocketReused}).
160          */
161         @Nullable
getSslStart()162         public abstract Instant getSslStart();
163 
164         /**
165          * Returns time when SSL handshake finished. For QUIC, this will be the same time as {@link
166          * #getConnectEnd}.
167          *
168          * @return {@link java.util.Date} representing when SSL handshake finished. {@code null} if
169          *         SSL
170          *     is not used or if the socket was reused (see {@link #getSocketReused}).
171          */
172         @Nullable
getSslEnd()173         public abstract Instant getSslEnd();
174 
175         /**
176          * Returns time when sending the request started.
177          *
178          * @return {@link java.util.Date} representing when sending HTTP request headers started.
179          */
180         @Nullable
getSendingStart()181         public abstract Instant getSendingStart();
182 
183         /**
184          * Returns time when sending the request finished.
185          *
186          * @return {@link java.util.Date} representing when sending HTTP request body finished.
187          *         (Sending
188          *     request body happens after sending request headers.)
189          */
190         @Nullable
getSendingEnd()191         public abstract Instant getSendingEnd();
192 
193         /**
194          * Returns time when first byte of HTTP/2 server push was received.
195          *
196          * @return {@link java.util.Date} representing when the first byte of an HTTP/2 server push
197          *         was
198          *     received. {@code null} if server push is not used.
199          */
200         @Nullable
getPushStart()201         public abstract Instant getPushStart();
202 
203         /**
204          * Returns time when last byte of HTTP/2 server push was received.
205          *
206          * @return {@link java.util.Date} representing when the last byte of an HTTP/2 server push
207          *         was
208          *     received. {@code null} if server push is not used.
209          */
210         @Nullable
getPushEnd()211         public abstract Instant getPushEnd();
212 
213         /**
214          * Returns time when the end of the response headers was received.
215          *
216          * @return {@link java.util.Date} representing when the end of the response headers was
217          *     received.
218          */
219         @Nullable
getResponseStart()220         public abstract Instant getResponseStart();
221 
222         /**
223          * Returns time when the request finished.
224          *
225          * @return {@link java.util.Date} representing when the request finished.
226          */
227         @Nullable
getRequestEnd()228         public abstract Instant getRequestEnd();
229 
230         /**
231          * Returns whether the socket was reused from a previous request. In HTTP/2 or QUIC, if
232          * streams are multiplexed in a single connection, returns {@code true} for all streams
233          * after the first.
234          *
235          * @return whether this request reused a socket from a previous request. When {@code true},
236          *         DNS,
237          *     connection, and SSL times will be {@code null}.
238          */
getSocketReused()239         public abstract boolean getSocketReused();
240 
241         /**
242          * Returns total bytes sent over the network transport layer, or {@code null} if not
243          * collected.
244          */
245         @Nullable
getSentByteCount()246         public abstract Long getSentByteCount();
247 
248         /**
249          * Returns total bytes received over the network transport layer, or {@code null} if not
250          * collected. Number of bytes does not include any previous redirects.
251          */
252         @Nullable
getReceivedByteCount()253         public abstract Long getReceivedByteCount();
254     }
255 
256     /**
257      * Reason value indicating that the request succeeded. Returned from {@link #getFinishedReason}.
258      */
259     public static final int SUCCEEDED = 0;
260     /**
261      * Reason value indicating that the request failed or returned an error. Returned from {@link
262      * #getFinishedReason}.
263      */
264     public static final int FAILED = 1;
265     /**
266      * Reason value indicating that the request was canceled. Returned from {@link
267      * #getFinishedReason}.
268      */
269     public static final int CANCELED = 2;
270 
271     /**
272      * Returns the request's original URL.
273      *
274      * @return the request's original URL
275      */
getUrl()276     public abstract String getUrl();
277 
278     /**
279      * Returns the objects that the caller has supplied when initiating the request, using {@link
280      * UrlRequest.Builder#addRequestAnnotation}. Annotations can be used to associate a
281      * {@link RequestFinishedInfo} with the original request or type of request.
282      *
283      * @return annotations supplied when creating the request
284      */
getAnnotations()285     public abstract Collection<Object> getAnnotations();
286 
287     // TODO(klm): Collect and return a chain of Metrics objects for redirect responses.
288     // TODO(mgersh): Update this javadoc when new metrics are fully implemented
289 
290     /**
291      * Returns metrics collected for this request.
292      *
293      * <p>The reported times and bytes account for all redirects, i.e.
294      * the TTFB is from the start of the original request to the ultimate response headers, the TTLB
295      * is from the start of the original request to the end of the ultimate response, the received
296      * byte count is for all redirects and the ultimate response combined. These cumulative metric
297      * definitions are debatable, but are chosen to make sense for user-facing latency analysis.
298      *
299      * @return metrics collected for this request.
300      *
301      * <p>{@hide} as the Metrics class is hidden
302      */
getMetrics()303     public abstract Metrics getMetrics();
304 
305     /**
306      * Returns the reason why the request finished.
307      *
308      * @return one of {@link #SUCCEEDED}, {@link #FAILED}, or {@link #CANCELED}
309      */
getFinishedReason()310     public abstract int getFinishedReason();
311 
312     /**
313      * Returns a {@link UrlResponseInfo} for the request, if its response had started.
314      *
315      * @return {@link UrlResponseInfo} for the request, if its response had started.
316      */
317     @Nullable
getResponseInfo()318     public abstract UrlResponseInfo getResponseInfo();
319 
320     /**
321      * If the request failed, returns the same {@link HttpException} provided to
322      * {@link UrlRequest.Callback#onFailed}.
323      *
324      * @return the request's {@link HttpException}, if the request failed
325      */
326     @Nullable
getException()327     public abstract HttpException getException();
328 }
329