OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 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 android.content.Context; |
| 8 import android.util.Log; |
| 9 |
| 10 import org.json.JSONArray; |
| 11 import org.json.JSONException; |
| 12 import org.json.JSONObject; |
| 13 |
| 14 import java.io.File; |
| 15 import java.lang.reflect.Constructor; |
| 16 import java.util.concurrent.Executor; |
| 17 |
| 18 /** |
| 19 * An engine to process {@link UrlRequest}s, which uses the best HTTP stack |
| 20 * available on the current platform. |
| 21 */ |
| 22 public abstract class CronetEngine { |
| 23 /** |
| 24 * A builder for {@link CronetEngine}s, which allows runtime configuration o
f |
| 25 * {@code CronetEngine}. Configuration options are set on the builder and |
| 26 * then {@link #build} is called to create the {@code CronetEngine}. |
| 27 */ |
| 28 public static class Builder { |
| 29 private final JSONObject mConfig; |
| 30 private final Context mContext; |
| 31 |
| 32 /** |
| 33 * Default config enables SPDY, disables QUIC, SDCH and HTTP cache. |
| 34 * @param context Android {@link Context} for engine to use. |
| 35 */ |
| 36 public Builder(Context context) { |
| 37 mConfig = new JSONObject(); |
| 38 mContext = context; |
| 39 enableLegacyMode(false); |
| 40 enableQUIC(false); |
| 41 enableHTTP2(true); |
| 42 enableSDCH(false); |
| 43 enableHttpCache(HTTP_CACHE_DISABLED, 0); |
| 44 } |
| 45 |
| 46 /** |
| 47 * Creates a config from a JSON string, which was serialized using |
| 48 * {@link #toString}. |
| 49 * |
| 50 * @param context Android {@link Context} for engine to use. |
| 51 * @param json JSON string of configuration parameters, which was |
| 52 * serialized using {@link #toString}. |
| 53 */ |
| 54 public Builder(Context context, String json) throws JSONException { |
| 55 mConfig = new JSONObject(json); |
| 56 mContext = context; |
| 57 } |
| 58 |
| 59 /** |
| 60 * Overrides the user-agent header for all requests. |
| 61 * @return the builder to facilitate chaining. |
| 62 */ |
| 63 public Builder setUserAgent(String userAgent) { |
| 64 return putString(CronetEngineBuilderList.USER_AGENT, userAgent); |
| 65 } |
| 66 |
| 67 String userAgent() { |
| 68 return mConfig.optString(CronetEngineBuilderList.USER_AGENT); |
| 69 } |
| 70 |
| 71 /** |
| 72 * Sets directory for HTTP Cache and Cookie Storage. The directory must |
| 73 * exist. |
| 74 * @param value path to existing directory. |
| 75 * @return the builder to facilitate chaining. |
| 76 */ |
| 77 public Builder setStoragePath(String value) { |
| 78 if (!new File(value).isDirectory()) { |
| 79 throw new IllegalArgumentException( |
| 80 "Storage path must be set to existing directory"); |
| 81 } |
| 82 |
| 83 return putString(CronetEngineBuilderList.STORAGE_PATH, value); |
| 84 } |
| 85 |
| 86 String storagePath() { |
| 87 return mConfig.optString(CronetEngineBuilderList.STORAGE_PATH); |
| 88 } |
| 89 |
| 90 /** |
| 91 * Sets whether falling back to implementation based on system's |
| 92 * {@link java.net.HttpURLConnection} implementation is enabled. |
| 93 * Defaults to disabled. |
| 94 * @return the builder to facilitate chaining. |
| 95 * @deprecated Not supported by the new API. |
| 96 */ |
| 97 @Deprecated |
| 98 public Builder enableLegacyMode(boolean value) { |
| 99 return putBoolean(CronetEngineBuilderList.ENABLE_LEGACY_MODE, value)
; |
| 100 } |
| 101 |
| 102 boolean legacyMode() { |
| 103 return mConfig.optBoolean(CronetEngineBuilderList.ENABLE_LEGACY_MODE
); |
| 104 } |
| 105 |
| 106 /** |
| 107 * Overrides the name of the native library backing Cronet. |
| 108 * @return the builder to facilitate chaining. |
| 109 */ |
| 110 Builder setLibraryName(String libName) { |
| 111 return putString(CronetEngineBuilderList.NATIVE_LIBRARY_NAME, libNam
e); |
| 112 } |
| 113 |
| 114 String libraryName() { |
| 115 return mConfig.optString(CronetEngineBuilderList.NATIVE_LIBRARY_NAME
, "cronet"); |
| 116 } |
| 117 |
| 118 /** |
| 119 * Sets whether <a href="https://www.chromium.org/quic">QUIC</a> protoco
l |
| 120 * is enabled. Defaults to disabled. |
| 121 * @return the builder to facilitate chaining. |
| 122 */ |
| 123 public Builder enableQUIC(boolean value) { |
| 124 return putBoolean(CronetEngineBuilderList.ENABLE_QUIC, value); |
| 125 } |
| 126 |
| 127 /** |
| 128 * Sets whether <a href="https://tools.ietf.org/html/rfc7540">HTTP/2</a> |
| 129 * protocol is enabled. Defaults to enabled. |
| 130 * @return the builder to facilitate chaining. |
| 131 */ |
| 132 public Builder enableHTTP2(boolean value) { |
| 133 return putBoolean(CronetEngineBuilderList.ENABLE_SPDY, value); |
| 134 } |
| 135 |
| 136 /** |
| 137 * Sets whether |
| 138 * <a |
| 139 * href="https://lists.w3.org/Archives/Public/ietf-http-wg/2008JulSep/at
t-0441/Shared_Dictionary_Compression_over_HTTP.pdf"> |
| 140 * SDCH</a> compression is enabled. Defaults to disabled. |
| 141 * @return the builder to facilitate chaining. |
| 142 */ |
| 143 public Builder enableSDCH(boolean value) { |
| 144 return putBoolean(CronetEngineBuilderList.ENABLE_SDCH, value); |
| 145 } |
| 146 |
| 147 /** |
| 148 * Enables |
| 149 * <a href="https://developer.chrome.com/multidevice/data-compression">D
ata |
| 150 * Reduction Proxy</a>. Defaults to disabled. |
| 151 * @param key key to use when authenticating with the proxy. |
| 152 * @return the builder to facilitate chaining. |
| 153 */ |
| 154 public Builder enableDataReductionProxy(String key) { |
| 155 return (putString(CronetEngineBuilderList.DATA_REDUCTION_PROXY_KEY,
key)); |
| 156 } |
| 157 |
| 158 /** |
| 159 * Overrides |
| 160 * <a href="https://developer.chrome.com/multidevice/data-compression"> |
| 161 * Data Reduction Proxy</a> configuration parameters with a primary |
| 162 * proxy name, fallback proxy name, and a secure proxy check URL. Proxie
s |
| 163 * are specified as [scheme://]host[:port]. Used for testing. |
| 164 * @param primaryProxy the primary data reduction proxy to use. |
| 165 * @param fallbackProxy a fallback data reduction proxy to use. |
| 166 * @param secureProxyCheckUrl a URL to fetch to determine if using a sec
ure |
| 167 * proxy is allowed. |
| 168 * @return the builder to facilitate chaining. |
| 169 * @hide |
| 170 */ |
| 171 public Builder setDataReductionProxyOptions( |
| 172 String primaryProxy, String fallbackProxy, String secureProxyChe
ckUrl) { |
| 173 if (primaryProxy.isEmpty() || fallbackProxy.isEmpty() |
| 174 || secureProxyCheckUrl.isEmpty()) { |
| 175 throw new IllegalArgumentException( |
| 176 "Primary and fallback proxies and check url must be set"
); |
| 177 } |
| 178 putString(CronetEngineBuilderList.DATA_REDUCTION_PRIMARY_PROXY, prim
aryProxy); |
| 179 putString(CronetEngineBuilderList.DATA_REDUCTION_FALLBACK_PROXY, fal
lbackProxy); |
| 180 putString(CronetEngineBuilderList.DATA_REDUCTION_SECURE_PROXY_CHECK_
URL, |
| 181 secureProxyCheckUrl); |
| 182 return this; |
| 183 } |
| 184 |
| 185 /** |
| 186 * Setting to disable HTTP cache. Some data may still be temporarily sto
red in memory. |
| 187 * Passed to {@link #enableHttpCache}. |
| 188 */ |
| 189 public static final int HTTP_CACHE_DISABLED = 0; |
| 190 |
| 191 /** |
| 192 * Setting to enable in-memory HTTP cache, including HTTP data. |
| 193 * Passed to {@link #enableHttpCache}. |
| 194 */ |
| 195 public static final int HTTP_CACHE_IN_MEMORY = 1; |
| 196 |
| 197 /** |
| 198 * Setting to enable on-disk cache, excluding HTTP data. |
| 199 * {@link #setStoragePath} must be called prior to passing this constant
to |
| 200 * {@link #enableHttpCache}. |
| 201 */ |
| 202 public static final int HTTP_CACHE_DISK_NO_HTTP = 2; |
| 203 |
| 204 /** |
| 205 * Setting to enable on-disk cache, including HTTP data. |
| 206 * {@link #setStoragePath} must be called prior to passing this constant
to |
| 207 * {@link #enableHttpCache}. |
| 208 */ |
| 209 public static final int HTTP_CACHE_DISK = 3; |
| 210 |
| 211 /** |
| 212 * Enables or disables caching of HTTP data and other information like Q
UIC |
| 213 * server information. |
| 214 * @param cacheMode control location and type of cached data. |
| 215 * @param maxSize maximum size in bytes used to cache data (advisory and
maybe |
| 216 * exceeded at times). |
| 217 * @return the builder to facilitate chaining. |
| 218 */ |
| 219 public Builder enableHttpCache(int cacheMode, long maxSize) { |
| 220 if (cacheMode == HTTP_CACHE_DISK || cacheMode == HTTP_CACHE_DISK_NO_
HTTP) { |
| 221 if (storagePath().isEmpty()) { |
| 222 throw new IllegalArgumentException("Storage path must be set
"); |
| 223 } |
| 224 } else { |
| 225 if (!storagePath().isEmpty()) { |
| 226 throw new IllegalArgumentException("Storage path must be emp
ty"); |
| 227 } |
| 228 } |
| 229 putBoolean(CronetEngineBuilderList.LOAD_DISABLE_CACHE, |
| 230 cacheMode == HTTP_CACHE_DISABLED || cacheMode == HTTP_CACHE_
DISK_NO_HTTP); |
| 231 putLong(CronetEngineBuilderList.HTTP_CACHE_MAX_SIZE, maxSize); |
| 232 |
| 233 switch (cacheMode) { |
| 234 case HTTP_CACHE_DISABLED: |
| 235 return putString(CronetEngineBuilderList.HTTP_CACHE, |
| 236 CronetEngineBuilderList.HTTP_CACHE_DISABLED); |
| 237 case HTTP_CACHE_DISK_NO_HTTP: |
| 238 case HTTP_CACHE_DISK: |
| 239 return putString(CronetEngineBuilderList.HTTP_CACHE, |
| 240 CronetEngineBuilderList.HTTP_CACHE_DISK); |
| 241 |
| 242 case HTTP_CACHE_IN_MEMORY: |
| 243 return putString(CronetEngineBuilderList.HTTP_CACHE, |
| 244 CronetEngineBuilderList.HTTP_CACHE_MEMORY); |
| 245 } |
| 246 return this; |
| 247 } |
| 248 |
| 249 /** |
| 250 * Adds hint that {@code host} supports QUIC. |
| 251 * Note that {@link #enableHttpCache enableHttpCache} |
| 252 * ({@link HttpCache#DISK DISK}) is needed to take advantage of 0-RTT |
| 253 * connection establishment between sessions. |
| 254 * |
| 255 * @param host hostname of the server that supports QUIC. |
| 256 * @param port host of the server that supports QUIC. |
| 257 * @param alternatePort alternate port to use for QUIC. |
| 258 * @return the builder to facilitate chaining. |
| 259 */ |
| 260 public Builder addQuicHint(String host, int port, int alternatePort) { |
| 261 if (host.contains("/")) { |
| 262 throw new IllegalArgumentException("Illegal QUIC Hint Host: " +
host); |
| 263 } |
| 264 try { |
| 265 JSONArray quicHints = mConfig.optJSONArray(CronetEngineBuilderLi
st.QUIC_HINTS); |
| 266 if (quicHints == null) { |
| 267 quicHints = new JSONArray(); |
| 268 mConfig.put(CronetEngineBuilderList.QUIC_HINTS, quicHints); |
| 269 } |
| 270 |
| 271 JSONObject hint = new JSONObject(); |
| 272 hint.put(CronetEngineBuilderList.QUIC_HINT_HOST, host); |
| 273 hint.put(CronetEngineBuilderList.QUIC_HINT_PORT, port); |
| 274 hint.put(CronetEngineBuilderList.QUIC_HINT_ALT_PORT, alternatePo
rt); |
| 275 quicHints.put(hint); |
| 276 } catch (JSONException e) { |
| 277 // Intentionally do nothing. |
| 278 } |
| 279 return this; |
| 280 } |
| 281 |
| 282 /** |
| 283 * Sets experimental QUIC connection options, overwriting any pre-existi
ng |
| 284 * options. List of options is subject to change. |
| 285 * |
| 286 * @param quicConnectionOptions comma-separated QUIC options (for exampl
e |
| 287 * "PACE,IW10") to use if QUIC is enabled. |
| 288 * @return the builder to facilitate chaining. |
| 289 */ |
| 290 public Builder setExperimentalQuicConnectionOptions(String quicConnectio
nOptions) { |
| 291 return putString(CronetEngineBuilderList.QUIC_OPTIONS, quicConnectio
nOptions); |
| 292 } |
| 293 |
| 294 /** |
| 295 * Get JSON string representation of the builder. |
| 296 */ |
| 297 @Override |
| 298 public String toString() { |
| 299 return mConfig.toString(); |
| 300 } |
| 301 |
| 302 /** |
| 303 * Returns {@link Context} for builder. |
| 304 * |
| 305 * @return {@link Context} for builder. |
| 306 */ |
| 307 Context getContext() { |
| 308 return mContext; |
| 309 } |
| 310 |
| 311 /** |
| 312 * Sets a boolean value in the config. Returns a reference to the same |
| 313 * config object, so you can chain put calls together. |
| 314 * @return the builder to facilitate chaining. |
| 315 */ |
| 316 private Builder putBoolean(String key, boolean value) { |
| 317 try { |
| 318 mConfig.put(key, value); |
| 319 } catch (JSONException e) { |
| 320 // Intentionally do nothing. |
| 321 } |
| 322 return this; |
| 323 } |
| 324 |
| 325 /** |
| 326 * Sets a long value in the config. Returns a reference to the same |
| 327 * config object, so you can chain put calls together. |
| 328 * @return the builder to facilitate chaining. |
| 329 */ |
| 330 private Builder putLong(String key, long value) { |
| 331 try { |
| 332 mConfig.put(key, value); |
| 333 } catch (JSONException e) { |
| 334 // Intentionally do nothing. |
| 335 } |
| 336 return this; |
| 337 } |
| 338 |
| 339 /** |
| 340 * Sets a string value in the config. Returns a reference to the same |
| 341 * config object, so you can chain put calls together. |
| 342 * @return the builder to facilitate chaining. |
| 343 */ |
| 344 private Builder putString(String key, String value) { |
| 345 try { |
| 346 mConfig.put(key, value); |
| 347 } catch (JSONException e) { |
| 348 // Intentionally do nothing. |
| 349 } |
| 350 return this; |
| 351 } |
| 352 |
| 353 /** |
| 354 * Build a {@link CronetEngine} using this builder's configuration. |
| 355 */ |
| 356 public CronetEngine build() { |
| 357 return createContext(this); |
| 358 } |
| 359 } |
| 360 |
| 361 private static final String TAG = "UrlRequestFactory"; |
| 362 private static final String CRONET_URL_REQUEST_CONTEXT = |
| 363 "org.chromium.net.CronetUrlRequestContext"; |
| 364 |
| 365 /** |
| 366 * Creates a {@link UrlRequest} object. All callbacks will |
| 367 * be called on {@code executor}'s thread. {@code executor} must not run |
| 368 * tasks on the current thread to prevent blocking networking operations |
| 369 * and causing exceptions during shutdown. Request is given medium priority, |
| 370 * see {@link UrlRequest#REQUEST_PRIORITY_MEDIUM}. To specify other |
| 371 * priorities see {@link #createRequest(String, UrlRequestListener, |
| 372 * Executor, int priority)}. |
| 373 * |
| 374 * @param url {@link java.net.URL} for the request. |
| 375 * @param listener callback class that gets called on different events. |
| 376 * @param executor {@link Executor} on which all callbacks will be called. |
| 377 * @return new request. |
| 378 * @deprecated Use {@link Builder#build}. |
| 379 */ |
| 380 @Deprecated |
| 381 public abstract UrlRequest createRequest( |
| 382 String url, UrlRequestListener listener, Executor executor); |
| 383 |
| 384 /** |
| 385 * Creates a {@link UrlRequest} object. All callbacks will |
| 386 * be called on {@code executor}'s thread. {@code executor} must not run |
| 387 * tasks on the current thread to prevent blocking networking operations |
| 388 * and causing exceptions during shutdown. |
| 389 * |
| 390 * @param url {@link java.net.URL} for the request. |
| 391 * @param listener callback class that gets called on different events. |
| 392 * @param executor {@link Executor} on which all callbacks will be called. |
| 393 * @param priority priority of the request which should be one of the |
| 394 * {@link UrlRequest#REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*} |
| 395 * values. |
| 396 * @return new request. |
| 397 * @deprecated Use {@link Builder#build}. |
| 398 */ |
| 399 @Deprecated |
| 400 public abstract UrlRequest createRequest( |
| 401 String url, UrlRequestListener listener, Executor executor, int prio
rity); |
| 402 |
| 403 /** |
| 404 * @return {@code true} if the engine is enabled. |
| 405 */ |
| 406 abstract boolean isEnabled(); |
| 407 |
| 408 /** |
| 409 * @return a human-readable version string of the engine. |
| 410 */ |
| 411 public abstract String getVersionString(); |
| 412 |
| 413 /** |
| 414 * Shuts down the {@link CronetEngine} if there are no active requests, |
| 415 * otherwise throws an exception. |
| 416 * |
| 417 * Cannot be called on network thread - the thread Cronet calls into |
| 418 * Executor on (which is different from the thread the Executor invokes |
| 419 * callbacks on). May block until all the {@code CronetEngine}'s |
| 420 * resources have been cleaned up. |
| 421 */ |
| 422 public abstract void shutdown(); |
| 423 |
| 424 /** |
| 425 * Starts NetLog logging to a file. The NetLog is useful for debugging. |
| 426 * The file can be viewed using a Chrome browser navigated to |
| 427 * chrome://net-internals/#import |
| 428 * @param fileName the complete file path. It must not be empty. If the file |
| 429 * exists, it is truncated before starting. If actively logging, |
| 430 * this method is ignored. |
| 431 * @param logAll {@code true} to include basic events, user cookies, |
| 432 * credentials and all transferred bytes in the log. |
| 433 * {@code false} to just include basic events. |
| 434 */ |
| 435 public abstract void startNetLogToFile(String fileName, boolean logAll); |
| 436 |
| 437 /** |
| 438 * Stops NetLog logging and flushes file to disk. If a logging session is |
| 439 * not in progress, this call is ignored. |
| 440 */ |
| 441 public abstract void stopNetLog(); |
| 442 |
| 443 /** |
| 444 * Enables the network quality estimator, which collects and reports |
| 445 * measurements of round trip time (RTT) and downstream throughput at |
| 446 * various layers of the network stack. After enabling the estimator, |
| 447 * listeners of RTT and throughput can be added with |
| 448 * {@link #addRttListener} and {@link #addThroughputListener} and |
| 449 * removed with {@link #removeRttListener} and |
| 450 * {@link #removeThroughputListener}. The estimator uses memory and CPU |
| 451 * only when enabled. |
| 452 * @param executor an executor that will be used to notified all |
| 453 * added RTT and throughput listeners. |
| 454 * @deprecated not really deprecated but hidden for now as it's a prototype. |
| 455 */ |
| 456 @Deprecated public abstract void enableNetworkQualityEstimator(Executor exec
utor); |
| 457 |
| 458 /** |
| 459 * Enables the network quality estimator for testing. This must be called |
| 460 * before round trip time and throughput listeners are added. Set both |
| 461 * boolean parameters to false for default behavior. |
| 462 * @param useLocalHostRequests include requests to localhost in estimates. |
| 463 * @param useSmallerResponses include small responses in throughput estimate
s. |
| 464 * @param executor an {@link java.util.concurrent.Executor} on which all |
| 465 * listeners will be called. |
| 466 * @deprecated not really deprecated but hidden for now as it's a prototype. |
| 467 */ |
| 468 @Deprecated |
| 469 abstract void enableNetworkQualityEstimatorForTesting( |
| 470 boolean useLocalHostRequests, boolean useSmallerResponses, Executor
executor); |
| 471 |
| 472 /** |
| 473 * Registers a listener that gets called whenever the network quality |
| 474 * estimator witnesses a sample round trip time. This must be called |
| 475 * after {@link #enableNetworkQualityEstimator}, and with throw an |
| 476 * exception otherwise. Round trip times may be recorded at various layers |
| 477 * of the network stack, including TCP, QUIC, and at the URL request layer. |
| 478 * The listener is called on the {@link java.util.concurrent.Executor} that |
| 479 * is passed to {@link #enableNetworkQualityEstimator}. |
| 480 * @param listener the listener of round trip times. |
| 481 * @deprecated not really deprecated but hidden for now as it's a prototype. |
| 482 */ |
| 483 @Deprecated public abstract void addRttListener(NetworkQualityRttListener li
stener); |
| 484 |
| 485 /** |
| 486 * Removes a listener of round trip times if previously registered with |
| 487 * {@link #addRttListener}. This should be called after a |
| 488 * {@link NetworkQualityRttListener} is added in order to stop receiving |
| 489 * observations. |
| 490 * @param listener the listener of round trip times. |
| 491 * @deprecated not really deprecated but hidden for now as it's a prototype. |
| 492 */ |
| 493 @Deprecated public abstract void removeRttListener(NetworkQualityRttListener
listener); |
| 494 |
| 495 /** |
| 496 * Registers a listener that gets called whenever the network quality |
| 497 * estimator witnesses a sample throughput measurement. This must be called |
| 498 * after {@link #enableNetworkQualityEstimator}. Throughput observations |
| 499 * are computed by measuring bytes read over the active network interface |
| 500 * at times when at least one URL response is being received. The listener |
| 501 * is called on the {@link java.util.concurrent.Executor} that is passed to |
| 502 * {@link #enableNetworkQualityEstimator}. |
| 503 * @param listener the listener of throughput. |
| 504 * @deprecated not really deprecated but hidden for now as it's a prototype. |
| 505 */ |
| 506 @Deprecated |
| 507 public abstract void addThroughputListener(NetworkQualityThroughputListener
listener); |
| 508 |
| 509 /** |
| 510 * Removes a listener of throughput. This should be called after a |
| 511 * {@link NetworkQualityThroughputListener} is added with |
| 512 * {@link #addThroughputListener} in order to stop receiving observations. |
| 513 * @param listener the listener of throughput. |
| 514 * @deprecated not really deprecated but hidden for now as it's a prototype. |
| 515 */ |
| 516 @Deprecated |
| 517 public abstract void removeThroughputListener(NetworkQualityThroughputListen
er listener); |
| 518 |
| 519 /** |
| 520 * Creates a {@link CronetEngine} with the given {@link Builder}. |
| 521 * @param context Android {@link Context}. |
| 522 * @param config engine configuration. |
| 523 * @deprecated Use {@link CronetEngine.Builder}. |
| 524 */ |
| 525 @Deprecated |
| 526 public static CronetEngine createContext(Builder config) { |
| 527 CronetEngine cronetEngine = null; |
| 528 if (config.userAgent().isEmpty()) { |
| 529 config.setUserAgent(UserAgent.from(config.getContext())); |
| 530 } |
| 531 if (!config.legacyMode()) { |
| 532 cronetEngine = createCronetEngine(config); |
| 533 } |
| 534 if (cronetEngine == null) { |
| 535 // TODO(mef): Fallback to stub implementation. Once stub |
| 536 // implementation is available merge with createCronetFactory. |
| 537 cronetEngine = createCronetEngine(config); |
| 538 } |
| 539 Log.i(TAG, "Using network stack: " + cronetEngine.getVersionString()); |
| 540 return cronetEngine; |
| 541 } |
| 542 |
| 543 private static CronetEngine createCronetEngine(Builder config) { |
| 544 CronetEngine cronetEngine = null; |
| 545 try { |
| 546 Class<? extends CronetEngine> engineClass = |
| 547 CronetEngine.class.getClassLoader() |
| 548 .loadClass(CRONET_URL_REQUEST_CONTEXT) |
| 549 .asSubclass(CronetEngine.class); |
| 550 Constructor<? extends CronetEngine> constructor = |
| 551 engineClass.getConstructor(Builder.class); |
| 552 CronetEngine possibleEngine = constructor.newInstance(config); |
| 553 if (possibleEngine.isEnabled()) { |
| 554 cronetEngine = possibleEngine; |
| 555 } |
| 556 } catch (ClassNotFoundException e) { |
| 557 // Leave as null. |
| 558 } catch (Exception e) { |
| 559 throw new IllegalStateException("Cannot instantiate: " + CRONET_URL_
REQUEST_CONTEXT, e); |
| 560 } |
| 561 return cronetEngine; |
| 562 } |
| 563 } |
OLD | NEW |