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; |
+ } |
+} |