1 // Copyright 2014 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.
5 package org.chromium.net;
7 import android.content.Context;
8 import android.util.Log;
10 import java.lang.reflect.Constructor;
11 import java.util.concurrent.Executor;
14 * A context for {@link UrlRequest}'s, which uses the best HTTP stack
15 * available on the current platform.
17 public abstract class UrlRequestContext {
18 private static final String TAG = "UrlRequestFactory";
19 private static final String CRONET_URL_REQUEST_CONTEXT =
20 "org.chromium.net.CronetUrlRequestContext";
23 * Creates an UrlRequest object. All UrlRequest functions must
24 * be called on the Executor's thread, and all callbacks will be called
25 * on the Executor's thread as well. Executor must not run tasks on the
26 * current thread to prevent network jank and exception during shutdown.
28 * createRequest itself may be called on any thread.
29 * @param url URL for the request.
30 * @param listener Callback interface that gets called on different events.
31 * @param executor Executor on which all callbacks will be called.
32 * @return new request.
34 public abstract UrlRequest createRequest(String url,
35 UrlRequestListener listener, Executor executor);
38 * @return true if the context is enabled.
40 public abstract boolean isEnabled();
43 * @return a human-readable version string of the context.
45 public abstract String getVersionString();
48 * Shuts down the UrlRequestContext if there are no active requests,
49 * otherwise throws an exception.
51 * Cannot be called on network thread - the thread Cronet calls into
52 * Executor on (which is different from the thread the Executor invokes
53 * callbacks on). May block until all the Context's resources have been
56 public abstract void shutdown();
59 * Create context with given config. If config.legacyMode is true, or
60 * native library is not available, then creates HttpUrlConnection-based
62 * @param context application context.
63 * @param config context configuration.
65 public static UrlRequestContext createContext(Context context,
66 UrlRequestContextConfig config) {
67 UrlRequestContext urlRequestContext = null;
68 if (config.userAgent().isEmpty()) {
69 config.setUserAgent(UserAgent.from(context));
71 if (!config.legacyMode()) {
72 urlRequestContext = createCronetContext(context, config);
74 if (urlRequestContext == null) {
75 // TODO(mef): Fallback to stub implementation. Once stub
76 // implementation is available merge with createCronetFactory.
77 urlRequestContext = createCronetContext(context, config);
79 Log.i(TAG, "Using network stack: "
80 + urlRequestContext.getVersionString());
81 return urlRequestContext;
84 private static UrlRequestContext createCronetContext(Context context,
85 UrlRequestContextConfig config) {
86 UrlRequestContext urlRequestContext = null;
88 Class<? extends UrlRequestContext> contextClass =
89 UrlRequestContext.class.getClassLoader()
90 .loadClass(CRONET_URL_REQUEST_CONTEXT)
91 .asSubclass(UrlRequestContext.class);
92 Constructor<? extends UrlRequestContext> constructor =
93 contextClass.getConstructor(
94 Context.class, UrlRequestContextConfig.class);
95 UrlRequestContext cronetContext =
96 constructor.newInstance(context, config);
97 if (cronetContext.isEnabled()) {
98 urlRequestContext = cronetContext;
100 } catch (ClassNotFoundException e) {
102 } catch (Exception e) {
103 throw new IllegalStateException(
104 "Cannot instantiate: " + CRONET_URL_REQUEST_CONTEXT,
107 return urlRequestContext;