blob: e98e67b36e554263d51f4400a1b0de85ef881385 [file] [log] [blame]
// Copyright 2014 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;
import android.content.Context;
import android.util.Log;
import java.lang.reflect.Constructor;
import java.util.concurrent.Executor;
/**
* A context for {@link UrlRequest}'s, which uses the best HTTP stack
* available on the current platform.
*/
public abstract class UrlRequestContext {
private static final String TAG = "UrlRequestFactory";
private static final String CRONET_URL_REQUEST_CONTEXT =
"org.chromium.net.CronetUrlRequestContext";
/**
* Creates an UrlRequest object. All UrlRequest functions must
* be called on the Executor's thread, and all callbacks will be called
* on the Executor's thread as well. Executor must not run tasks on the
* current thread to prevent network jank and exception during shutdown.
*
* createRequest itself may be called on any thread.
* @param url URL for the request.
* @param listener Callback interface that gets called on different events.
* @param executor Executor on which all callbacks will be called.
* @return new request.
*/
public abstract UrlRequest createRequest(String url,
UrlRequestListener listener, Executor executor);
/**
* @return true if the context is enabled.
*/
public abstract boolean isEnabled();
/**
* @return a human-readable version string of the context.
*/
public abstract String getVersionString();
/**
* Shuts down the UrlRequestContext if there are no active requests,
* otherwise throws an exception.
*
* Cannot be called on network thread - the thread Cronet calls into
* Executor on (which is different from the thread the Executor invokes
* callbacks on). May block until all the Context's resources have been
* cleaned up.
*/
public abstract void shutdown();
/**
* Create context with given config. If config.legacyMode is true, or
* native library is not available, then creates HttpUrlConnection-based
* context.
* @param context application context.
* @param config context configuration.
*/
public static UrlRequestContext createContext(Context context,
UrlRequestContextConfig config) {
UrlRequestContext urlRequestContext = null;
if (config.userAgent().isEmpty()) {
config.setUserAgent(UserAgent.from(context));
}
if (!config.legacyMode()) {
urlRequestContext = createCronetContext(context, config);
}
if (urlRequestContext == null) {
// TODO(mef): Fallback to stub implementation. Once stub
// implementation is available merge with createCronetFactory.
urlRequestContext = createCronetContext(context, config);
}
Log.i(TAG, "Using network stack: "
+ urlRequestContext.getVersionString());
return urlRequestContext;
}
private static UrlRequestContext createCronetContext(Context context,
UrlRequestContextConfig config) {
UrlRequestContext urlRequestContext = null;
try {
Class<? extends UrlRequestContext> contextClass =
UrlRequestContext.class.getClassLoader()
.loadClass(CRONET_URL_REQUEST_CONTEXT)
.asSubclass(UrlRequestContext.class);
Constructor<? extends UrlRequestContext> constructor =
contextClass.getConstructor(
Context.class, UrlRequestContextConfig.class);
UrlRequestContext cronetContext =
constructor.newInstance(context, config);
if (cronetContext.isEnabled()) {
urlRequestContext = cronetContext;
}
} catch (ClassNotFoundException e) {
// Leave as null.
} catch (Exception e) {
throw new IllegalStateException(
"Cannot instantiate: " + CRONET_URL_REQUEST_CONTEXT,
e);
}
return urlRequestContext;
}
}