Move several annotations to annotations package.
[chromium-blink-merge.git] / components / cronet / android / java / src / org / chromium / net / CronetUrlRequestContext.java
blob78d3bee0873c0d9487657842156233caa6588fad
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.os.Build;
9 import android.os.ConditionVariable;
10 import android.os.Handler;
11 import android.os.Looper;
12 import android.os.Process;
13 import android.util.Log;
15 import org.chromium.base.CalledByNative;
16 import org.chromium.base.JNINamespace;
17 import org.chromium.base.NativeClassQualifiedName;
18 import org.chromium.base.annotations.UsedByReflection;
20 import java.util.concurrent.Executor;
21 import java.util.concurrent.atomic.AtomicInteger;
23 /**
24 * UrlRequest context using Chromium HTTP stack implementation.
26 @JNINamespace("cronet")
27 @UsedByReflection("UrlRequestContext.java")
28 public class CronetUrlRequestContext extends UrlRequestContext {
29 private static final int LOG_NONE = 3; // LOG(FATAL), no VLOG.
30 private static final int LOG_DEBUG = -1; // LOG(FATAL...INFO), VLOG(1)
31 private static final int LOG_VERBOSE = -2; // LOG(FATAL...INFO), VLOG(2)
32 static final String LOG_TAG = "ChromiumNetwork";
34 /**
35 * Synchronize access to mUrlRequestContextAdapter and shutdown routine.
37 private final Object mLock = new Object();
38 private final ConditionVariable mInitCompleted = new ConditionVariable(false);
39 private final AtomicInteger mActiveRequestCount = new AtomicInteger(0);
41 private long mUrlRequestContextAdapter = 0;
42 private Thread mNetworkThread;
44 @UsedByReflection("UrlRequestContext.java")
45 public CronetUrlRequestContext(Context context,
46 UrlRequestContextConfig config) {
47 CronetLibraryLoader.ensureInitialized(context, config);
48 nativeSetMinLogLevel(getLoggingLevel());
49 mUrlRequestContextAdapter = nativeCreateRequestContextAdapter(config.toString());
50 if (mUrlRequestContextAdapter == 0) {
51 throw new NullPointerException("Context Adapter creation failed.");
54 // Init native Chromium URLRequestContext on main UI thread.
55 Runnable task = new Runnable() {
56 @Override
57 public void run() {
58 synchronized (mLock) {
59 // mUrlRequestContextAdapter is guaranteed to exist until
60 // initialization on main and network threads completes and
61 // initNetworkThread is called back on network thread.
62 nativeInitRequestContextOnMainThread(mUrlRequestContextAdapter);
66 // Run task immediately or post it to the UI thread.
67 if (Looper.getMainLooper() == Looper.myLooper()) {
68 task.run();
69 } else {
70 new Handler(Looper.getMainLooper()).post(task);
74 @Override
75 public UrlRequest createRequest(String url, UrlRequestListener listener,
76 Executor executor) {
77 synchronized (mLock) {
78 checkHaveAdapter();
79 return new CronetUrlRequest(this, mUrlRequestContextAdapter, url,
80 UrlRequest.REQUEST_PRIORITY_MEDIUM, listener, executor);
84 @Override
85 public boolean isEnabled() {
86 return Build.VERSION.SDK_INT >= 14;
89 @Override
90 public String getVersionString() {
91 return "Cronet/" + Version.getVersion();
94 @Override
95 public void shutdown() {
96 synchronized (mLock) {
97 checkHaveAdapter();
98 if (mActiveRequestCount.get() != 0) {
99 throw new IllegalStateException(
100 "Cannot shutdown with active requests.");
102 // Destroying adapter stops the network thread, so it cannot be
103 // called on network thread.
104 if (Thread.currentThread() == mNetworkThread) {
105 throw new IllegalThreadStateException(
106 "Cannot shutdown from network thread.");
109 // Wait for init to complete on main and network thread (without lock,
110 // so other thread could access it).
111 mInitCompleted.block();
113 synchronized (mLock) {
114 // It is possible that adapter is already destroyed on another thread.
115 if (!haveRequestContextAdapter()) {
116 return;
118 nativeDestroy(mUrlRequestContextAdapter);
119 mUrlRequestContextAdapter = 0;
123 @Override
124 public void startNetLogToFile(String fileName) {
125 synchronized (mLock) {
126 checkHaveAdapter();
127 nativeStartNetLogToFile(mUrlRequestContextAdapter, fileName);
131 @Override
132 public void stopNetLog() {
133 synchronized (mLock) {
134 checkHaveAdapter();
135 nativeStopNetLog(mUrlRequestContextAdapter);
140 * Mark request as started to prevent shutdown when there are active
141 * requests.
143 void onRequestStarted(UrlRequest urlRequest) {
144 mActiveRequestCount.incrementAndGet();
148 * Mark request as completed to allow shutdown when there are no active
149 * requests.
151 void onRequestDestroyed(UrlRequest urlRequest) {
152 mActiveRequestCount.decrementAndGet();
155 long getUrlRequestContextAdapter() {
156 synchronized (mLock) {
157 checkHaveAdapter();
158 return mUrlRequestContextAdapter;
162 private void checkHaveAdapter() throws IllegalStateException {
163 if (!haveRequestContextAdapter()) {
164 throw new IllegalStateException("Context is shut down.");
168 private boolean haveRequestContextAdapter() {
169 return mUrlRequestContextAdapter != 0;
173 * @return loggingLevel see {@link #LOG_NONE}, {@link #LOG_DEBUG} and
174 * {@link #LOG_VERBOSE}.
176 private int getLoggingLevel() {
177 int loggingLevel;
178 if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
179 loggingLevel = LOG_VERBOSE;
180 } else if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
181 loggingLevel = LOG_DEBUG;
182 } else {
183 loggingLevel = LOG_NONE;
185 return loggingLevel;
188 @SuppressWarnings("unused")
189 @CalledByNative
190 private void initNetworkThread() {
191 synchronized (mLock) {
192 mNetworkThread = Thread.currentThread();
193 mInitCompleted.open();
195 Thread.currentThread().setName("ChromiumNet");
196 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
199 // Native methods are implemented in cronet_url_request_context.cc.
200 private static native long nativeCreateRequestContextAdapter(String config);
202 private static native int nativeSetMinLogLevel(int loggingLevel);
204 @NativeClassQualifiedName("CronetURLRequestContextAdapter")
205 private native void nativeDestroy(long nativePtr);
207 @NativeClassQualifiedName("CronetURLRequestContextAdapter")
208 private native void nativeStartNetLogToFile(long nativePtr,
209 String fileName);
211 @NativeClassQualifiedName("CronetURLRequestContextAdapter")
212 private native void nativeStopNetLog(long nativePtr);
214 @NativeClassQualifiedName("CronetURLRequestContextAdapter")
215 private native void nativeInitRequestContextOnMainThread(long nativePtr);