// Copyright (c) 2013 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 "jni_util.h" #include "client_handler.h" #include #include "util.h" namespace { JavaVM *g_jvm = NULL; } // namespace void SetJVM(JavaVM* jvm) { ASSERT(!g_jvm); g_jvm = jvm; } JNIEnv* GetJNIEnv() { JNIEnv *env = NULL; if (g_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) == JNI_EDETACHED && g_jvm->AttachCurrentThread((void**)&env, NULL) != JNI_OK) { return NULL; } return env; } // Determines whether the current thread is already attached to the VM, // and tells the caller if it needs to later DetachCurrentThread. // // CALL THIS ONCE WITHIN A FUNCTION SCOPE and use a local boolean // for mustDetach; if you do not, the first call might attach, setting // mustDetach to true, but the second will misleadingly set mustDetach // to false, leaving a dangling JNIEnv. jint GetJNIEnv(JNIEnv **env, bool *mustDetach) { jint getEnvErr = JNI_OK; *mustDetach = false; if (g_jvm) { getEnvErr = g_jvm->GetEnv((void **)env, JNI_VERSION_1_4); if (getEnvErr == JNI_EDETACHED) { getEnvErr = g_jvm->AttachCurrentThread((void **)env, NULL); if (getEnvErr == JNI_OK) { *mustDetach = true; } } } return getEnvErr; } void DetachFromThread(bool *mustDetach) { if (!g_jvm) { return; } if (*mustDetach) g_jvm->DetachCurrentThread(); } jobject NewJNIObject(JNIEnv* env, jclass cls) { jmethodID initID = env->GetMethodID(cls, "", "()V"); if(initID == 0) { env->ExceptionClear(); return NULL; } jobject obj = env->NewObject(cls, initID); if(obj == NULL) { env->ExceptionClear(); return NULL; } return obj; } jobject NewJNIObject(JNIEnv* env, const char* class_name) { jclass cls = env->FindClass(class_name); if (!cls) return NULL; return NewJNIObject(env, cls); } jobject NewJNIObject(JNIEnv* env, const char* class_name, const char* sig, ...) { jclass cls = env->FindClass(class_name); if (!cls) return NULL; jmethodID initID = env->GetMethodID(cls, "", sig); if (initID == 0) { env->ExceptionClear(); return NULL; } va_list ap; va_start(ap, sig); jobject obj = env->NewObjectV(cls, initID, ap); if (obj == NULL) { env->ExceptionClear(); return NULL; } return obj; } jobject NewJNIBoolRef(JNIEnv* env, bool initValue) { jobject jboolRef = NewJNIObject(env, "org/cef/misc/BoolRef"); if (!jboolRef) return NULL; SetJNIBoolRef(env, jboolRef, initValue); return jboolRef; } jobject NewJNIIntRef(JNIEnv* env, int initValue) { jobject jintRef = NewJNIObject(env, "org/cef/misc/IntRef"); if (!jintRef) return NULL; SetJNIIntRef(env, jintRef, initValue); return jintRef; } jobject NewJNIStringRef(JNIEnv* env, const CefString& initValue) { jobject jstringRef = NewJNIObject(env, "org/cef/misc/StringRef"); if (!jstringRef) return NULL; SetJNIStringRef(env, jstringRef, initValue); return jstringRef; } bool GetJNIBoolRef(JNIEnv* env, jobject jboolRef) { jboolean boolRefRes = JNI_FALSE; JNI_CALL_METHOD(env, jboolRef, "get", "()Z", Boolean, boolRefRes); return (boolRefRes != JNI_FALSE); } int GetJNIIntRef(JNIEnv* env, jobject jintRef) { jint intRefRes = -1; JNI_CALL_METHOD(env, jintRef, "get", "()I", Int, intRefRes); return intRefRes; } CefString GetJNIStringRef(JNIEnv* env, jobject jstringRef) { jobject jstr = NULL; JNI_CALL_METHOD(env, jstringRef, "get", "()Ljava/lang/String;", Object, jstr); return GetJNIString(env, (jstring)jstr); } void SetJNIBoolRef(JNIEnv* env, jobject jboolRef, bool boolValue) { JNI_CALL_VOID_METHOD(env, jboolRef, "set", "(Z)V", (boolValue ? JNI_TRUE : JNI_FALSE)); } void SetJNIIntRef(JNIEnv* env, jobject jintRef, int intValue) { JNI_CALL_VOID_METHOD(env, jintRef, "set", "(I)V", intValue); } void SetJNIStringRef(JNIEnv* env, jobject jstringRef, const CefString& stringValue) { JNI_CALL_VOID_METHOD(env, jstringRef, "set", "(Ljava/lang/String;)V", NewJNIString(env, stringValue)); } jobject NewJNIDate(JNIEnv* env, const CefTime& time) { jobject jdate = NewJNIObject(env, "java/util/Date"); if (!jdate) return NULL; double timestamp = time.GetDoubleT() * 1000; JNI_CALL_VOID_METHOD(env, jdate, "setTime", "(J)V",(jlong)timestamp); return jdate; } jobject NewJNICookie(JNIEnv* env, const CefCookie& cookie) { bool hasExpires = (cookie.has_expires != 0); jobject jExpiresDate = hasExpires ? NewJNIDate(env, cookie.expires) : NULL; jobject jcookie = NewJNIObject(env, "org/cef/network/CefCookie", "(Ljava/lang/String;Ljava/lang/String;" "Ljava/lang/String;Ljava/lang/String;" "ZZLjava/util/Date;Ljava/util/Date;" "ZLjava/util/Date;)V", NewJNIString(env, CefString(&cookie.name)), NewJNIString(env, CefString(&cookie.value)), NewJNIString(env, CefString(&cookie.domain)), NewJNIString(env, CefString(&cookie.path)), (cookie.secure != 0 ? JNI_TRUE : JNI_FALSE), (cookie.httponly != 0 ? JNI_TRUE : JNI_FALSE), NewJNIDate(env, cookie.creation), NewJNIDate(env, cookie.last_access), (hasExpires ? JNI_TRUE : JNI_FALSE), jExpiresDate); return jcookie; } CefCookie GetJNICookie(JNIEnv* env, jobject jcookie) { CefCookie cookie; jclass cls = env->FindClass("org/cef/network/CefCookie"); if (!cls) return cookie; CefString name(&cookie.name); CefString value(&cookie.value); CefString domain(&cookie.domain); CefString path(&cookie.path); CefTime creation, lastAccess, expires; GetJNIFieldString(env, cls, jcookie, "name", &name); GetJNIFieldString(env, cls, jcookie, "value", &value); GetJNIFieldString(env, cls, jcookie, "domain", &domain); GetJNIFieldString(env, cls, jcookie, "path", &path); GetJNIFieldBoolean(env, cls, jcookie, "secure", &cookie.secure); GetJNIFieldBoolean(env, cls, jcookie, "httponly", &cookie.httponly); GetJNIFieldDate(env, cls, jcookie, "creation", &creation); cookie.creation = creation; GetJNIFieldDate(env, cls, jcookie, "lastAccess", &lastAccess); cookie.last_access = lastAccess; GetJNIFieldBoolean(env, cls, jcookie, "hasExpires", &cookie.has_expires); GetJNIFieldDate(env, cls, jcookie, "expires", &expires); cookie.expires = expires; return cookie; } CefString GetJNIString(JNIEnv* env, jstring jstr) { CefString cef_str; const char* chr = NULL; if(jstr) chr = env->GetStringUTFChars(jstr, NULL); if(chr) cef_str = chr; if(jstr) env->ReleaseStringUTFChars(jstr, chr); return cef_str; } void GetJNIStringArray(JNIEnv* env, jobjectArray jarray, std::vector& vals) { jsize argc = env->GetArrayLength(jarray); for (jsize i = 0; i < argc; ++i) { jstring jstr = (jstring)env->GetObjectArrayElement(jarray, i); const char* cstr = env->GetStringUTFChars(jstr, NULL); CefString cef_str(cstr); vals.push_back(cef_str); env->ReleaseStringUTFChars(jstr, cstr); } } CefMessageRouterConfig GetJNIMessageRouterConfig(JNIEnv* env, jobject jConfig) { CefMessageRouterConfig config; if (jConfig == NULL) return config; jclass cls = env->FindClass("org/cef/browser/CefMessageRouter$CefMessageRouterConfig"); if (cls == NULL) return config; GetJNIFieldString(env, cls, jConfig, "jsQueryFunction", &config.js_query_function); GetJNIFieldString(env, cls, jConfig, "jsCancelFunction", &config.js_cancel_function); return config; } CefMessageRouterConfig GetJNIMessageRouterConfigFromRouter(JNIEnv* env, jobject jRouter) { jobject jrouterConfig = NULL; JNI_CALL_METHOD(env, jRouter, "getMessageRouterConfig", "()Lorg/cef/browser/CefMessageRouter$CefMessageRouterConfig;", Object, jrouterConfig); return GetJNIMessageRouterConfig(env, jrouterConfig); } jobject NewJNIErrorCode(JNIEnv* env, cef_errorcode_t errorCode) { jobject jerrorCode = NULL; switch (errorCode) { default: JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_NONE, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_FAILED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_ABORTED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_INVALID_ARGUMENT, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_INVALID_HANDLE, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_FILE_NOT_FOUND, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_TIMED_OUT, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_FILE_TOO_BIG, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_UNEXPECTED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_ACCESS_DENIED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_NOT_IMPLEMENTED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CONNECTION_CLOSED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CONNECTION_RESET, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CONNECTION_REFUSED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CONNECTION_ABORTED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CONNECTION_FAILED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_NAME_NOT_RESOLVED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_INTERNET_DISCONNECTED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_SSL_PROTOCOL_ERROR, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_ADDRESS_INVALID, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_ADDRESS_UNREACHABLE, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_SSL_CLIENT_AUTH_CERT_NEEDED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_TUNNEL_CONNECTION_FAILED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_NO_SSL_VERSIONS_ENABLED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_SSL_VERSION_OR_CIPHER_MISMATCH, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_SSL_RENEGOTIATION_REQUESTED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CERT_COMMON_NAME_INVALID, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CERT_DATE_INVALID, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CERT_AUTHORITY_INVALID, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CERT_CONTAINS_ERRORS, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CERT_NO_REVOCATION_MECHANISM, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CERT_UNABLE_TO_CHECK_REVOCATION, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CERT_REVOKED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CERT_INVALID, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CERT_END, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_INVALID_URL, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_DISALLOWED_URL_SCHEME, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_UNKNOWN_URL_SCHEME, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_TOO_MANY_REDIRECTS, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_UNSAFE_REDIRECT, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_UNSAFE_PORT, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_INVALID_RESPONSE, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_INVALID_CHUNKED_ENCODING, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_METHOD_NOT_SUPPORTED, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_UNEXPECTED_PROXY_AUTH, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_EMPTY_RESPONSE, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_RESPONSE_HEADERS_TOO_BIG, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_CACHE_MISS, jerrorCode); JNI_CASE(env, "org/cef/handler/CefLoadHandler$ErrorCode", ERR_INSECURE_RESPONSE, jerrorCode); } return jerrorCode; } jstring NewJNIString(JNIEnv* env, const CefString& str) { std::string cstr(str); return env->NewStringUTF(cstr.c_str()); } jobjectArray NewJNIStringArray(JNIEnv* env, const std::vector& vals) { if(vals.empty()) return NULL; jclass cls = env->FindClass("java/lang/String"); if (!cls) return NULL; jobjectArray arr = env->NewObjectArray( static_cast(vals.size()), cls, NULL); for(jsize i = 0; i < static_cast(vals.size()); i++) env->SetObjectArrayElement(arr, i, NewJNIString(env, vals[i])); return arr; } jobject NewJNIStringVector(JNIEnv* env, const std::vector& vals) { jobject jvector = NewJNIObject(env, "java/util/Vector"); if (!jvector) return NULL; std::vector::const_iterator iter; for (iter = vals.begin(); iter != vals.end(); ++iter) { AddJNIStringToVector(env, jvector, *iter); } return jvector; } void AddJNIStringToVector(JNIEnv* env, jobject jvector, const CefString &str) { jstring argument = NewJNIString(env, str); JNI_CALL_VOID_METHOD(env, jvector, "addElement", "(Ljava/lang/Object;)V",argument); } void GetJNIStringVector(JNIEnv* env, jobject jvector, std::vector& vals) { if (!jvector) return; jint jsize=0; JNI_CALL_METHOD(env, jvector, "size", "()I", Int, jsize); for (jint index=0; index< jsize; index++) { jobject str=NULL; JNI_CALL_METHOD(env, jvector, "get", "(I)Ljava/lang/Object;", Object, str, index); vals.push_back(GetJNIString(env, (jstring)str)); } } bool GetJNIFieldString(JNIEnv* env, jclass cls, jobject obj, const char* field_name, CefString *value) { jfieldID field = env->GetFieldID(cls, field_name, "Ljava/lang/String;"); if (field) { jstring jstr = (jstring)env->GetObjectField(obj, field); const char* chr = NULL; if(jstr) chr = env->GetStringUTFChars(jstr, NULL); if(chr) *value = chr; env->ReleaseStringUTFChars(jstr, chr); return true; } env->ExceptionClear(); return false; } bool GetJNIFieldDate(JNIEnv* env, jclass cls, jobject obj, const char* field_name, CefTime* value) { jfieldID field = env->GetFieldID(cls, field_name, "Ljava/util/Date;"); if (field) { jobject jdate = env->GetObjectField(obj, field); long timestamp = 0; JNI_CALL_METHOD(env, jdate, "getTime", "()J", Long, timestamp); value->SetDoubleT((double)(timestamp/1000)); return true; } env->ExceptionClear(); return false; } bool GetJNIFieldBoolean(JNIEnv* env, jclass cls, jobject obj, const char* field_name, int* value) { jfieldID field = env->GetFieldID(cls, field_name, "Z"); if (field) { *value = env->GetBooleanField(obj, field) != JNI_FALSE ? 1 : 0; return true; } env->ExceptionClear(); return false; } bool GetJNIFieldObject(JNIEnv* env, jclass cls, jobject obj, const char* field_name, jobject* value, const char* object_type) { jfieldID field = env->GetFieldID(cls, field_name, object_type); if (field) { *value = env->GetObjectField(obj, field); return true; } env->ExceptionClear(); return false; } bool GetJNIFieldInt(JNIEnv* env, jclass cls, jobject obj, const char* field_name, int* value) { jfieldID field = env->GetFieldID(cls, field_name, "I"); if (field) { *value = env->GetIntField(obj, field); return true; } env->ExceptionClear(); return false; } bool SetJNIFieldInt(JNIEnv* env, jclass cls, jobject obj, const char* field_name, int value) { jfieldID field = env->GetFieldID(cls, field_name, "I"); if (field) { env->SetIntField(obj, field, value); return true; } env->ExceptionClear(); return false; } bool GetJNIFieldStaticInt(JNIEnv* env, jclass cls, const char* field_name, int* value) { jfieldID field = env->GetStaticFieldID(cls, field_name, "I"); if (field) { *value = env->GetStaticIntField(cls, field); return true; } env->ExceptionClear(); return false; } bool CallJNIMethodI_V(JNIEnv* env, jclass cls, jobject obj, const char* method_name, int* value) { jmethodID methodID = env->GetMethodID(cls, method_name, "()I"); if (methodID) { *value = env->CallIntMethod(obj, methodID); return true; } env->ExceptionClear(); return false; } bool CallJNIMethodC_V(JNIEnv* env, jclass cls, jobject obj, const char* method_name, char* value) { jmethodID methodID = env->GetMethodID(cls, method_name, "()C"); if (methodID) { *value = env->CallCharMethod(obj, methodID); return true; } env->ExceptionClear(); return false; } CefPageRange GetJNIPageRange(JNIEnv* env, jobject obj) { CefPageRange range; jclass cls = env->FindClass("org/cef/misc/CefPageRange"); if (!cls) return range; int from, to; if (GetJNIFieldInt(env, cls, obj, "from", &from) && GetJNIFieldInt(env, cls, obj, "to", &to)) { range.Set(from, to); } return range; } jobject NewJNIPageRange(JNIEnv* env, const CefPageRange& range) { jclass cls = env->FindClass("org/cef/misc/CefPageRange"); if (!cls) return NULL; jobject obj = NewJNIObject(env, cls); if (!obj) return NULL; if (SetJNIFieldInt(env, cls, obj, "from", range.from) && SetJNIFieldInt(env, cls, obj, "to", range.to)) { return obj; } env->DeleteLocalRef(obj); return NULL; } CefSize GetJNISize(JNIEnv* env, jobject obj) { CefSize size; jclass cls = env->FindClass("java/awt/Dimension"); if (!cls) return size; int width, height; if (GetJNIFieldInt(env, cls, obj, "width", &width) && GetJNIFieldInt(env, cls, obj, "height", &height)) { size.Set(width, height); } return size; } CefRect GetJNIRect(JNIEnv* env, jobject obj) { CefRect rect; jclass cls = env->FindClass("java/awt/Rectangle"); if (!cls) return rect; int x, y, width, height; if (GetJNIFieldInt(env, cls, obj, "x", &x) && GetJNIFieldInt(env, cls, obj, "y", &y) && GetJNIFieldInt(env, cls, obj, "width", &width) && GetJNIFieldInt(env, cls, obj, "height", &height)) { rect.Set(x, y, width, height); return rect; } return rect; } jobject NewJNIRect(JNIEnv* env, const CefRect& rect) { jclass cls = env->FindClass("java/awt/Rectangle"); if (!cls) return NULL; jobject obj = NewJNIObject(env, cls); if (!obj) return NULL; if (SetJNIFieldInt(env, cls, obj, "x", rect.x) && SetJNIFieldInt(env, cls, obj, "y", rect.y) && SetJNIFieldInt(env, cls, obj, "width", rect.width) && SetJNIFieldInt(env, cls, obj, "height", rect.height)) { return obj; } env->DeleteLocalRef(obj); return NULL; } jobjectArray NewJNIRectArray(JNIEnv* env, const std::vector& vals) { if(vals.empty()) return NULL; jclass cls = env->FindClass("java/awt/Rectangle"); if (!cls) return NULL; jobjectArray arr = env->NewObjectArray( static_cast(vals.size()), cls, NULL); for(jsize i = 0; i < static_cast(vals.size()); i++) env->SetObjectArrayElement(arr, i, NewJNIRect(env, vals[i])); return arr; } bool GetJNIPoint(JNIEnv* env, jobject obj, int* x, int* y) { jclass cls = env->FindClass("java/awt/Point"); if (!cls) return false; if (GetJNIFieldInt(env, cls, obj, "x", x) && GetJNIFieldInt(env, cls, obj, "y", y)) { return true; } return false; } // Create a new java.awt.Point. jobject NewJNIPoint(JNIEnv* env, int x, int y) { jclass cls = env->FindClass("java/awt/Point"); if (!cls) return NULL; jobject obj = NewJNIObject(env, cls); if (!obj) return NULL; if (SetJNIFieldInt(env, cls, obj, "x", x) && SetJNIFieldInt(env, cls, obj, "y", y)) { return obj; } env->DeleteLocalRef(obj); return NULL; } CefSettings GetJNISettings(JNIEnv* env, jobject obj) { CefString tmp; CefSettings settings; if (!obj) return settings; jclass cls = env->FindClass("org/cef/CefSettings"); if (!cls) return settings; if (GetJNIFieldString(env, cls, obj, "browser_subprocess_path", &tmp) && !tmp.empty()) { CefString(&settings.browser_subprocess_path) = tmp; tmp.clear(); } GetJNIFieldBoolean(env, cls, obj, "windowless_rendering_enabled", &settings.windowless_rendering_enabled); GetJNIFieldBoolean(env, cls, obj, "command_line_args_disabled", &settings.command_line_args_disabled); if (GetJNIFieldString(env, cls, obj, "cache_path", &tmp) && !tmp.empty()) { CefString(&settings.cache_path) = tmp; tmp.clear(); } GetJNIFieldBoolean(env, cls, obj, "persist_session_cookies", &settings.persist_session_cookies); if (GetJNIFieldString(env, cls, obj, "user_agent", &tmp) && !tmp.empty()) { CefString(&settings.user_agent) = tmp; tmp.clear(); } if (GetJNIFieldString(env, cls, obj, "product_version", &tmp) && !tmp.empty()) { CefString(&settings.product_version) = tmp; tmp.clear(); } if (GetJNIFieldString(env, cls, obj, "locale", &tmp) && !tmp.empty()) { CefString(&settings.locale) = tmp; tmp.clear(); } if (GetJNIFieldString(env, cls, obj, "log_file", &tmp) && !tmp.empty()) { CefString(&settings.log_file) = tmp; tmp.clear(); } jobject obj_sev = NULL; if (GetJNIFieldObject(env, cls, obj, "log_severity", &obj_sev, "Lorg/cef/CefSettings$LogSeverity;")) { if (obj_sev != NULL) { if (IsJNIEnumValue(env, obj_sev, "org/cef/CefSettings$LogSeverity", "LOGSEVERITY_VERBOSE")) settings.log_severity = LOGSEVERITY_VERBOSE; else if (IsJNIEnumValue(env, obj_sev, "org/cef/CefSettings$LogSeverity", "LOGSEVERITY_INFO")) settings.log_severity = LOGSEVERITY_INFO; else if (IsJNIEnumValue(env, obj_sev, "org/cef/CefSettings$LogSeverity", "LOGSEVERITY_WARNING")) settings.log_severity = LOGSEVERITY_WARNING; else if (IsJNIEnumValue(env, obj_sev, "org/cef/CefSettings$LogSeverity", "LOGSEVERITY_ERROR")) settings.log_severity = LOGSEVERITY_ERROR; else if (IsJNIEnumValue(env, obj_sev, "org/cef/CefSettings$LogSeverity", "LOGSEVERITY_DISABLE")) settings.log_severity = LOGSEVERITY_DISABLE; else settings.log_severity = LOGSEVERITY_DEFAULT; } } if (GetJNIFieldString(env, cls, obj, "javascript_flags", &tmp) && !tmp.empty()) { CefString(&settings.javascript_flags) = tmp; tmp.clear(); } if (GetJNIFieldString(env, cls, obj, "resources_dir_path", &tmp) && !tmp.empty()) { CefString(&settings.resources_dir_path) = tmp; tmp.clear(); } if (GetJNIFieldString(env, cls, obj, "locales_dir_path", &tmp) && !tmp.empty()) { CefString(&settings.locales_dir_path) = tmp; tmp.clear(); } GetJNIFieldBoolean(env, cls, obj, "pack_loading_disabled", &settings.pack_loading_disabled); GetJNIFieldInt(env, cls, obj, "remote_debugging_port", &settings.remote_debugging_port); GetJNIFieldInt(env, cls, obj, "uncaught_exception_stack_size", &settings.uncaught_exception_stack_size); GetJNIFieldInt(env, cls, obj, "context_safety_implementation", &settings.context_safety_implementation); GetJNIFieldBoolean(env, cls, obj, "ignore_certificate_errors", &settings.ignore_certificate_errors); jobject obj_col = NULL; if (GetJNIFieldObject(env, cls, obj, "background_color", &obj_col, "Lorg/cef/CefSettings$ColorType;")) { if (obj_col != NULL) { jlong jcolor = 0; JNI_CALL_METHOD(env, obj_col, "getColor", "()J", Long, jcolor); settings.background_color = (cef_color_t)jcolor; } } return settings; } jobject GetJNIBrowser(CefRefPtr browser) { if (!browser.get()) return NULL; CefRefPtr client = (ClientHandler*)browser->GetHost()->GetClient().get(); return client->getBrowser(browser); } jobjectArray GetAllJNIBrowser(JNIEnv* env, jobject jclientHandler) { jobject jbrowsers = NULL; JNI_CALL_METHOD(env, jclientHandler, "getAllBrowser", "()[Ljava/lang/Object;", Object, jbrowsers); if(!jbrowsers) return NULL; return (jobjectArray)jbrowsers; } jobject GetJNIEnumValue(JNIEnv* env, const char* class_name, const char* enum_valname) { jclass sourceCls = env->FindClass(class_name); if (!sourceCls) return NULL; std::string tmp; tmp.append("L").append(class_name).append(";"); jfieldID fieldId = env->GetStaticFieldID(sourceCls, enum_valname, tmp.c_str()); if (!fieldId) return NULL; jobject jsource = env->GetStaticObjectField(sourceCls, fieldId); return jsource; } bool IsJNIEnumValue(JNIEnv* env, jobject jenum, const char* class_name, const char* enum_valname) { if(!jenum) return false; jobject compareTo = GetJNIEnumValue(env, class_name, enum_valname); if (compareTo) { jboolean isEqual = JNI_FALSE; JNI_CALL_METHOD(env, jenum, "equals", "(Ljava/lang/Object;)Z", Boolean, isEqual, compareTo); return (isEqual != JNI_FALSE); } return false; }