OLD | NEW |
---|---|
(Empty) | |
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 | |
5 #include "net/cronet/android/org_chromium_net_UrlRequestContext.h" | |
6 | |
7 #include <stdio.h> | |
8 | |
9 #include "base/android/base_jni_registrar.h" | |
10 #include "base/android/jni_android.h" | |
11 #include "base/android/jni_registrar.h" | |
12 #include "base/at_exit.h" | |
13 #include "net/android/net_jni_registrar.h" | |
14 #include "net/cronet/android/android_log.h" | |
15 #include "net/cronet/android/url_request_context_peer.h" | |
16 #include "net/cronet/android/url_request_peer.h" | |
17 | |
18 // Version of this build of Chromium NET. | |
19 #define CHROMIUM_NET_VERSION "1" | |
20 | |
21 static const char kVersion[] = CHROMIUM_VERSION "/" CHROMIUM_NET_VERSION; | |
22 | |
23 static jclass g_class; | |
24 static jmethodID g_method_initNetworkThread; | |
25 static jfieldID g_field_mRequestContext; | |
26 | |
27 static base::AtExitManager* s_at_exit_manager = NULL; | |
28 | |
29 /* | |
30 * Checks the available version of JNI. Also, caches Java reflection artifacts. | |
31 */ | |
32 jint JNI_OnLoad(JavaVM* vm, void* reserved) { | |
33 JNIEnv* env; | |
34 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { | |
35 return -1; | |
36 } | |
37 | |
38 const char* class_name = "org/chromium/net/UrlRequestContext"; | |
39 g_class = (jclass) env->NewGlobalRef(env->FindClass(class_name)); | |
40 g_method_initNetworkThread = | |
41 env->GetMethodID(g_class, "initNetworkThread", "()V"); | |
42 g_field_mRequestContext = | |
43 env->GetFieldID(g_class, "mRequestContext", "J"); | |
44 | |
45 base::android::InitVM(vm); | |
46 | |
47 if (!base::android::RegisterJni(env)) | |
48 return -1; | |
49 | |
50 if (!net::android::RegisterJni(env)) { | |
51 return -1; | |
52 } | |
53 | |
54 s_at_exit_manager = new base::AtExitManager(); | |
55 | |
56 return JNI_VERSION_1_6; | |
57 } | |
58 | |
59 JNIEnv* GetEnv(JavaVM* vm) { | |
60 // We need to make sure this native thread is attached to the JVM before | |
61 // we can call any Java methods. | |
62 JNIEnv* env; | |
63 if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) | |
64 == JNI_EDETACHED) { | |
65 vm->AttachCurrentThread(&env, NULL); | |
66 } | |
67 return env; | |
68 } | |
69 | |
70 /* | |
71 * Delegate of URLRequestContextPeer that delivers callbacks to the Java layer. | |
72 */ | |
73 class JniURLRequestContextPeerDelegate : | |
74 public URLRequestContextPeer::URLRequestContextPeerDelegate { | |
75 jobject owner_; | |
76 JavaVM* vm_; | |
77 | |
78 public: | |
79 JniURLRequestContextPeerDelegate(JNIEnv* env, jobject owner) { | |
80 owner_ = env->NewGlobalRef(owner); | |
81 | |
82 env->GetJavaVM(&vm_); | |
83 } | |
84 | |
85 ~JniURLRequestContextPeerDelegate() { | |
86 GetEnv(vm_)->DeleteGlobalRef(owner_); | |
87 } | |
88 | |
89 virtual void OnContextInitialized(URLRequestContextPeer* context) { | |
90 JNIEnv* env = GetEnv(vm_); | |
91 env->CallVoidMethod(owner_, g_method_initNetworkThread); | |
92 if (env->ExceptionOccurred()) { | |
93 env->ExceptionDescribe(); | |
94 env->ExceptionClear(); | |
95 } | |
96 | |
97 // TODO(dplotnikov): figure out if we need to detach from the thread. | |
98 // The documentation says we should detach just before the thread exits. | |
99 } | |
100 }; | |
101 | |
102 /* | |
103 * Stores a reference to the peer in a java field. | |
104 */ | |
105 static void SetNativeObject(JNIEnv *env, jobject object, | |
106 URLRequestContextPeer* peer) { | |
107 env->SetLongField(object, g_field_mRequestContext, | |
108 reinterpret_cast<jlong>(peer)); | |
109 } | |
110 | |
111 /* | |
112 * Returns a reference to the peer, which is stored in a field of | |
113 * the java object. | |
114 */ | |
115 static URLRequestContextPeer* GetNativeObject(JNIEnv* env, jobject object) { | |
116 return reinterpret_cast<URLRequestContextPeer *>( | |
117 env->GetLongField(object, g_field_mRequestContext)); | |
118 } | |
119 | |
120 URLRequestContextPeer* GetURLRequestContextPeer(JNIEnv* env, | |
121 jobject request_context) { | |
122 return GetNativeObject(env, request_context); | |
123 } | |
124 | |
125 JNIEXPORT jstring JNICALL | |
126 Java_org_chromium_net_UrlRequestContext_getVersion( | |
127 JNIEnv* env, jobject object) { | |
128 return env->NewStringUTF(kVersion); | |
129 } | |
130 | |
131 /* | |
132 * Sets global user-agent to be used for all subsequent requests. | |
133 */ | |
134 JNIEXPORT void JNICALL | |
135 Java_org_chromium_net_UrlRequestContext_nativeInitialize( | |
136 JNIEnv* env, | |
137 jobject object, | |
138 jobject context, | |
139 jstring user_agent, | |
140 jint log_level) { | |
141 const char *user_agent_utf8 = env->GetStringUTFChars(user_agent, NULL); | |
142 std::string user_agent_string(user_agent_utf8); | |
143 env->ReleaseStringUTFChars(user_agent, user_agent_utf8); | |
144 | |
145 // Set application context | |
146 base::android::ScopedJavaLocalRef<jobject> scoped_context(env, context); | |
mef
2014/02/04 21:14:11
Setting application context here doesn't seem quit
| |
147 base::android::InitApplicationContext(env, scoped_context); | |
148 | |
149 LoggingLevel logging_level; | |
150 switch (log_level) { | |
151 case 0: | |
152 logging_level = LOG_NONE; | |
153 break; | |
154 case 1: | |
155 logging_level = LOG_DEBUG; | |
156 break; | |
157 case 2: | |
158 logging_level = LOG_VERBOSE; | |
159 break; | |
160 default: | |
161 logging_level = LOG_NONE; | |
162 NOTREACHED(); | |
163 } | |
164 | |
165 // TODO(dplotnikov): set application context | |
166 URLRequestContextPeer* peer = new URLRequestContextPeer( | |
167 new JniURLRequestContextPeerDelegate(env, object), user_agent_string, | |
168 logging_level, kVersion); | |
169 peer->AddRef(); // Hold onto this ref-counted object. | |
170 | |
171 SetNativeObject(env, object, peer); | |
172 | |
173 peer->Initialize(); | |
174 } | |
175 | |
176 /* | |
177 * Releases native objects. | |
178 */ | |
179 JNIEXPORT void JNICALL | |
180 Java_org_chromium_net_UrlRequestContext_nativeFinalize( | |
181 JNIEnv* env, jobject object) { | |
182 // URLRequestContextPeer is a ref-counted object, so we need to release it | |
183 // instead of deleting outright. | |
184 GetNativeObject(env, object)->Release(); | |
185 SetNativeObject(env, object, NULL); | |
186 } | |
OLD | NEW |