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