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.
4
5package org.chromium.net;
6
7import android.content.Context;
8import android.os.ConditionVariable;
9import android.os.Process;
10import android.util.Log;
11
12import org.chromium.base.CalledByNative;
13import org.chromium.base.JNINamespace;
14
15/**
16 * Provides context for the native HTTP operations.
17 */
18@JNINamespace("cronet")
19public class UrlRequestContext {
20    private static final int LOG_NONE = 0;
21    private static final int LOG_DEBUG = 1;
22    private static final int LOG_VERBOSE = 2;
23    private static final String LOG_TAG = "ChromiumNetwork";
24
25    /**
26     * Native peer object, owned by UrlRequestContext.
27     */
28    private long mUrlRequestContextPeer;
29
30    private final ConditionVariable mStarted = new ConditionVariable();
31
32    /**
33     * Constructor.
34     *
35     */
36    protected UrlRequestContext(Context context, String userAgent,
37            String config) {
38        mUrlRequestContextPeer = nativeCreateRequestContextPeer(context,
39                userAgent, getLoggingLevel(), config);
40        if (mUrlRequestContextPeer == 0)
41            throw new NullPointerException("Context Peer creation failed");
42
43        // TODO(mef): Revisit the need of block here.
44        mStarted.block(2000);
45    }
46
47    /**
48     * Returns the version of this network stack formatted as N.N.N.N/X where
49     * N.N.N.N is the version of Chromium and X is the version of the JNI layer.
50     */
51    public static String getVersion() {
52        return nativeGetVersion();
53    }
54
55    /**
56     * Initializes statistics recorder.
57     */
58    public void initializeStatistics() {
59        nativeInitializeStatistics();
60    }
61
62    /**
63     * Gets current statistics recorded since |initializeStatistics| with
64     * |filter| as a substring as JSON text (an empty |filter| will include all
65     * registered histograms).
66     */
67    public String getStatisticsJSON(String filter) {
68        return nativeGetStatisticsJSON(filter);
69    }
70
71    /**
72     * Starts NetLog logging to a file named |fileName| in the
73     * application temporary directory. |fileName| must not be empty. Log level
74     * is LOG_ALL_BUT_BYTES. If the file exists it is truncated before starting.
75     * If actively logging the call is ignored.
76     */
77    public void startNetLogToFile(String fileName) {
78        nativeStartNetLogToFile(mUrlRequestContextPeer, fileName);
79    }
80
81    /**
82     * Stops NetLog logging and flushes file to disk. If a logging session is
83     * not in progress this call is ignored.
84     */
85    public void stopNetLog() {
86        nativeStopNetLog(mUrlRequestContextPeer);
87    }
88
89    @CalledByNative
90    private void initNetworkThread() {
91        Thread.currentThread().setName("ChromiumNet");
92        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
93        mStarted.open();
94    }
95
96    @Override
97    protected void finalize() throws Throwable {
98        nativeReleaseRequestContextPeer(mUrlRequestContextPeer);
99        super.finalize();
100    }
101
102    protected long getUrlRequestContextPeer() {
103        return mUrlRequestContextPeer;
104    }
105
106    /**
107     * @return loggingLevel see {@link #LOG_NONE}, {@link #LOG_DEBUG} and
108     *         {@link #LOG_VERBOSE}.
109     */
110    private int getLoggingLevel() {
111        int loggingLevel;
112        if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
113            loggingLevel = LOG_VERBOSE;
114        } else if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
115            loggingLevel = LOG_DEBUG;
116        } else {
117            loggingLevel = LOG_NONE;
118        }
119        return loggingLevel;
120    }
121
122    private static native String nativeGetVersion();
123
124    // Returns an instance URLRequestContextPeer to be stored in
125    // mUrlRequestContextPeer.
126    private native long nativeCreateRequestContextPeer(Context context,
127            String userAgent, int loggingLevel, String config);
128
129    private native void nativeReleaseRequestContextPeer(
130            long urlRequestContextPeer);
131
132    private native void nativeInitializeStatistics();
133
134    private native String nativeGetStatisticsJSON(String filter);
135
136    private native void nativeStartNetLogToFile(long urlRequestContextPeer,
137            String fileName);
138
139    private native void nativeStopNetLog(long urlRequestContextPeer);
140}
141