OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 23 matching lines...) Expand all Loading... |
34 }; | 34 }; |
35 | 35 |
36 // Android's FindClass() is trickier than usual because the app-specific | 36 // Android's FindClass() is trickier than usual because the app-specific |
37 // ClassLoader is not consulted when there is no app-specific frame on the | 37 // ClassLoader is not consulted when there is no app-specific frame on the |
38 // stack. Consequently, we only look up all classes once in native WebRTC. | 38 // stack. Consequently, we only look up all classes once in native WebRTC. |
39 // http://developer.android.com/training/articles/perf-jni.html#faq_FindClass | 39 // http://developer.android.com/training/articles/perf-jni.html#faq_FindClass |
40 void LoadClasses(JNIEnv* jni) { | 40 void LoadClasses(JNIEnv* jni) { |
41 for (auto& c : loaded_classes) { | 41 for (auto& c : loaded_classes) { |
42 jclass localRef = FindClass(jni, c.name); | 42 jclass localRef = FindClass(jni, c.name); |
43 CHECK_EXCEPTION(jni) << "Error during FindClass: " << c.name; | 43 CHECK_EXCEPTION(jni) << "Error during FindClass: " << c.name; |
44 CHECK(localRef) << c.name; | 44 RTC_CHECK(localRef) << c.name; |
45 jclass globalRef = reinterpret_cast<jclass>(jni->NewGlobalRef(localRef)); | 45 jclass globalRef = reinterpret_cast<jclass>(jni->NewGlobalRef(localRef)); |
46 CHECK_EXCEPTION(jni) << "Error during NewGlobalRef: " << c.name; | 46 CHECK_EXCEPTION(jni) << "Error during NewGlobalRef: " << c.name; |
47 CHECK(globalRef) << c.name; | 47 RTC_CHECK(globalRef) << c.name; |
48 c.clazz = globalRef; | 48 c.clazz = globalRef; |
49 } | 49 } |
50 } | 50 } |
51 | 51 |
52 void FreeClassReferences(JNIEnv* jni) { | 52 void FreeClassReferences(JNIEnv* jni) { |
53 for (auto& c : loaded_classes) { | 53 for (auto& c : loaded_classes) { |
54 jni->DeleteGlobalRef(c.clazz); | 54 jni->DeleteGlobalRef(c.clazz); |
55 c.clazz = nullptr; | 55 c.clazz = nullptr; |
56 } | 56 } |
57 } | 57 } |
58 | 58 |
59 jclass LookUpClass(const char* name) { | 59 jclass LookUpClass(const char* name) { |
60 for (auto& c : loaded_classes) { | 60 for (auto& c : loaded_classes) { |
61 if (strcmp(c.name, name) == 0) | 61 if (strcmp(c.name, name) == 0) |
62 return c.clazz; | 62 return c.clazz; |
63 } | 63 } |
64 CHECK(false) << "Unable to find class in lookup table"; | 64 RTC_CHECK(false) << "Unable to find class in lookup table"; |
65 return 0; | 65 return 0; |
66 } | 66 } |
67 | 67 |
68 // AttachCurrentThreadIfNeeded implementation. | 68 // AttachCurrentThreadIfNeeded implementation. |
69 AttachCurrentThreadIfNeeded::AttachCurrentThreadIfNeeded() | 69 AttachCurrentThreadIfNeeded::AttachCurrentThreadIfNeeded() |
70 : attached_(false) { | 70 : attached_(false) { |
71 ALOGD("AttachCurrentThreadIfNeeded::ctor%s", GetThreadInfo().c_str()); | 71 ALOGD("AttachCurrentThreadIfNeeded::ctor%s", GetThreadInfo().c_str()); |
72 JavaVM* jvm = JVM::GetInstance()->jvm(); | 72 JavaVM* jvm = JVM::GetInstance()->jvm(); |
73 CHECK(jvm); | 73 RTC_CHECK(jvm); |
74 JNIEnv* jni = GetEnv(jvm); | 74 JNIEnv* jni = GetEnv(jvm); |
75 if (!jni) { | 75 if (!jni) { |
76 ALOGD("Attaching thread to JVM"); | 76 ALOGD("Attaching thread to JVM"); |
77 JNIEnv* env = nullptr; | 77 JNIEnv* env = nullptr; |
78 jint ret = jvm->AttachCurrentThread(&env, nullptr); | 78 jint ret = jvm->AttachCurrentThread(&env, nullptr); |
79 attached_ = (ret == JNI_OK); | 79 attached_ = (ret == JNI_OK); |
80 } | 80 } |
81 } | 81 } |
82 | 82 |
83 AttachCurrentThreadIfNeeded::~AttachCurrentThreadIfNeeded() { | 83 AttachCurrentThreadIfNeeded::~AttachCurrentThreadIfNeeded() { |
84 ALOGD("AttachCurrentThreadIfNeeded::dtor%s", GetThreadInfo().c_str()); | 84 ALOGD("AttachCurrentThreadIfNeeded::dtor%s", GetThreadInfo().c_str()); |
85 DCHECK(thread_checker_.CalledOnValidThread()); | 85 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
86 if (attached_) { | 86 if (attached_) { |
87 ALOGD("Detaching thread from JVM"); | 87 ALOGD("Detaching thread from JVM"); |
88 jint res = JVM::GetInstance()->jvm()->DetachCurrentThread(); | 88 jint res = JVM::GetInstance()->jvm()->DetachCurrentThread(); |
89 CHECK(res == JNI_OK) << "DetachCurrentThread failed: " << res; | 89 RTC_CHECK(res == JNI_OK) << "DetachCurrentThread failed: " << res; |
90 } | 90 } |
91 } | 91 } |
92 | 92 |
93 // GlobalRef implementation. | 93 // GlobalRef implementation. |
94 GlobalRef::GlobalRef(JNIEnv* jni, jobject object) | 94 GlobalRef::GlobalRef(JNIEnv* jni, jobject object) |
95 : jni_(jni), j_object_(NewGlobalRef(jni, object)) { | 95 : jni_(jni), j_object_(NewGlobalRef(jni, object)) { |
96 ALOGD("GlobalRef::ctor%s", GetThreadInfo().c_str()); | 96 ALOGD("GlobalRef::ctor%s", GetThreadInfo().c_str()); |
97 } | 97 } |
98 | 98 |
99 GlobalRef::~GlobalRef() { | 99 GlobalRef::~GlobalRef() { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 return res; | 171 return res; |
172 } | 172 } |
173 | 173 |
174 // JNIEnvironment implementation. | 174 // JNIEnvironment implementation. |
175 JNIEnvironment::JNIEnvironment(JNIEnv* jni) : jni_(jni) { | 175 JNIEnvironment::JNIEnvironment(JNIEnv* jni) : jni_(jni) { |
176 ALOGD("JNIEnvironment::ctor%s", GetThreadInfo().c_str()); | 176 ALOGD("JNIEnvironment::ctor%s", GetThreadInfo().c_str()); |
177 } | 177 } |
178 | 178 |
179 JNIEnvironment::~JNIEnvironment() { | 179 JNIEnvironment::~JNIEnvironment() { |
180 ALOGD("JNIEnvironment::dtor%s", GetThreadInfo().c_str()); | 180 ALOGD("JNIEnvironment::dtor%s", GetThreadInfo().c_str()); |
181 DCHECK(thread_checker_.CalledOnValidThread()); | 181 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
182 } | 182 } |
183 | 183 |
184 rtc::scoped_ptr<NativeRegistration> JNIEnvironment::RegisterNatives( | 184 rtc::scoped_ptr<NativeRegistration> JNIEnvironment::RegisterNatives( |
185 const char* name, const JNINativeMethod *methods, int num_methods) { | 185 const char* name, const JNINativeMethod *methods, int num_methods) { |
186 ALOGD("JNIEnvironment::RegisterNatives(%s)", name); | 186 ALOGD("JNIEnvironment::RegisterNatives(%s)", name); |
187 DCHECK(thread_checker_.CalledOnValidThread()); | 187 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
188 jclass clazz = LookUpClass(name); | 188 jclass clazz = LookUpClass(name); |
189 jni_->RegisterNatives(clazz, methods, num_methods); | 189 jni_->RegisterNatives(clazz, methods, num_methods); |
190 CHECK_EXCEPTION(jni_) << "Error during RegisterNatives"; | 190 CHECK_EXCEPTION(jni_) << "Error during RegisterNatives"; |
191 return rtc::scoped_ptr<NativeRegistration>( | 191 return rtc::scoped_ptr<NativeRegistration>( |
192 new NativeRegistration(jni_, clazz)); | 192 new NativeRegistration(jni_, clazz)); |
193 } | 193 } |
194 | 194 |
195 std::string JNIEnvironment::JavaToStdString(const jstring& j_string) { | 195 std::string JNIEnvironment::JavaToStdString(const jstring& j_string) { |
196 DCHECK(thread_checker_.CalledOnValidThread()); | 196 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
197 const char* jchars = jni_->GetStringUTFChars(j_string, nullptr); | 197 const char* jchars = jni_->GetStringUTFChars(j_string, nullptr); |
198 CHECK_EXCEPTION(jni_); | 198 CHECK_EXCEPTION(jni_); |
199 const int size = jni_->GetStringUTFLength(j_string); | 199 const int size = jni_->GetStringUTFLength(j_string); |
200 CHECK_EXCEPTION(jni_); | 200 CHECK_EXCEPTION(jni_); |
201 std::string ret(jchars, size); | 201 std::string ret(jchars, size); |
202 jni_->ReleaseStringUTFChars(j_string, jchars); | 202 jni_->ReleaseStringUTFChars(j_string, jchars); |
203 CHECK_EXCEPTION(jni_); | 203 CHECK_EXCEPTION(jni_); |
204 return ret; | 204 return ret; |
205 } | 205 } |
206 | 206 |
207 // static | 207 // static |
208 void JVM::Initialize(JavaVM* jvm, jobject context) { | 208 void JVM::Initialize(JavaVM* jvm, jobject context) { |
209 ALOGD("JVM::Initialize%s", GetThreadInfo().c_str()); | 209 ALOGD("JVM::Initialize%s", GetThreadInfo().c_str()); |
210 CHECK(!g_jvm); | 210 RTC_CHECK(!g_jvm); |
211 g_jvm = new JVM(jvm, context); | 211 g_jvm = new JVM(jvm, context); |
212 } | 212 } |
213 | 213 |
214 // static | 214 // static |
215 void JVM::Uninitialize() { | 215 void JVM::Uninitialize() { |
216 ALOGD("JVM::Uninitialize%s", GetThreadInfo().c_str()); | 216 ALOGD("JVM::Uninitialize%s", GetThreadInfo().c_str()); |
217 DCHECK(g_jvm); | 217 RTC_DCHECK(g_jvm); |
218 delete g_jvm; | 218 delete g_jvm; |
219 g_jvm = nullptr; | 219 g_jvm = nullptr; |
220 } | 220 } |
221 | 221 |
222 // static | 222 // static |
223 JVM* JVM::GetInstance() { | 223 JVM* JVM::GetInstance() { |
224 DCHECK(g_jvm); | 224 RTC_DCHECK(g_jvm); |
225 return g_jvm; | 225 return g_jvm; |
226 } | 226 } |
227 | 227 |
228 JVM::JVM(JavaVM* jvm, jobject context) | 228 JVM::JVM(JavaVM* jvm, jobject context) |
229 : jvm_(jvm) { | 229 : jvm_(jvm) { |
230 ALOGD("JVM::JVM%s", GetThreadInfo().c_str()); | 230 ALOGD("JVM::JVM%s", GetThreadInfo().c_str()); |
231 CHECK(jni()) << "AttachCurrentThread() must be called on this thread."; | 231 RTC_CHECK(jni()) << "AttachCurrentThread() must be called on this thread."; |
232 context_ = NewGlobalRef(jni(), context); | 232 context_ = NewGlobalRef(jni(), context); |
233 LoadClasses(jni()); | 233 LoadClasses(jni()); |
234 } | 234 } |
235 | 235 |
236 JVM::~JVM() { | 236 JVM::~JVM() { |
237 ALOGD("JVM::~JVM%s", GetThreadInfo().c_str()); | 237 ALOGD("JVM::~JVM%s", GetThreadInfo().c_str()); |
238 DCHECK(thread_checker_.CalledOnValidThread()); | 238 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
239 FreeClassReferences(jni()); | 239 FreeClassReferences(jni()); |
240 DeleteGlobalRef(jni(), context_); | 240 DeleteGlobalRef(jni(), context_); |
241 } | 241 } |
242 | 242 |
243 rtc::scoped_ptr<JNIEnvironment> JVM::environment() { | 243 rtc::scoped_ptr<JNIEnvironment> JVM::environment() { |
244 ALOGD("JVM::environment%s", GetThreadInfo().c_str()); | 244 ALOGD("JVM::environment%s", GetThreadInfo().c_str()); |
245 // The JNIEnv is used for thread-local storage. For this reason, we cannot | 245 // The JNIEnv is used for thread-local storage. For this reason, we cannot |
246 // share a JNIEnv between threads. If a piece of code has no other way to get | 246 // share a JNIEnv between threads. If a piece of code has no other way to get |
247 // its JNIEnv, we should share the JavaVM, and use GetEnv to discover the | 247 // its JNIEnv, we should share the JavaVM, and use GetEnv to discover the |
248 // thread's JNIEnv. (Assuming it has one, if not, use AttachCurrentThread). | 248 // thread's JNIEnv. (Assuming it has one, if not, use AttachCurrentThread). |
249 // See // http://developer.android.com/training/articles/perf-jni.html. | 249 // See // http://developer.android.com/training/articles/perf-jni.html. |
250 JNIEnv* jni = GetEnv(jvm_); | 250 JNIEnv* jni = GetEnv(jvm_); |
251 if (!jni) { | 251 if (!jni) { |
252 ALOGE("AttachCurrentThread() has not been called on this thread."); | 252 ALOGE("AttachCurrentThread() has not been called on this thread."); |
253 return rtc::scoped_ptr<JNIEnvironment>(); | 253 return rtc::scoped_ptr<JNIEnvironment>(); |
254 } | 254 } |
255 return rtc::scoped_ptr<JNIEnvironment>(new JNIEnvironment(jni)); | 255 return rtc::scoped_ptr<JNIEnvironment>(new JNIEnvironment(jni)); |
256 } | 256 } |
257 | 257 |
258 JavaClass JVM::GetClass(const char* name) { | 258 JavaClass JVM::GetClass(const char* name) { |
259 ALOGD("JVM::GetClass(%s)%s", name, GetThreadInfo().c_str()); | 259 ALOGD("JVM::GetClass(%s)%s", name, GetThreadInfo().c_str()); |
260 DCHECK(thread_checker_.CalledOnValidThread()); | 260 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
261 return JavaClass(jni(), LookUpClass(name)); | 261 return JavaClass(jni(), LookUpClass(name)); |
262 } | 262 } |
263 | 263 |
264 } // namespace webrtc | 264 } // namespace webrtc |
OLD | NEW |