Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Unified Diff: components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java

Issue 2339223002: Cronet API Refactoring (Closed)
Patch Set: Rebased onto Charles change + Paul's Comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..b602a25e4e7705e50c4118aea980a171fe122108
--- /dev/null
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java
@@ -0,0 +1,673 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// 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 android.content.Context;
+import android.support.annotation.IntDef;
+
+import org.chromium.base.Log;
+import org.chromium.base.VisibleForTesting;
+import org.chromium.net.CronetEngine;
+import org.chromium.net.ICronetEngineBuilder;
+
+import java.io.File;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.IDN;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * Implementation of {@link ICronetEngineBuilder}.
+ */
+public class CronetEngineBuilderImpl extends ICronetEngineBuilder {
+ /**
+ * A hint that a host supports QUIC.
+ */
+ public static class QuicHint {
+ // The host.
+ final String mHost;
+ // Port of the server that supports QUIC.
+ final int mPort;
+ // Alternate protocol port.
+ final int mAlternatePort;
+
+ QuicHint(String host, int port, int alternatePort) {
+ mHost = host;
+ mPort = port;
+ mAlternatePort = alternatePort;
+ }
+ }
+
+ /**
+ * A public key pin.
+ */
+ public static class Pkp {
+ // Host to pin for.
+ final String mHost;
+ // Array of SHA-256 hashes of keys.
+ final byte[][] mHashes;
+ // Should pin apply to subdomains?
+ final boolean mIncludeSubdomains;
+ // When the pin expires.
+ final Date mExpirationDate;
+
+ Pkp(String host, byte[][] hashes, boolean includeSubdomains, Date expirationDate) {
+ mHost = host;
+ mHashes = hashes;
+ mIncludeSubdomains = includeSubdomains;
+ mExpirationDate = expirationDate;
+ }
+ }
+
+ private static final String TAG = "CronetEngineBuilder";
+ private static final Pattern INVALID_PKP_HOST_NAME = Pattern.compile("^[0-9\\.]*$");
+
+ // Private fields are simply storage of configuration for the resulting CronetEngine.
+ // See setters below for verbose descriptions.
+ private final Context mContext;
+ private final List<QuicHint> mQuicHints = new LinkedList<>();
+ private final List<Pkp> mPkps = new LinkedList<>();
+ private boolean mPublicKeyPinningBypassForLocalTrustAnchorsEnabled;
+ private String mUserAgent;
+ private String mStoragePath;
+ private boolean mLegacyModeEnabled;
+ private CronetEngine.Builder.LibraryLoader mLibraryLoader;
+ private String mLibraryName;
+ private boolean mQuicEnabled;
+ private boolean mHttp2Enabled;
+ private boolean mSdchEnabled;
+ private String mDataReductionProxyKey;
+ private String mDataReductionProxyPrimaryProxy;
+ private String mDataReductionProxyFallbackProxy;
+ private String mDataReductionProxySecureProxyCheckUrl;
+ private boolean mDisableCache;
+ private int mHttpCacheMode;
+ private long mHttpCacheMaxSize;
+ private String mExperimentalOptions;
+ private long mMockCertVerifier;
+ private boolean mNetworkQualityEstimatorEnabled;
+ private String mCertVerifierData;
+
+ /**
+ * Default config enables SPDY, disables QUIC, SDCH and HTTP cache.
+ * @param context Android {@link Context} for engine to use.
+ */
+ public CronetEngineBuilderImpl(Context context) {
+ mContext = context;
+ setLibraryName("cronet");
+ enableLegacyMode(false);
+ enableQuic(false);
+ enableHttp2(true);
+ enableSdch(false);
+ enableHttpCache(HTTP_CACHE_DISABLED, 0);
+ enableNetworkQualityEstimator(false);
+ enablePublicKeyPinningBypassForLocalTrustAnchors(true);
+ }
+
+ /**
+ * Constructs a User-Agent string including application name and version,
+ * system build version, model and id, and Cronet version.
+ *
+ * @return User-Agent string.
+ */
pauljensen 2016/09/26 14:51:22 Add @Override to all these functions and remove co
kapishnikov 2016/09/27 18:38:26 Should we add Javadocs to ICronetEngineBuilder in
pauljensen 2016/09/27 19:08:09 Definitly add @Override; I'd prefer no docs, perha
kapishnikov 2016/09/28 00:20:49 Done.
+ public String getDefaultUserAgent() {
+ return UserAgent.from(mContext);
+ }
+
+ /**
+ * Overrides the User-Agent header for all requests. An explicitly
+ * set User-Agent header (set using
+ * {@link org.chromium.net.UrlRequest.Builder#addHeader(String, String)})
+ * will override a value set using this function.
+ *
+ * @param userAgent the User-Agent string to use for all requests.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl setUserAgent(String userAgent) {
+ mUserAgent = userAgent;
+ return this;
+ }
+
+ String getUserAgent() {
+ return mUserAgent;
+ }
+
+ /**
+ * Sets directory for HTTP Cache and Cookie Storage. The directory must
+ * exist.
+ * <p>
+ * <b>NOTE:</b> Do not use the same storage directory with more than one
+ * {@code CronetEngine} at a time. Access to the storage directory does
+ * not support concurrent access by multiple {@code CronetEngine}s.
+ *
+ * @param value path to existing directory.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl setStoragePath(String value) {
+ if (!new File(value).isDirectory()) {
+ throw new IllegalArgumentException("Storage path must be set to existing directory");
+ }
+ mStoragePath = value;
+ return this;
+ }
+
+ String storagePath() {
+ return mStoragePath;
+ }
+
+ /**
+ * Sets whether the resulting {@link CronetEngine} uses an
+ * implementation based on the system's
+ * {@link java.net.HttpURLConnection} implementation, or if this is
+ * only done as a backup if the native implementation fails to load.
+ * Defaults to disabled.
+ * @param value {@code true} makes the resulting {@link CronetEngine}
+ * use an implementation based on the system's
+ * {@link java.net.HttpURLConnection} implementation
+ * without trying to load the native implementation.
+ * {@code false} makes the resulting {@code CronetEngine}
+ * use the native implementation, or if that fails to load,
+ * falls back to an implementation based on the system's
+ * {@link java.net.HttpURLConnection} implementation.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl enableLegacyMode(boolean value) {
+ mLegacyModeEnabled = value;
+ return this;
+ }
+
+ private boolean legacyMode() {
+ return mLegacyModeEnabled;
+ }
+
+ /**
+ * Overrides the name of the native library backing Cronet.
+ * @param libName the name of the native library backing Cronet.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl setLibraryName(String libName) {
+ mLibraryName = libName;
+ return this;
+ }
+
+ String libraryName() {
+ return mLibraryName;
+ }
+
+ /**
+ * Sets a {@link CronetEngine.Builder.LibraryLoader} to be used to load the native library.
+ * If not set, the library will be loaded using {@link System#loadLibrary}.
+ * @param loader {@code LibraryLoader} to be used to load the native library.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl setLibraryLoader(CronetEngine.Builder.LibraryLoader loader) {
+ mLibraryLoader = loader;
+ return this;
+ }
+
+ CronetEngine.Builder.LibraryLoader libraryLoader() {
+ return mLibraryLoader;
+ }
+
+ /**
+ * Sets whether <a href="https://www.chromium.org/quic">QUIC</a> protocol
+ * is enabled. Defaults to disabled. If QUIC is enabled, then QUIC User Agent Id
+ * containing application name and Cronet version is sent to the server.
+ * @param value {@code true} to enable QUIC, {@code false} to disable.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl enableQuic(boolean value) {
+ mQuicEnabled = value;
+ return this;
+ }
+
+ boolean quicEnabled() {
+ return mQuicEnabled;
+ }
+
+ /**
+ * Constructs default QUIC User Agent Id string including application name
+ * and Cronet version. Returns empty string if QUIC is not enabled.
+ *
+ * @param context Android {@link Context} to get package name from.
+ * @return QUIC User Agent ID string.
+ */
+ // TODO(mef): remove |context| parameter when legacy ChromiumUrlRequestContext is removed.
+ String getDefaultQuicUserAgentId(Context context) {
+ return mQuicEnabled ? UserAgent.getQuicUserAgentIdFrom(context) : "";
+ }
+
+ /**
+ * Sets whether <a href="https://tools.ietf.org/html/rfc7540">HTTP/2</a>
+ * protocol is enabled. Defaults to enabled.
+ * @param value {@code true} to enable HTTP/2, {@code false} to disable.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl enableHttp2(boolean value) {
+ mHttp2Enabled = value;
+ return this;
+ }
+
+ boolean http2Enabled() {
+ return mHttp2Enabled;
+ }
+
+ /**
+ * Sets whether
+ * <a
+ * href="https://lists.w3.org/Archives/Public/ietf-http-wg/2008JulSep/att-0441/Shared_Dictionary_Compression_over_HTTP.pdf">
+ * SDCH</a> compression is enabled. Defaults to disabled.
+ * @param value {@code true} to enable SDCH, {@code false} to disable.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl enableSdch(boolean value) {
+ mSdchEnabled = value;
+ return this;
+ }
+
+ boolean sdchEnabled() {
+ return mSdchEnabled;
+ }
+
+ /**
+ * Enables
+ * <a href="https://developer.chrome.com/multidevice/data-compression">Data
+ * Reduction Proxy</a>. Defaults to disabled.
+ * @param key key to use when authenticating with the proxy.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl enableDataReductionProxy(String key) {
+ mDataReductionProxyKey = key;
+ return this;
+ }
+
+ String dataReductionProxyKey() {
+ return mDataReductionProxyKey;
+ }
+
+ /**
+ * Overrides
+ * <a href="https://developer.chrome.com/multidevice/data-compression">
+ * Data Reduction Proxy</a> configuration parameters with a primary
+ * proxy name, fallback proxy name, and a secure proxy check URL. Proxies
+ * are specified as [scheme://]host[:port]. Used for testing.
+ * @param primaryProxy the primary data reduction proxy to use.
+ * @param fallbackProxy a fallback data reduction proxy to use.
+ * @param secureProxyCheckUrl a URL to fetch to determine if using a secure
+ * proxy is allowed.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl setDataReductionProxyOptions(
+ String primaryProxy, String fallbackProxy, String secureProxyCheckUrl) {
+ if (primaryProxy.isEmpty() || fallbackProxy.isEmpty() || secureProxyCheckUrl.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Primary and fallback proxies and check url must be set");
+ }
+ mDataReductionProxyPrimaryProxy = primaryProxy;
+ mDataReductionProxyFallbackProxy = fallbackProxy;
+ mDataReductionProxySecureProxyCheckUrl = secureProxyCheckUrl;
+ return this;
+ }
+
+ String dataReductionProxyPrimaryProxy() {
+ return mDataReductionProxyPrimaryProxy;
+ }
+
+ String dataReductionProxyFallbackProxy() {
+ return mDataReductionProxyFallbackProxy;
+ }
+
+ String dataReductionProxySecureProxyCheckUrl() {
+ return mDataReductionProxySecureProxyCheckUrl;
+ }
+
+ @IntDef({
+ HTTP_CACHE_DISABLED, HTTP_CACHE_IN_MEMORY, HTTP_CACHE_DISK_NO_HTTP, HTTP_CACHE_DISK,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface HttpCacheSetting {}
+
+ /**
+ * Setting to disable HTTP cache. Some data may still be temporarily stored in memory.
+ * Passed to {@link #enableHttpCache}.
+ */
+ static final int HTTP_CACHE_DISABLED = 0;
+
+ /**
+ * Setting to enable in-memory HTTP cache, including HTTP data.
+ * Passed to {@link #enableHttpCache}.
+ */
+ public static final int HTTP_CACHE_IN_MEMORY = 1;
+
+ /**
+ * Setting to enable on-disk cache, excluding HTTP data.
+ * {@link #setStoragePath} must be called prior to passing this constant to
+ * {@link #enableHttpCache}.
+ */
+ static final int HTTP_CACHE_DISK_NO_HTTP = 2;
+
+ /**
+ * Setting to enable on-disk cache, including HTTP data.
+ * {@link #setStoragePath} must be called prior to passing this constant to
+ * {@link #enableHttpCache}.
+ */
+ static final int HTTP_CACHE_DISK = 3;
+
+ /**
+ * Enables or disables caching of HTTP data and other information like QUIC
+ * server information.
+ * @param cacheMode control location and type of cached data. Must be one of
+ * {@link #HTTP_CACHE_DISABLED HTTP_CACHE_*}.
+ * @param maxSize maximum size in bytes used to cache data (advisory and maybe
+ * exceeded at times).
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl enableHttpCache(@HttpCacheSetting int cacheMode, long maxSize) {
+ if (cacheMode == HTTP_CACHE_DISK || cacheMode == HTTP_CACHE_DISK_NO_HTTP) {
+ if (storagePath() == null) {
+ throw new IllegalArgumentException("Storage path must be set");
+ }
+ } else {
+ if (storagePath() != null) {
+ throw new IllegalArgumentException("Storage path must not be set");
+ }
+ }
+ mDisableCache = (cacheMode == HTTP_CACHE_DISABLED || cacheMode == HTTP_CACHE_DISK_NO_HTTP);
+ mHttpCacheMaxSize = maxSize;
+
+ switch (cacheMode) {
+ case HTTP_CACHE_DISABLED:
+ mHttpCacheMode = HttpCacheType.DISABLED;
+ break;
+ case HTTP_CACHE_DISK_NO_HTTP:
+ case HTTP_CACHE_DISK:
+ mHttpCacheMode = HttpCacheType.DISK;
+ break;
+ case HTTP_CACHE_IN_MEMORY:
+ mHttpCacheMode = HttpCacheType.MEMORY;
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown cache mode");
+ }
+ return this;
+ }
+
+ boolean cacheDisabled() {
+ return mDisableCache;
+ }
+
+ long httpCacheMaxSize() {
+ return mHttpCacheMaxSize;
+ }
+
+ int httpCacheMode() {
+ return mHttpCacheMode;
+ }
+
+ /**
+ * Adds hint that {@code host} supports QUIC.
+ * Note that {@link #enableHttpCache enableHttpCache}
+ * ({@link #HTTP_CACHE_DISK}) is needed to take advantage of 0-RTT
+ * connection establishment between sessions.
+ *
+ * @param host hostname of the server that supports QUIC.
+ * @param port host of the server that supports QUIC.
+ * @param alternatePort alternate port to use for QUIC.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl addQuicHint(String host, int port, int alternatePort) {
+ if (host.contains("/")) {
+ throw new IllegalArgumentException("Illegal QUIC Hint Host: " + host);
+ }
+ mQuicHints.add(new QuicHint(host, port, alternatePort));
+ return this;
+ }
+
+ List<QuicHint> quicHints() {
+ return mQuicHints;
+ }
+
+ /**
+ * <p>
+ * Pins a set of public keys for a given host. By pinning a set of public keys,
+ * {@code pinsSha256}, communication with {@code hostName} is required to
+ * authenticate with a certificate with a public key from the set of pinned ones.
+ * An app can pin the public key of the root certificate, any of the intermediate
+ * certificates or the end-entry certificate. Authentication will fail and secure
+ * communication will not be established if none of the public keys is present in the
+ * host's certificate chain, even if the host attempts to authenticate with a
+ * certificate allowed by the device's trusted store of certificates.
+ * </p>
+ * <p>
+ * Calling this method multiple times with the same host name overrides the previously
+ * set pins for the host.
+ * </p>
+ * <p>
+ * More information about the public key pinning can be found in
+ * <a href="https://tools.ietf.org/html/rfc7469">RFC 7469</a>.
+ * </p>
+ *
+ * @param hostName name of the host to which the public keys should be pinned. A host that
+ * consists only of digits and the dot character is treated as invalid.
+ * @param pinsSha256 a set of pins. Each pin is the SHA-256 cryptographic
+ * hash of the DER-encoded ASN.1 representation of the Subject Public
+ * Key Info (SPKI) of the host's X.509 certificate. Use
+ * {@link java.security.cert.Certificate#getPublicKey()
+ * Certificate.getPublicKey()} and
+ * {@link java.security.Key#getEncoded() Key.getEncoded()}
+ * to obtain DER-encoded ASN.1 representation of the SPKI.
+ * Although, the method does not mandate the presence of the backup pin
+ * that can be used if the control of the primary private key has been
+ * lost, it is highly recommended to supply one.
+ * @param includeSubdomains indicates whether the pinning policy should be applied to
+ * subdomains of {@code hostName}.
+ * @param expirationDate specifies the expiration date for the pins.
+ * @return the builder to facilitate chaining.
+ * @throws NullPointerException if any of the input parameters are {@code null}.
+ * @throws IllegalArgumentException if the given host name is invalid or {@code pinsSha256}
+ * contains a byte array that does not represent a valid
+ * SHA-256 hash.
+ */
+ public CronetEngineBuilderImpl addPublicKeyPins(String hostName, Set<byte[]> pinsSha256,
+ boolean includeSubdomains, Date expirationDate) {
+ if (hostName == null) {
+ throw new NullPointerException("The hostname cannot be null");
+ }
+ if (pinsSha256 == null) {
+ throw new NullPointerException("The set of SHA256 pins cannot be null");
+ }
+ if (expirationDate == null) {
+ throw new NullPointerException("The pin expiration date cannot be null");
+ }
+ String idnHostName = validateHostNameForPinningAndConvert(hostName);
+ // Convert the pin to BASE64 encoding. The hash set will eliminate duplications.
+ Set<byte[]> hashes = new HashSet<>(pinsSha256.size());
+ for (byte[] pinSha256 : pinsSha256) {
+ if (pinSha256 == null || pinSha256.length != 32) {
+ throw new IllegalArgumentException("Public key pin is invalid");
+ }
+ hashes.add(pinSha256);
+ }
+ // Add new element to PKP list.
+ mPkps.add(new Pkp(idnHostName, hashes.toArray(new byte[hashes.size()][]), includeSubdomains,
+ expirationDate));
+ return this;
+ }
+
+ /**
+ * Returns list of public key pins.
+ * @return list of public key pins.
+ */
+ List<Pkp> publicKeyPins() {
+ return mPkps;
+ }
+
+ /**
+ * Enables or disables public key pinning bypass for local trust anchors. Disabling the
+ * bypass for local trust anchors is highly discouraged since it may prohibit the app
+ * from communicating with the pinned hosts. E.g., a user may want to send all traffic
+ * through an SSL enabled proxy by changing the device proxy settings and adding the
+ * proxy certificate to the list of local trust anchor. Disabling the bypass will most
+ * likly prevent the app from sending any traffic to the pinned hosts. For more
+ * information see 'How does key pinning interact with local proxies and filters?' at
+ * https://www.chromium.org/Home/chromium-security/security-faq
+ *
+ * @param value {@code true} to enable the bypass, {@code false} to disable.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl enablePublicKeyPinningBypassForLocalTrustAnchors(boolean value) {
+ mPublicKeyPinningBypassForLocalTrustAnchorsEnabled = value;
+ return this;
+ }
+
+ boolean publicKeyPinningBypassForLocalTrustAnchorsEnabled() {
+ return mPublicKeyPinningBypassForLocalTrustAnchorsEnabled;
+ }
+
+ /**
+ * Checks whether a given string represents a valid host name for PKP and converts it
+ * to ASCII Compatible Encoding representation according to RFC 1122, RFC 1123 and
+ * RFC 3490. This method is more restrictive than required by RFC 7469. Thus, a host
+ * that contains digits and the dot character only is considered invalid.
+ *
+ * Note: Currently Cronet doesn't have native implementation of host name validation that
+ * can be used. There is code that parses a provided URL but doesn't ensure its
+ * correctness. The implementation relies on {@code getaddrinfo} function.
+ *
+ * @param hostName host name to check and convert.
+ * @return true if the string is a valid host name.
+ * @throws IllegalArgumentException if the the given string does not represent a valid
+ * hostname.
+ */
+ private static String validateHostNameForPinningAndConvert(String hostName)
+ throws IllegalArgumentException {
+ if (INVALID_PKP_HOST_NAME.matcher(hostName).matches()) {
+ throw new IllegalArgumentException("Hostname " + hostName + " is illegal."
+ + " A hostname should not consist of digits and/or dots only.");
+ }
+ // Workaround for crash, see crbug.com/634914
+ if (hostName.length() > 255) {
+ throw new IllegalArgumentException("Hostname " + hostName + " is too long."
+ + " The name of the host does not comply with RFC 1122 and RFC 1123.");
+ }
+ try {
+ return IDN.toASCII(hostName, IDN.USE_STD3_ASCII_RULES);
+ } catch (IllegalArgumentException ex) {
+ throw new IllegalArgumentException("Hostname " + hostName + " is illegal."
+ + " The name of the host does not comply with RFC 1122 and RFC 1123.");
+ }
+ }
+
+ /**
+ * Sets experimental options to be used in Cronet.
+ *
+ * @param options JSON formatted experimental options.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl setExperimentalOptions(String options) {
+ mExperimentalOptions = options;
+ return this;
+ }
+
+ public String experimentalOptions() {
+ return mExperimentalOptions;
+ }
+
+ /**
+ * Sets a native MockCertVerifier for testing. See
+ * {@code MockCertVerifier.createMockCertVerifier} for a method that
+ * can be used to create a MockCertVerifier.
+ * @param mockCertVerifier pointer to native MockCertVerifier.
+ * @return the builder to facilitate chaining.
+ */
+ @VisibleForTesting
+ public CronetEngineBuilderImpl setMockCertVerifierForTesting(long mockCertVerifier) {
+ mMockCertVerifier = mockCertVerifier;
+ return this;
+ }
+
+ long mockCertVerifier() {
+ return mMockCertVerifier;
+ }
+
+ /**
+ * @return true if the network quality estimator has been enabled for
+ * this builder.
+ */
+ boolean networkQualityEstimatorEnabled() {
+ return mNetworkQualityEstimatorEnabled;
+ }
+
+ /**
+ * Initializes CachingCertVerifier's cache with certVerifierData which has
+ * the results of certificate verification.
+ * @param certVerifierData a serialized representation of certificate
+ * verification results.
+ * @return the builder to facilitate chaining.
+ */
+ public CronetEngineBuilderImpl setCertVerifierData(String certVerifierData) {
+ mCertVerifierData = certVerifierData;
+ return this;
+ }
+
+ /**
+ * Enables the network quality estimator, which collects and reports
+ * measurements of round trip time (RTT) and downstream throughput at
+ * various layers of the network stack. After enabling the estimator,
+ * listeners of RTT and throughput can be added with
+ * {@link org.chromium.net.ExperimentalCronetEngine#addRttListener} and
+ * {@link org.chromium.net.ExperimentalCronetEngine#addThroughputListener} and
+ * removed with {@link org.chromium.net.ExperimentalCronetEngine#removeRttListener} and
+ * {@link org.chromium.net.ExperimentalCronetEngine#removeThroughputListener}.
+ * The estimator uses memory and CPU only when enabled.
+ * @param value {@code true} to enable network quality estimator,
+ * {@code false} to disable.
+ * @return the builder to facilitate chaining.
+ */
+ @Override
+ public CronetEngineBuilderImpl enableNetworkQualityEstimator(boolean value) {
+ mNetworkQualityEstimatorEnabled = value;
+ return this;
+ }
+
+ String certVerifierData() {
+ return mCertVerifierData;
+ }
+
+ /**
+ * Returns {@link Context} for builder.
+ *
+ * @return {@link Context} for builder.
+ */
+ public Context getContext() {
+ return mContext;
+ }
+
+ /**
+ * Build a {@link CronetEngine} using this builder's configuration.
+ * @return constructed {@link CronetEngine}.
+ */
+ public CronetEngine build() {
+ if (getUserAgent() == null) {
+ setUserAgent(getDefaultUserAgent());
+ }
+ CronetEngine cronetEngine = null;
+ if (!legacyMode()) {
+ cronetEngine = CronetEngineBase.createCronetEngine(this);
+ }
+ if (cronetEngine == null) {
+ cronetEngine = new JavaCronetEngine(getUserAgent());
+ }
+ Log.i(TAG, "Using network stack: " + cronetEngine.getVersionString());
+ // Clear MOCK_CERT_VERIFIER reference if there is any, since
+ // the ownership has been transferred to the engine.
+ mMockCertVerifier = 0;
+ return cronetEngine;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698