blob: 065c0464c74e78a862c84b8833f8cb82d74c134c [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.net;
import androidx.annotation.Nullable;
import java.util.Collection;
import java.util.Date;
import java.util.concurrent.Executor;
/**
* Information about a finished request. Passed to {@link RequestFinishedInfo.Listener}.
*
* <p>To associate the data with the original request, use {@link
* UrlRequest.Builder#addRequestAnnotation} to add a unique identifier when creating the
* request, and call {@link #getAnnotations} when the {@link RequestFinishedInfo} is received to
* retrieve the identifier.
*/
public abstract class RequestFinishedInfo {
/** Listens for finished requests for the purpose of collecting metrics. */
public abstract static class Listener {
private final Executor mExecutor;
public Listener(Executor executor) {
if (executor == null) {
throw new IllegalStateException("Executor must not be null");
}
mExecutor = executor;
}
/**
* Invoked with request info. Will be called in a task submitted to the {@link
* java.util.concurrent.Executor} returned by {@link #getExecutor}.
*
* @param requestInfo {@link RequestFinishedInfo} for finished request.
*/
public abstract void onRequestFinished(RequestFinishedInfo requestInfo);
/**
* Returns this listener's executor. Can be called on any thread.
*
* @return this listener's {@link java.util.concurrent.Executor}
*/
public Executor getExecutor() {
return mExecutor;
}
}
/**
* Metrics collected for a single request. Most of these metrics are timestamps for events
* during the lifetime of the request, which can be used to build a detailed timeline for
* investigating performance.
*
* <p>Events happen in this order:
*
* <ol>
* <li>{@link #getRequestStart request start}
* <li>{@link #getDnsStart DNS start}
* <li>{@link #getDnsEnd DNS end}
* <li>{@link #getConnectStart connect start}
* <li>{@link #getSslStart SSL start}
* <li>{@link #getSslEnd SSL end}
* <li>{@link #getConnectEnd connect end}
* <li>{@link #getSendingStart sending start}
* <li>{@link #getSendingEnd sending end}
* <li>{@link #getResponseStart response start}
* <li>{@link #getRequestEnd request end}
* </ol>
*
* Start times are reported as the time when a request started blocking on event, not when the
* event actually occurred, with the exception of push start and end. If a metric is not
* meaningful or not available, including cases when a request finished before reaching that
* stage, start and end times will be {@code null}. If no time was spent blocking on an event,
* start and end will be the same time.
*
* <p>If the system clock is adjusted during the request, some of the {@link java.util.Date}
* values might not match it. Timestamps are recorded using a clock that is guaranteed not to
* run backwards. All timestamps are correct relative to the system clock at the time of request
* start, and taking the difference between two timestamps will give the correct difference
* between the events. In order to preserve this property, timestamps for events other than
* request start are not guaranteed to match the system clock at the times they represent.
*
* <p>Most timing metrics are taken from <a
* href="https://cs.chromium.org/chromium/src/net/base/load_timing_info.h">LoadTimingInfo</a>,
* which holds the information for <a href="http://w3c.github.io/navigation-timing/"></a> and <a
* href="https://www.w3.org/TR/resource-timing/"></a>.
*
* <p>{@hide} as it's a prototype.
*/
public abstract static class Metrics {
/**
* Returns time when the request started.
*
* @return {@link java.util.Date} representing when the native request actually started.
* This
* timestamp will match the system clock at the time it represents.
*/
@Nullable
public abstract Date getRequestStart();
/**
* Returns time when DNS lookup started. This and {@link #getDnsEnd} will return non-null
* values regardless of whether the result came from a DNS server or the local cache.
*
* @return {@link java.util.Date} representing when DNS lookup started. {@code null} if the
* socket was reused (see {@link #getSocketReused}).
*/
@Nullable
public abstract Date getDnsStart();
/**
* Returns time when DNS lookup finished. This and {@link #getDnsStart} will return non-null
* values regardless of whether the result came from a DNS server or the local cache.
*
* @return {@link java.util.Date} representing when DNS lookup finished. {@code null} if the
* socket was reused (see {@link #getSocketReused}).
*/
@Nullable
public abstract Date getDnsEnd();
/**
* Returns time when connection establishment started.
*
* @return {@link java.util.Date} representing when connection establishment started,
* typically
* when DNS resolution finishes. {@code null} if the socket was reused (see {@link
* #getSocketReused}).
*/
@Nullable
public abstract Date getConnectStart();
/**
* Returns time when connection establishment finished.
*
* @return {@link java.util.Date} representing when connection establishment finished, after
* TCP
* connection is established and, if using HTTPS, SSL handshake is completed. For QUIC
* 0-RTT, this represents the time of handshake confirmation and might happen later than
* {@link #getSendingStart}. {@code null} if the socket was reused (see {@link
* #getSocketReused}).
*/
@Nullable
public abstract Date getConnectEnd();
/**
* Returns time when SSL handshake started. For QUIC, this will be the same time as {@link
* #getConnectStart}.
*
* @return {@link java.util.Date} representing when SSL handshake started. {@code null} if
* SSL
* is not used or if the socket was reused (see {@link #getSocketReused}).
*/
@Nullable
public abstract Date getSslStart();
/**
* Returns time when SSL handshake finished. For QUIC, this will be the same time as {@link
* #getConnectEnd}.
*
* @return {@link java.util.Date} representing when SSL handshake finished. {@code null} if
* SSL
* is not used or if the socket was reused (see {@link #getSocketReused}).
*/
@Nullable
public abstract Date getSslEnd();
/**
* Returns time when sending the request started.
*
* @return {@link java.util.Date} representing when sending HTTP request headers started.
*/
@Nullable
public abstract Date getSendingStart();
/**
* Returns time when sending the request finished.
*
* @return {@link java.util.Date} representing when sending HTTP request body finished.
* (Sending
* request body happens after sending request headers.)
*/
@Nullable
public abstract Date getSendingEnd();
/**
* Returns time when first byte of HTTP/2 server push was received.
*
* @return {@link java.util.Date} representing when the first byte of an HTTP/2 server push
* was
* received. {@code null} if server push is not used.
*/
@Nullable
public abstract Date getPushStart();
/**
* Returns time when last byte of HTTP/2 server push was received.
*
* @return {@link java.util.Date} representing when the last byte of an HTTP/2 server push
* was
* received. {@code null} if server push is not used.
*/
@Nullable
public abstract Date getPushEnd();
/**
* Returns time when the end of the response headers was received.
*
* @return {@link java.util.Date} representing when the end of the response headers was
* received.
*/
@Nullable
public abstract Date getResponseStart();
/**
* Returns time when the request finished.
*
* @return {@link java.util.Date} representing when the request finished.
*/
@Nullable
public abstract Date getRequestEnd();
/**
* Returns whether the socket was reused from a previous request. In HTTP/2 or QUIC, if
* streams are multiplexed in a single connection, returns {@code true} for all streams
* after the first.
*
* @return whether this request reused a socket from a previous request. When {@code true},
* DNS,
* connection, and SSL times will be {@code null}.
*/
public abstract boolean getSocketReused();
/**
* Returns milliseconds between request initiation and first byte of response headers, or
* {@code null} if not collected. TODO(mgersh): Remove once new API works
* http://crbug.com/629194
* {@hide}
*/
@Nullable
public abstract Long getTtfbMs();
/**
* Returns milliseconds between request initiation and finish, including a failure or
* cancellation, or {@code null} if not collected. TODO(mgersh): Remove once new API works
* http://crbug.com/629194 {@hide}
*/
@Nullable
public abstract Long getTotalTimeMs();
/**
* Returns total bytes sent over the network transport layer, or {@code null} if not
* collected.
*/
@Nullable
public abstract Long getSentByteCount();
/**
* Returns total bytes received over the network transport layer, or {@code null} if not
* collected. Number of bytes does not include any previous redirects.
*/
@Nullable
public abstract Long getReceivedByteCount();
}
/** Reason value indicating that the request succeeded. Returned from {@link #getFinishedReason}. */
public static final int SUCCEEDED = 0;
/**
* Reason value indicating that the request failed or returned an error. Returned from {@link
* #getFinishedReason}.
*/
public static final int FAILED = 1;
/**
* Reason value indicating that the request was canceled. Returned from {@link
* #getFinishedReason}.
*/
public static final int CANCELED = 2;
/**
* Returns the request's original URL.
*
* @return the request's original URL
*/
public abstract String getUrl();
/**
* Returns the objects that the caller has supplied when initiating the request, using {@link
* UrlRequest.Builder#addRequestAnnotation}. Annotations can be used to associate a
* {@link RequestFinishedInfo} with the original request or type of request.
*
* @return annotations supplied when creating the request
*/
public abstract Collection<Object> getAnnotations();
// TODO(klm): Collect and return a chain of Metrics objects for redirect responses.
// TODO(mgersh): Update this javadoc when new metrics are fully implemented
/**
* Returns metrics collected for this request.
*
* <p>The reported times and bytes account for all redirects, i.e.
* the TTFB is from the start of the original request to the ultimate response headers, the TTLB
* is from the start of the original request to the end of the ultimate response, the received
* byte count is for all redirects and the ultimate response combined. These cumulative metric
* definitions are debatable, but are chosen to make sense for user-facing latency analysis.
*
* @return metrics collected for this request.
*
* <p>{@hide} as the Metrics class is hidden
*/
public abstract Metrics getMetrics();
/**
* Returns the reason why the request finished.
*
* @return one of {@link #SUCCEEDED}, {@link #FAILED}, or {@link #CANCELED}
*/
public abstract int getFinishedReason();
/**
* Returns a {@link UrlResponseInfo} for the request, if its response had started.
*
* @return {@link UrlResponseInfo} for the request, if its response had started.
*/
@Nullable
public abstract UrlResponseInfo getResponseInfo();
/**
* If the request failed, returns the same {@link CronetException} provided to {@link
* UrlRequest.Callback#onFailed}.
*
* @return the request's {@link CronetException}, if the request failed
*/
@Nullable
public abstract CronetException getException();
}