blob: b32566906b4ec5a41ffdd9b91251f4038c595477 [file] [log] [blame]
// Copyright 2022 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.impl;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
import java.time.Duration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** Base class for implementing a CronetLogger. */
public abstract class CronetLogger {
public static enum CronetSource {
// Safe default, don't use explicitly.
CRONET_SOURCE_UNSPECIFIED,
// The library is bundled with the application.
CRONET_SOURCE_STATICALLY_LINKED,
// The library is loaded from GooglePlayServices.
CRONET_SOURCE_PLAY_SERVICES,
// The application is using the fallback implementation.
CRONET_SOURCE_FALLBACK,
// The library is loaded through the bootclasspath.
CRONET_SOURCE_PLATFORM,
}
/**
* Logs a cronetEngine creation action with the details of the creation.
*
* @param cronetEngineId the id of the engine being created.
* @param engineBuilderInfo the configuration of the CronetEngine being created. See {@link
* CronetEngineBuilderInfo}
* @param version the version of cronet used for the engine. See {@link CronetVersion}
* @param source the source of the cronet provider for the engine. See {@link CronetSource}
*/
public abstract void logCronetEngineCreation(
int cronetEngineId,
CronetEngineBuilderInfo engineBuilderInfo,
CronetVersion version,
CronetSource source);
/**
* Logs a request/response action.
* @param cronetEngineId the id of the engine used for the request
* @param trafficInfo the associated traffic information. See {@link CronetTrafficInfo}
*/
public abstract void logCronetTrafficInfo(int cronetEngineId, CronetTrafficInfo trafficInfo);
/** Aggregates the information about a CronetEngine configuration. */
public static class CronetEngineBuilderInfo {
private final boolean mPublicKeyPinningBypassForLocalTrustAnchorsEnabled;
private final String mUserAgent;
private final String mStoragePath;
private final boolean mQuicEnabled;
private final boolean mHttp2Enabled;
private final boolean mBrotiEnabled;
private final int mHttpCacheMode;
private final String mExperimentalOptions;
private final boolean mNetworkQualityEstimatorEnabled;
private final int mThreadPriority;
public CronetEngineBuilderInfo(CronetEngineBuilderImpl builder) {
mPublicKeyPinningBypassForLocalTrustAnchorsEnabled =
builder.publicKeyPinningBypassForLocalTrustAnchorsEnabled();
mUserAgent = builder.getUserAgent();
mStoragePath = builder.storagePath();
mQuicEnabled = builder.quicEnabled();
mHttp2Enabled = builder.http2Enabled();
mBrotiEnabled = builder.brotliEnabled();
mHttpCacheMode = builder.publicBuilderHttpCacheMode();
mExperimentalOptions = builder.experimentalOptions();
mNetworkQualityEstimatorEnabled = builder.networkQualityEstimatorEnabled();
mThreadPriority = builder.threadPriority(THREAD_PRIORITY_BACKGROUND);
}
/** @return Whether public key pinning bypass for local trust anchors is enabled */
public boolean isPublicKeyPinningBypassForLocalTrustAnchorsEnabled() {
return mPublicKeyPinningBypassForLocalTrustAnchorsEnabled;
}
/** @return User-Agent used for URLRequests created through this CronetEngine */
public String getUserAgent() {
return mUserAgent;
}
/** @return Path to the directory used for HTTP cache and Cookie storage */
public String getStoragePath() {
return mStoragePath;
}
/** @return Whether QUIC protocol is enabled */
public boolean isQuicEnabled() {
return mQuicEnabled;
}
/** @return Whether HTTP2 protocol is enabled */
public boolean isHttp2Enabled() {
return mHttp2Enabled;
}
/** @return Whether Brotli compression is enabled */
public boolean isBrotliEnabled() {
return mBrotiEnabled;
}
/**
* @return Whether caching of HTTP data and other information like QUIC server information
* is enabled
*/
public int getHttpCacheMode() {
return mHttpCacheMode;
}
/** @return Experimental options configuration used by the CronetEngine */
public String getExperimentalOptions() {
return mExperimentalOptions;
}
/** @return Whether network quality estimator is enabled */
public boolean isNetworkQualityEstimatorEnabled() {
return mNetworkQualityEstimatorEnabled;
}
/** @return The thread priority of Cronet's internal thread */
public int getThreadPriority() {
return mThreadPriority;
}
}
/**
* Aggregates the information about request and response traffic for a
* particular CronetEngine.
*/
public static class CronetTrafficInfo {
private final long mRequestHeaderSizeInBytes;
private final long mRequestBodySizeInBytes;
private final long mResponseHeaderSizeInBytes;
private final long mResponseBodySizeInBytes;
private final int mResponseStatusCode;
private final Duration mHeadersLatency;
private final Duration mTotalLatency;
private final String mNegotiatedProtocol;
private final boolean mWasConnectionMigrationAttempted;
private final boolean mDidConnectionMigrationSucceed;
public CronetTrafficInfo(
long requestHeaderSizeInBytes,
long requestBodySizeInBytes,
long responseHeaderSizeInBytes,
long responseBodySizeInBytes,
int responseStatusCode,
Duration headersLatency,
Duration totalLatency,
String negotiatedProtocol,
boolean wasConnectionMigrationAttempted,
boolean didConnectionMigrationSucceed) {
mRequestHeaderSizeInBytes = requestHeaderSizeInBytes;
mRequestBodySizeInBytes = requestBodySizeInBytes;
mResponseHeaderSizeInBytes = responseHeaderSizeInBytes;
mResponseBodySizeInBytes = responseBodySizeInBytes;
mResponseStatusCode = responseStatusCode;
mHeadersLatency = headersLatency;
mTotalLatency = totalLatency;
mNegotiatedProtocol = negotiatedProtocol;
mWasConnectionMigrationAttempted = wasConnectionMigrationAttempted;
mDidConnectionMigrationSucceed = didConnectionMigrationSucceed;
}
/** @return The total size of headers sent in bytes */
public long getRequestHeaderSizeInBytes() {
return mRequestHeaderSizeInBytes;
}
/** @return The total size of request body sent, if any, in bytes */
public long getRequestBodySizeInBytes() {
return mRequestBodySizeInBytes;
}
/** @return The total size of headers received in bytes */
public long getResponseHeaderSizeInBytes() {
return mResponseHeaderSizeInBytes;
}
/** @return The total size of response body, if any, received in bytes */
public long getResponseBodySizeInBytes() {
return mResponseBodySizeInBytes;
}
/** @return The response status code of the request */
public int getResponseStatusCode() {
return mResponseStatusCode;
}
/**
* The time it took from starting the request to receiving the full set of
* response headers.
*
* @return The time to get response headers
*/
public Duration getHeadersLatency() {
return mHeadersLatency;
}
/**
* The time it took from starting the request to receiving the entire
* response.
*
* @return The time to get total response
*/
public Duration getTotalLatency() {
return mTotalLatency;
}
/** @return The negotiated protocol used for the traffic */
public String getNegotiatedProtocol() {
return mNegotiatedProtocol;
}
/** @return True if the connection migration was attempted, else False */
public boolean wasConnectionMigrationAttempted() {
return mWasConnectionMigrationAttempted;
}
/** @return True if the connection migration was attempted and succeeded, else False */
public boolean didConnectionMigrationSucceed() {
return mDidConnectionMigrationSucceed;
}
}
/** Holds information about the cronet version used for a cronetEngine. */
public static class CronetVersion {
private static final Pattern VERSION_PATTERN =
Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)");
private final int mMajorVersion;
private final int mMinorVersion;
private final int mBuildVersion;
private final int mPatchVersion;
/**
* Pass the cronet version string here and
* it would be split. The string comes in the format
* MAJOR.MINOR.BUILD.PATCH
*/
public CronetVersion(String version) {
Matcher m = VERSION_PATTERN.matcher(version);
if (!m.matches()) {
throw new IllegalArgumentException(
"Invalid version: expected a string matching " + VERSION_PATTERN
+ ", got " + version);
}
mMajorVersion = Integer.parseInt(m.group(1));
mMinorVersion = Integer.parseInt(m.group(2));
mBuildVersion = Integer.parseInt(m.group(3));
mPatchVersion = Integer.parseInt(m.group(4));
}
/** @return the MAJOR version of cronet used for the traffic */
public int getMajorVersion() {
return mMajorVersion;
}
/** @return the MINOR version of cronet used for the traffic */
public int getMinorVersion() {
return mMinorVersion;
}
/** @return the BUILD version of cronet used for the traffic */
public int getBuildVersion() {
return mBuildVersion;
}
/** @return the PATCH version of cronet used for the traffic */
public int getPatchVersion() {
return mPatchVersion;
}
@Override
public String toString() {
return ""
+ mMajorVersion
+ "."
+ mMinorVersion
+ "."
+ mBuildVersion
+ "."
+ mPatchVersion;
}
}
}