Skip to content

Commit af30919

Browse files
fg185036magreenblatt
authored andcommitted
Fix JNI memory leaks (issue chromiumembedded#167)
1 parent 327096b commit af30919

4 files changed

Lines changed: 85 additions & 19 deletions

File tree

native/display_handler.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,31 +23,39 @@ void DisplayHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
2323
JNIEnv* env = GetJNIEnv();
2424
if (!env)
2525
return;
26+
jobject jframe = GetJNIFrame(env, frame);
27+
jstring jurl = NewJNIString(env, url);
2628
JNI_CALL_VOID_METHOD(env, jhandler_, "onAddressChange",
2729
"(Lorg/cef/browser/CefBrowser;Lorg/cef/browser/"
2830
"CefFrame;Ljava/lang/String;)V",
29-
GetJNIBrowser(browser), GetJNIFrame(env, frame),
30-
NewJNIString(env, url));
31+
GetJNIBrowser(browser), jframe,
32+
jurl);
33+
env->DeleteLocalRef(jurl);
34+
env->DeleteLocalRef(jframe);
3135
}
3236

3337
void DisplayHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
3438
const CefString& title) {
3539
JNIEnv* env = GetJNIEnv();
3640
if (!env)
3741
return;
42+
jstring jtitle = NewJNIString(env, title);
3843
JNI_CALL_VOID_METHOD(env, jhandler_, "onTitleChange",
3944
"(Lorg/cef/browser/CefBrowser;Ljava/lang/String;)V",
40-
GetJNIBrowser(browser), NewJNIString(env, title));
45+
GetJNIBrowser(browser), jtitle);
46+
env->DeleteLocalRef(jtitle);
4147
}
4248

4349
bool DisplayHandler::OnTooltip(CefRefPtr<CefBrowser> browser, CefString& text) {
4450
JNIEnv* env = GetJNIEnv();
4551
if (!env)
4652
return false;
4753
jboolean jreturn = JNI_FALSE;
54+
jstring jtext = NewJNIString(env, text);
4855
JNI_CALL_METHOD(env, jhandler_, "onTooltip",
4956
"(Lorg/cef/browser/CefBrowser;Ljava/lang/String;)Z", Boolean,
50-
jreturn, GetJNIBrowser(browser), NewJNIString(env, text));
57+
jreturn, GetJNIBrowser(browser), jtext);
58+
env->DeleteLocalRef(jtext);
5159
return (jreturn != JNI_FALSE);
5260
}
5361

@@ -56,9 +64,11 @@ void DisplayHandler::OnStatusMessage(CefRefPtr<CefBrowser> browser,
5664
JNIEnv* env = GetJNIEnv();
5765
if (!env)
5866
return;
67+
jstring jvalue = NewJNIString(env, value);
5968
JNI_CALL_VOID_METHOD(env, jhandler_, "onStatusMessage",
6069
"(Lorg/cef/browser/CefBrowser;Ljava/lang/String;)V",
61-
GetJNIBrowser(browser), NewJNIString(env, value));
70+
GetJNIBrowser(browser), jvalue);
71+
env->DeleteLocalRef(jvalue);
6272
}
6373

6474
bool DisplayHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
@@ -85,11 +95,15 @@ bool DisplayHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
8595
}
8696

8797
jboolean jreturn = JNI_FALSE;
98+
jstring jmessage = NewJNIString(env, message);
99+
jstring jsource = NewJNIString(env, source);
88100
JNI_CALL_METHOD(
89101
env, jhandler_, "onConsoleMessage",
90102
"(Lorg/cef/browser/CefBrowser;Lorg/cef/CefSettings$LogSeverity;"
91103
"Ljava/lang/String;Ljava/lang/String;I)Z",
92104
Boolean, jreturn, GetJNIBrowser(browser), jlevel,
93-
NewJNIString(env, message), NewJNIString(env, source), line);
105+
jmessage, jsource, line);
106+
env->DeleteLocalRef(jsource);
107+
env->DeleteLocalRef(jmessage);
94108
return (jreturn != JNI_FALSE);
95109
}

native/jni_util.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,10 @@ bool SetCefForJNIObject(JNIEnv* env,
333333
jobject obj,
334334
T* base,
335335
const char* varName) {
336-
jstring identifer = env->NewStringUTF(varName);
337-
jlong previousValue = 0;
338336
if (!obj)
339337
return false;
338+
jstring identifer = env->NewStringUTF(varName);
339+
jlong previousValue = 0;
340340
JNI_CALL_METHOD(env, obj, "getNativeRef", "(Ljava/lang/String;)J", Long,
341341
previousValue, identifer);
342342

@@ -352,6 +352,7 @@ bool SetCefForJNIObject(JNIEnv* env,
352352
// Add a reference to the new base object.
353353
SetCefForJNIObjectHelper::AddRef(base);
354354
}
355+
env->DeleteLocalRef(identifer);
355356
return true;
356357
}
357358

