blob: eb4cf1dce9d0bc4a7a2ab5adc439334e6bcd19e5 [file] [log] [blame]
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "request_handler.h"
#include "client_handler.h"
#include "jni_util.h"
#include "resource_handler.h"
#include "resource_request_handler.h"
#include "util.h"
#include "include/base/cef_logging.h"
namespace {
jobject NewCefX509Certificate(JNIEnv_* env,
CefRefPtr<CefX509Certificate> ssl_info) {
ScopedJNIClass byteArrayCls(env, env->FindClass("[B"));
if (!byteArrayCls) {
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
return nullptr;
}
CefX509Certificate::IssuerChainBinaryList der_chain;
ssl_info->GetDEREncodedIssuerChain(der_chain);
der_chain.insert(der_chain.begin(), ssl_info->GetDEREncoded());
ScopedJNIObjectLocal certificatesChain(
env, env->NewObjectArray(static_cast<int>(der_chain.size()),
byteArrayCls, nullptr));
for (size_t i = 0; i < der_chain.size(); ++i) {
const auto& der_cert = der_chain[i];
ScopedJNIObjectLocal derArray(
env, env->NewByteArray((jsize)der_cert->GetSize()));
{
void* buf = env->GetPrimitiveArrayCritical((jarray)derArray.get(), 0);
der_cert->GetData(buf, der_cert->GetSize(), 0);
env->ReleasePrimitiveArrayCritical((jarray)derArray.get(), buf, 0);
}
env->SetObjectArrayElement((jobjectArray)certificatesChain.get(), (jsize)i,
derArray);
}
return NewJNIObject(env, "org/cef/security/CefX509Certificate", "([[B)V",
certificatesChain.get());
}
jobject NewCefSSLInfo(JNIEnv_* env, CefRefPtr<CefSSLInfo> ssl_info) {
ScopedJNIObjectLocal certificate(
env, NewCefX509Certificate(env, ssl_info->GetX509Certificate()));
return NewJNIObject(env, "org/cef/security/CefSSLInfo",
"(ILorg/cef/security/CefX509Certificate;)V",
ssl_info.get()->GetCertStatus(), certificate.get());
}
} // namespace
RequestHandler::RequestHandler(JNIEnv* env, jobject handler)
: handle_(env, handler) {}
bool RequestHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool user_gesture,
bool is_redirect) {
// Forward request to ClientHandler to make the message_router_ happy.
CefRefPtr<ClientHandler> client =
(ClientHandler*)browser->GetHost()->GetClient().get();
client->OnBeforeBrowse(browser, frame);
ScopedJNIEnv env;
if (!env)
return false;
ScopedJNIBrowser jbrowser(env, browser);
ScopedJNIFrame jframe(env, frame);
jframe.SetTemporary();
ScopedJNIRequest jrequest(env, request);
jrequest.SetTemporary();
jboolean jresult = JNI_FALSE;
JNI_CALL_METHOD(env, handle_, "onBeforeBrowse",
"(Lorg/cef/browser/CefBrowser;Lorg/cef/browser/CefFrame;Lorg/"
"cef/network/CefRequest;ZZ)Z",
Boolean, jresult, jbrowser.get(), jframe.get(),
jrequest.get(), (user_gesture ? JNI_TRUE : JNI_FALSE),
(is_redirect ? JNI_TRUE : JNI_FALSE));
return (jresult != JNI_FALSE);
}
bool RequestHandler::OnOpenURLFromTab(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& target_url,
WindowOpenDisposition target_disposition,
bool user_gesture) {
ScopedJNIEnv env;
if (!env)
return false;
ScopedJNIBrowser jbrowser(env, browser);
ScopedJNIFrame jframe(env, frame);
jframe.SetTemporary();
ScopedJNIString jtargetUrl(env, target_url);
jboolean jresult = JNI_FALSE;
JNI_CALL_METHOD(env, handle_, "onOpenURLFromTab",
"(Lorg/cef/browser/CefBrowser;Lorg/cef/browser/CefFrame;"
"Ljava/lang/String;Z)Z",
Boolean, jresult, jbrowser.get(), jframe.get(),
jtargetUrl.get(), (user_gesture ? JNI_TRUE : JNI_FALSE));
return (jresult != JNI_FALSE);
}
CefRefPtr<CefResourceRequestHandler> RequestHandler::GetResourceRequestHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_navigation,
bool is_download,
const CefString& request_initiator,
bool& disable_default_handling) {
ScopedJNIEnv env;
if (!env)
return nullptr;
ScopedJNIBrowser jbrowser(env, browser);
ScopedJNIFrame jframe(env, frame);
jframe.SetTemporary();
ScopedJNIRequest jrequest(env, request);
jrequest.SetTemporary();
ScopedJNIString jrequestInitiator(env, request_initiator);
ScopedJNIBoolRef jdisableDefaultHandling(env, disable_default_handling);
ScopedJNIObjectResult jresult(env);
JNI_CALL_METHOD(env, handle_, "getResourceRequestHandler",
"(Lorg/cef/browser/CefBrowser;Lorg/cef/browser/CefFrame;Lorg/"
"cef/network/CefRequest;ZZLjava/lang/String;Lorg/cef/misc/"
"BoolRef;)Lorg/cef/handler/CefResourceRequestHandler;",
Object, jresult, jbrowser.get(), jframe.get(), jrequest.get(),
is_navigation ? JNI_TRUE : JNI_FALSE,
is_download ? JNI_TRUE : JNI_FALSE, jrequestInitiator.get(),
jdisableDefaultHandling.get());
disable_default_handling = jdisableDefaultHandling;
if (jresult)
return new ResourceRequestHandler(env, jresult);
return nullptr;
}
bool RequestHandler::GetAuthCredentials(CefRefPtr<CefBrowser> browser,
const CefString& origin_url,
bool isProxy,
const CefString& host,
int port,
const CefString& realm,
const CefString& scheme,
CefRefPtr<CefAuthCallback> callback) {
ScopedJNIEnv env;
if (!env)
return false;
ScopedJNIBrowser jbrowser(env, browser);
ScopedJNIString joriginUrl(env, origin_url);
ScopedJNIString jhost(env, host);
ScopedJNIString jrealm(env, host);
ScopedJNIString jscheme(env, host);
ScopedJNIAuthCallback jcallback(env, callback);
jboolean jresult = JNI_FALSE;
JNI_CALL_METHOD(
env, handle_, "getAuthCredentials",
"(Lorg/cef/browser/CefBrowser;Ljava/lang/String;ZLjava/lang/String;"
"ILjava/lang/String;Ljava/lang/String;"
"Lorg/cef/callback/CefAuthCallback;)Z",
Boolean, jresult, jbrowser.get(), joriginUrl.get(),
(isProxy ? JNI_TRUE : JNI_FALSE), jhost.get(), port, jrealm.get(),
jscheme.get(), jcallback.get());
if (jresult == JNI_FALSE) {
// If the Java method returns "false" the callback won't be used and
// the reference can therefore be removed.
jcallback.SetTemporary();
}
return (jresult != JNI_FALSE);
}
bool RequestHandler::OnCertificateError(CefRefPtr<CefBrowser> browser,
cef_errorcode_t cert_error,
const CefString& request_url,
CefRefPtr<CefSSLInfo> ssl_info,
CefRefPtr<CefCallback> callback) {
ScopedJNIEnv env;
if (!env)
return false;
ScopedJNIBrowser jbrowser(env, browser);
ScopedJNIObjectLocal jcertError(env, NewJNIErrorCode(env, cert_error));
ScopedJNIString jrequestUrl(env, request_url);
ScopedJNIObjectLocal jSSLInfo(env, NewCefSSLInfo(env, ssl_info));
ScopedJNICallback jcallback(env, callback);
jboolean jresult = JNI_FALSE;
JNI_CALL_METHOD(
env, handle_, "onCertificateError",
"(Lorg/cef/browser/CefBrowser;Lorg/cef/handler/CefLoadHandler$ErrorCode;"
"Ljava/lang/String;Lorg/cef/security/CefSSLInfo;Lorg/cef/callback/"
"CefCallback;)Z",
Boolean, jresult, jbrowser.get(), jcertError.get(), jrequestUrl.get(),
jSSLInfo.get(), jcallback.get());
if (jresult == JNI_FALSE) {
// If the Java method returns "false" the callback won't be used and
// the reference can therefore be removed.
jcallback.SetTemporary();
}
return (jresult != JNI_FALSE);
}
void RequestHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
TerminationStatus status) {
// Forward request to ClientHandler to make the message_router_ happy.
CefRefPtr<ClientHandler> client =
(ClientHandler*)browser->GetHost()->GetClient().get();
client->OnRenderProcessTerminated(browser);
ScopedJNIEnv env;
if (!env)
return;
ScopedJNIBrowser jbrowser(env, browser);
ScopedJNIObjectResult jstatus(env);
switch (status) {
JNI_CASE(env, "org/cef/handler/CefRequestHandler$TerminationStatus",
TS_ABNORMAL_TERMINATION, jstatus);
JNI_CASE(env, "org/cef/handler/CefRequestHandler$TerminationStatus",
TS_PROCESS_WAS_KILLED, jstatus);
JNI_CASE(env, "org/cef/handler/CefRequestHandler$TerminationStatus",
TS_PROCESS_CRASHED, jstatus);
JNI_CASE(env, "org/cef/handler/CefRequestHandler$TerminationStatus",
TS_PROCESS_OOM, jstatus);
}
JNI_CALL_VOID_METHOD(
env, handle_, "onRenderProcessTerminated",
"(Lorg/cef/browser/CefBrowser;"
"Lorg/cef/handler/CefRequestHandler$TerminationStatus;)V",
jbrowser.get(), jstatus.get());
}