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