@@ -364,6 +365,7 @@ T* GetCefFromJNIObject(JNIEnv* env, jobject obj, const char* varName) {
364365
JNI_CALL_METHOD(env, obj, "getNativeRef", "(Ljava/lang/String;)J", Long,
365366
previousValue, identifer);
366367

368+
env->DeleteLocalRef(identifer);
367369
if (previousValue != 0)
368370
return reinterpret_cast<T*>(previousValue);
369371
return NULL;

native/load_handler.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,20 @@ void LoadHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
3939
if (!env)
4040
return;
4141

42+
jobject jframe = GetJNIFrame(env, frame);
43+
4244
jobject jtransitionType = NewJNITransitionType(env, transition_type);
4345
if (!jtransitionType)
4446
return;
4547

4648
JNI_CALL_VOID_METHOD(env, jhandler_, "onLoadStart",
4749
"(Lorg/cef/browser/CefBrowser;Lorg/cef/browser/"
4850
"CefFrame;Lorg/cef/network/CefRequest$TransitionType;)V",
49-
GetJNIBrowser(browser), GetJNIFrame(env, frame),
51+
GetJNIBrowser(browser), jframe,
5052
jtransitionType);
53+
54+
if (jframe)
55+
env->DeleteLocalRef(jframe);
5156
}
5257

5358
void LoadHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
@@ -56,10 +61,16 @@ void LoadHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
5661
JNIEnv* env = GetJNIEnv();
5762
if (!env)
5863
return;
64+
65+
jobject jframe = GetJNIFrame(env, frame);
66+
5967
JNI_CALL_VOID_METHOD(
6068
env, jhandler_, "onLoadEnd",
6169
"(Lorg/cef/browser/CefBrowser;Lorg/cef/browser/CefFrame;I)V",
62-
GetJNIBrowser(browser), GetJNIFrame(env, frame), httpStatusCode);
70+
GetJNIBrowser(browser), jframe, httpStatusCode);
71+
72+
if (jframe)
73+
env->DeleteLocalRef(jframe);
6374
}
6475

6576
void LoadHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
@@ -70,11 +81,21 @@ void LoadHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
7081
JNIEnv* env = GetJNIEnv();
7182
if (!env)
7283
return;
84+
85+
jobject jframe = GetJNIFrame(env, frame);
86+
jobject jerrorText = NewJNIString(env, errorText);
87+
jobject jfailedUrl = NewJNIString(env, failedUrl);
88+
7389
JNI_CALL_VOID_METHOD(
7490
env, jhandler_, "onLoadError",
7591
"(Lorg/cef/browser/CefBrowser;Lorg/cef/browser/CefFrame;Lorg/cef/handler/"
7692
"CefLoadHandler$ErrorCode;Ljava/lang/String;Ljava/lang/String;)V",
77-
GetJNIBrowser(browser), GetJNIFrame(env, frame),
78-
NewJNIErrorCode(env, errorCode), NewJNIString(env, errorText),
79-
NewJNIString(env, failedUrl));
93+
GetJNIBrowser(browser), jframe,
94+
NewJNIErrorCode(env, errorCode), jerrorText,
95+
jfailedUrl);
96+
97+
env->DeleteLocalRef(jfailedUrl);
98+
env->DeleteLocalRef(jerrorText);
99+
if (jframe)
100+
env->DeleteLocalRef(jframe);
80101
}

native/request_handler.cpp

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ bool RequestHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
5151

5252
SetCefForJNIObject<CefRequest>(env, jframe, NULL, "CefFrame");
5353
SetCefForJNIObject<CefRequest>(env, jrequest, NULL, "CefRequest");
54+
env->DeleteLocalRef(jframe);
55+
env->DeleteLocalRef(jrequest);
5456
return (result != JNI_FALSE);
5557
}
5658

@@ -81,6 +83,8 @@ RequestHandler::ReturnValue RequestHandler::OnBeforeResourceLoad(
8183

8284
SetCefForJNIObject<CefRequest>(env, jframe, NULL, "CefFrame");
8385
SetCefForJNIObject<CefRequest>(env, jrequest, NULL, "CefRequest");
86+
env->DeleteLocalRef(jframe);
87+
env->DeleteLocalRef(jrequest);
8488
return (result != JNI_FALSE) ? RV_CANCEL : RV_CONTINUE;
8589
}
8690

