9
9
10
10
namespace {
11
11
12
+ // Retrieves the JNIEnv for the current thread. Attaches the VM to the current
13
+ // thread if necessary. Sets |mustDetach| to true if DetachJNIEnv must be
14
+ // called.
15
+ jint GetJNIEnv (JNIEnv** env, bool * mustDetach) {
16
+ *env = nullptr ;
17
+ *mustDetach = false ;
18
+
19
+ JavaVM* jvm = GetJVM ();
20
+ if (!jvm)
21
+ return JNI_ERR;
22
+
23
+ jint result = jvm->GetEnv ((void **)env, JNI_VERSION_1_6);
24
+ if (result == JNI_EDETACHED) {
25
+ result = jvm->AttachCurrentThreadAsDaemon ((void **)env, NULL );
26
+ if (result == JNI_OK) {
27
+ *mustDetach = true ;
28
+ }
29
+ }
30
+
31
+ return result;
32
+ }
33
+
34
+ // Detaches the current thread from the VM. Should only be called if
35
+ // |mustDetach| was set to true by GetJNIEnv.
36
+ void DetachJNIEnv () {
37
+ JavaVM* jvm = GetJVM ();
38
+ if (jvm) {
39
+ jvm->DetachCurrentThread ();
40
+ }
41
+ }
42
+
12
43
// Returns a class with the given fully qualified |class_name| (with '/' as
13
44
// separator).
14
45
jclass FindClass (JNIEnv* env, const char * class_name) {
@@ -139,6 +170,45 @@ jobject GetJNIBrowser(JNIEnv* env, CefRefPtr<CefBrowser> browser) {
139
170
140
171
} // namespace
141
172
173
+ // static
174
+ const int ScopedJNIEnv::kDefaultLocalCapacity = 1024 ;
175
+
176
+ ScopedJNIEnv::ScopedJNIEnv (jint local_capacity)
177
+ : ScopedJNIEnv(nullptr , local_capacity) {}
178
+
179
+ ScopedJNIEnv::ScopedJNIEnv (JNIEnv* env, jint local_capacity)
180
+ : jenv_(env), local_capacity_(local_capacity) {
181
+ if (!jenv_) {
182
+ if (GetJNIEnv (&jenv_, &should_detach_) != JNI_OK || !jenv_) {
183
+ NOTREACHED () << " Failed to retrieve JNIEnv" ;
184
+ return ;
185
+ }
186
+ }
187
+ if (local_capacity_ > 0 ) {
188
+ if (jenv_->EnsureLocalCapacity (local_capacity_) != JNI_OK ||
189
+ jenv_->PushLocalFrame (local_capacity_) != JNI_OK) {
190
+ LOG (WARNING) << " Failed to create local frame with capacity "
191
+ << local_capacity_;
192
+ local_capacity_ = 0 ;
193
+ }
194
+ }
195
+ }
196
+
197
+ ScopedJNIEnv::~ScopedJNIEnv () {
198
+ if (!jenv_)
199
+ return ;
200
+ if (local_capacity_ > 0 ) {
201
+ if (export_result_) {
202
+ *export_result_ = jenv_->PopLocalFrame (*export_result_);
203
+ } else {
204
+ jenv_->PopLocalFrame (NULL );
205
+ }
206
+ }
207
+ if (should_detach_) {
208
+ DetachJNIEnv ();
209
+ }
210
+ }
211
+
142
212
ScopedJNIObjectGlobal::ScopedJNIObjectGlobal (JNIEnv* env, jobject handle)
143
213
: jhandle_(NULL ) {
144
214
if (handle) {
@@ -149,9 +219,9 @@ ScopedJNIObjectGlobal::ScopedJNIObjectGlobal(JNIEnv* env, jobject handle)
149
219
150
220
ScopedJNIObjectGlobal::~ScopedJNIObjectGlobal () {
151
221
if (jhandle_) {
152
- BEGIN_ENV ( env) ;
153
- env-> DeleteGlobalRef (jhandle_);
154
- END_ENV ( env);
222
+ ScopedJNIEnv env;
223
+ if (env)
224
+ env-> DeleteGlobalRef (jhandle_ );
155
225
}
156
226
}
157
227
0 commit comments