@@ -97,8 +101,10 @@ CefRefPtr<CefResourceHandler> RequestHandler::GetResourceHandler(
97101
return NULL;
98102

99103
jobject jrequest = NewJNIObject(env, "org/cef/network/CefRequest_N");
100-
if (!jrequest)
104+
if (!jrequest) {
105+
env->DeleteLocalRef(jframe);
101106
return NULL;
107+
}
102108
SetCefForJNIObject(env, jrequest, request.get(), "CefRequest");
103109

104110
jobject jhandler = NULL;
@@ -107,15 +113,20 @@ CefRefPtr<CefResourceHandler> RequestHandler::GetResourceHandler(
107113
"cef/network/CefRequest;)"
108114
"Lorg/cef/handler/CefResourceHandler;",
109115
Object, jhandler, GetJNIBrowser(browser), jframe, jrequest);
110-
if (!jhandler)
116+
if (!jhandler) {
117+
env->DeleteLocalRef(jframe);
118+
env->DeleteLocalRef(jrequest);
111119
return NULL;
120+
}
112121
CefRefPtr<CefResourceHandler> handler = NULL;
113122
handler = GetCefFromJNIObject<CefResourceHandler>(env, jhandler,
114123
"CefResourceHandler");
115124
if (!handler.get()) {
116125
handler = new ResourceHandler(env, jhandler);
117126
SetCefForJNIObject(env, jhandler, handler.get(), "CefResourceHandler");
118127
}
128+
env->DeleteLocalRef(jframe);
129+
env->DeleteLocalRef(jrequest);
119130
return handler;
120131
}
121132

@@ -165,13 +176,19 @@ bool RequestHandler::OnResourceResponse(CefRefPtr<CefBrowser> browser,
165176
return false;
166177

167178
jobject jrequest = NewJNIObject(env, "org/cef/network/CefRequest_N");
168-
if (!jrequest)
179+
if (!jrequest) {
180+
env->DeleteLocalRef(jframe);
169181
return false;
182+
}
170183
SetCefForJNIObject(env, jrequest, request.get(), "CefRequest");
171184

172185
jobject jresponse = NewJNIObject(env, "org/cef/network/CefResponse_N");
173-
if (!jresponse)
186+
if (!jresponse) {
187+
SetCefForJNIObject<CefRequest>(env, jrequest, NULL, "CefRequest");
188+
env->DeleteLocalRef(jframe);
189+
env->DeleteLocalRef(jrequest);
174190
return false;
191+
}
175192
SetCefForJNIObject(env, jresponse, response.get(), "CefResponse");
176193

177194
jboolean result = JNI_FALSE;
@@ -184,6 +201,9 @@ bool RequestHandler::OnResourceResponse(CefRefPtr<CefBrowser> browser,
184201
SetCefForJNIObject<CefRequest>(env, jframe, NULL, "CefFrame");
185202
SetCefForJNIObject<CefRequest>(env, jrequest, NULL, "CefRequest");
186203
SetCefForJNIObject<CefRequest>(env, jresponse, NULL, "CefResponse");
204+
env->DeleteLocalRef(jframe);
205+
env->DeleteLocalRef(jrequest);
206+
env->DeleteLocalRef(jresponse);
187207
return (result != JNI_FALSE);
188208
}
189209

@@ -203,13 +223,19 @@ void RequestHandler::OnResourceLoadComplete(
203223
return;
204224

205225
jobject jrequest = NewJNIObject(env, "org/cef/network/CefRequest_N");
206-
if (!jrequest)
226+
if (!jrequest) {
227+
env->DeleteLocalRef(jframe);
207228
return;
229+
}
208230
SetCefForJNIObject(env, jrequest, request.get(), "CefRequest");
209231

210232
jobject jresponse = NewJNIObject(env, "org/cef/network/CefResponse_N");
211-
if (!jresponse)
233+
if (!jresponse) {
234+
SetCefForJNIObject<CefRequest>(env, jrequest, NULL, "CefRequest");
235+
env->DeleteLocalRef(jframe);
236+
env->DeleteLocalRef(jrequest);
212237
return;
238+
}
213239
SetCefForJNIObject(env, jresponse, response.get(), "CefResponse");
214240

215241
jobject jstatus = NewJNIURLRequestStatus(env, status);
@@ -227,6 +253,9 @@ void RequestHandler::OnResourceLoadComplete(
227253
SetCefForJNIObject<CefRequest>(env, jframe, NULL, "CefFrame");
228254
SetCefForJNIObject<CefRequest>(env, jrequest, NULL, "CefRequest");
229255
SetCefForJNIObject<CefRequest>(env, jresponse, NULL, "CefResponse");
256+
env->DeleteLocalRef(jframe);
257+
env->DeleteLocalRef(jrequest);
258+
env->DeleteLocalRef(jresponse);
230259
}
231260

232261
bool RequestHandler::GetAuthCredentials(CefRefPtr<CefBrowser> browser,

0 commit comments

Comments
 (0)