summaryrefslogtreecommitdiffstats
path: root/WebKit/android/jni/JavaBridge.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android/jni/JavaBridge.cpp')
-rw-r--r--WebKit/android/jni/JavaBridge.cpp319
1 files changed, 319 insertions, 0 deletions
diff --git a/WebKit/android/jni/JavaBridge.cpp b/WebKit/android/jni/JavaBridge.cpp
new file mode 100644
index 0000000..eefeea5
--- /dev/null
+++ b/WebKit/android/jni/JavaBridge.cpp
@@ -0,0 +1,319 @@
+/*
+ * Copyright 2006, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "webcoreglue"
+
+#include <config.h>
+#include <wtf/Platform.h>
+
+#include "Cache.h"
+#include "CookieClient.h"
+#include "JavaSharedClient.h"
+#include "KURL.h"
+#include "NetworkStateNotifier.h"
+#include "Timer.h"
+#include "TimerClient.h"
+#include "jni_utility.h"
+#include "WebCoreJni.h"
+
+#ifdef ANDROID_INSTRUMENT
+#include "TimeCounter.h"
+#endif
+
+#include <jni.h>
+#include <JNIHelp.h>
+#include <SkImageRef_GlobalPool.h>
+#include <SkUtils.h>
+#include <utils/misc.h>
+
+// maximum bytes used to cache decoded images
+// (not including big images using ashmem)
+#define IMAGE_POOL_BUDGET (512 * 1024)
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static jfieldID gJavaBridge_ObjectID;
+
+// ----------------------------------------------------------------------------
+
+class JavaBridge : public TimerClient, public CookieClient
+{
+public:
+ JavaBridge(JNIEnv* env, jobject obj);
+ virtual ~JavaBridge();
+
+ /*
+ * WebCore -> Java API
+ */
+ virtual void setSharedTimer(long long timemillis);
+ virtual void stopSharedTimer();
+
+ virtual void setCookies(WebCore::KURL const& url, WebCore::KURL const& docURL, WebCore::String const& value);
+ virtual WebCore::String cookies(WebCore::KURL const& url);
+ virtual bool cookiesEnabled();
+
+ ////////////////////////////////////////////
+
+ virtual void setSharedTimerCallback(void (*f)());
+
+ ////////////////////////////////////////////
+
+ void signalServiceFuncPtrQueue();
+
+ // jni functions
+ static void Constructor(JNIEnv* env, jobject obj);
+ static void Finalize(JNIEnv* env, jobject obj);
+ static void SharedTimerFired(JNIEnv* env, jobject);
+ static void SetCacheSize(JNIEnv* env, jobject obj, jint bytes);
+ static void SetNetworkOnLine(JNIEnv* env, jobject obj, jboolean online);
+ static void SetDeferringTimers(JNIEnv* env, jobject obj, jboolean defer);
+ static void ServiceFuncPtrQueue(JNIEnv*);
+
+private:
+ jobject mJavaObject;
+ jmethodID mSetSharedTimer;
+ jmethodID mStopSharedTimer;
+ jmethodID mSetCookies;
+ jmethodID mCookies;
+ jmethodID mCookiesEnabled;
+ jmethodID mSignalFuncPtrQueue;
+};
+
+static void (*sSharedTimerFiredCallback)();
+static JavaBridge* gJavaBridge;
+
+JavaBridge::JavaBridge(JNIEnv* env, jobject obj)
+{
+ mJavaObject = adoptGlobalRef(env, obj);
+ jclass clazz = env->GetObjectClass(obj);
+
+ mSetSharedTimer = env->GetMethodID(clazz, "setSharedTimer", "(J)V");
+ mStopSharedTimer = env->GetMethodID(clazz, "stopSharedTimer", "()V");
+ mSetCookies = env->GetMethodID(clazz, "setCookies", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ mCookies = env->GetMethodID(clazz, "cookies", "(Ljava/lang/String;)Ljava/lang/String;");
+ mCookiesEnabled = env->GetMethodID(clazz, "cookiesEnabled", "()Z");
+ mSignalFuncPtrQueue = env->GetMethodID(clazz, "signalServiceFuncPtrQueue", "()V");
+
+ LOG_ASSERT(mSetSharedTimer, "Could not find method setSharedTimer");
+ LOG_ASSERT(mStopSharedTimer, "Could not find method stopSharedTimer");
+ LOG_ASSERT(mSetCookies, "Could not find method setCookies");
+ LOG_ASSERT(mCookies, "Could not find method cookies");
+ LOG_ASSERT(mCookiesEnabled, "Could not find method cookiesEnabled");
+
+ JavaSharedClient::SetTimerClient(this);
+ JavaSharedClient::SetCookieClient(this);
+ gJavaBridge = this;
+}
+
+JavaBridge::~JavaBridge()
+{
+ if (mJavaObject) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->DeleteGlobalRef(mJavaObject);
+ mJavaObject = 0;
+ }
+
+ JavaSharedClient::SetTimerClient(NULL);
+ JavaSharedClient::SetCookieClient(NULL);
+}
+
+void
+JavaBridge::setSharedTimer(long long timemillis)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ AutoJObject obj = getRealObject(env, mJavaObject);
+ env->CallVoidMethod(obj.get(), mSetSharedTimer, timemillis);
+}
+
+void
+JavaBridge::stopSharedTimer()
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ AutoJObject obj = getRealObject(env, mJavaObject);
+ env->CallVoidMethod(obj.get(), mStopSharedTimer);
+}
+
+void
+JavaBridge::setCookies(WebCore::KURL const& url, WebCore::KURL const& docUrl, WebCore::String const& value)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ const WebCore::String& urlStr = url.string();
+ jstring jUrlStr = env->NewString(urlStr.characters(), urlStr.length());
+ const WebCore::String& docUrlStr = docUrl.string();
+ jstring jDocUrlStr = env->NewString(docUrlStr.characters(), docUrlStr.length());
+ jstring jValueStr = env->NewString(value.characters(), value.length());
+
+ AutoJObject obj = getRealObject(env, mJavaObject);
+ env->CallVoidMethod(obj.get(), mSetCookies, jUrlStr, jDocUrlStr, jValueStr);
+ env->DeleteLocalRef(jUrlStr);
+ env->DeleteLocalRef(jDocUrlStr);
+ env->DeleteLocalRef(jValueStr);
+}
+
+WebCore::String
+JavaBridge::cookies(WebCore::KURL const& url)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ const WebCore::String& urlStr = url.string();
+ jstring jUrlStr = env->NewString(urlStr.characters(), urlStr.length());
+
+ AutoJObject obj = getRealObject(env, mJavaObject);
+ jstring string = (jstring)(env->CallObjectMethod(obj.get(), mCookies, jUrlStr));
+
+ WebCore::String ret = to_string(env, string);
+ env->DeleteLocalRef(jUrlStr);
+ env->DeleteLocalRef(string);
+ return ret;
+}
+
+bool
+JavaBridge::cookiesEnabled()
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ AutoJObject obj = getRealObject(env, mJavaObject);
+ jboolean ret = env->CallBooleanMethod(obj.get(), mCookiesEnabled);
+ return (ret != 0);
+}
+
+void
+JavaBridge::setSharedTimerCallback(void (*f)())
+{
+ LOG_ASSERT(!sSharedTimerFiredCallback || sSharedTimerFiredCallback==f,
+ "Shared timer callback may already be set or null!");
+
+ sSharedTimerFiredCallback = f;
+}
+
+void JavaBridge::signalServiceFuncPtrQueue()
+{
+ // In order to signal the main thread we must go through JNI. This
+ // is the only usage on most threads, so we need to ensure a JNI
+ // environment is setup.
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ AutoJObject obj = getRealObject(env, mJavaObject);
+ env->CallVoidMethod(obj.get(), mSignalFuncPtrQueue);
+}
+
+// ----------------------------------------------------------------------------
+
+// visible to Shared
+void AndroidSignalServiceFuncPtrQueue()
+{
+ gJavaBridge->signalServiceFuncPtrQueue();
+}
+
+// ----------------------------------------------------------------------------
+
+void JavaBridge::Constructor(JNIEnv* env, jobject obj)
+{
+ JavaBridge* javaBridge = new JavaBridge(env, obj);
+ env->SetIntField(obj, gJavaBridge_ObjectID, (jint)javaBridge);
+}
+
+void JavaBridge::Finalize(JNIEnv* env, jobject obj)
+{
+ JavaBridge* javaBridge = (JavaBridge*)
+ (env->GetIntField(obj, gJavaBridge_ObjectID));
+ LOG_ASSERT(javaBridge, "Finalize should not be called twice for the same java bridge!");
+ LOGV("webcore_javabridge::nativeFinalize(%p)\n", javaBridge);
+ delete javaBridge;
+ env->SetIntField(obj, gJavaBridge_ObjectID, 0);
+}
+
+// we don't use the java bridge object, as we're just looking at a global
+void JavaBridge::SharedTimerFired(JNIEnv* env, jobject)
+{
+ if (sSharedTimerFiredCallback)
+ {
+#ifdef ANDROID_INSTRUMENT
+ TimeCounter::start(TimeCounter::SharedTimerTimeCounter);
+#endif
+ SkAutoMemoryUsageProbe mup("JavaBridge::sharedTimerFired");
+ sSharedTimerFiredCallback();
+#ifdef ANDROID_INSTRUMENT
+ TimeCounter::record(TimeCounter::SharedTimerTimeCounter, __FUNCTION__);
+#endif
+ }
+}
+
+void JavaBridge::SetCacheSize(JNIEnv* env, jobject obj, jint bytes)
+{
+ WebCore::cache()->setCapacities(0, bytes/2, bytes);
+ SkImageRef_GlobalPool::SetRAMBudget(IMAGE_POOL_BUDGET);
+ LOGV("--- set ImageRef budget %d\n", SkImageRef_GlobalPool::GetRAMBudget());
+}
+
+void JavaBridge::SetNetworkOnLine(JNIEnv* env, jobject obj, jboolean online)
+{
+ WebCore::networkStateNotifier().networkStateChange(online);
+}
+
+void JavaBridge::SetDeferringTimers(JNIEnv* env, jobject obj, jboolean defer)
+{
+ WebCore::setDeferringTimers(defer);
+}
+
+void JavaBridge::ServiceFuncPtrQueue(JNIEnv*)
+{
+ JavaSharedClient::ServiceFunctionPtrQueue();
+}
+
+// ----------------------------------------------------------------------------
+
+/*
+ * JNI registration.
+ */
+static JNINativeMethod gWebCoreJavaBridgeMethods[] = {
+ /* name, signature, funcPtr */
+ { "nativeConstructor", "()V",
+ (void*) JavaBridge::Constructor },
+ { "nativeFinalize", "()V",
+ (void*) JavaBridge::Finalize },
+ { "sharedTimerFired", "()V",
+ (void*) JavaBridge::SharedTimerFired },
+ { "setCacheSize", "(I)V",
+ (void*) JavaBridge::SetCacheSize },
+ { "setNetworkOnLine", "(Z)V",
+ (void*) JavaBridge::SetNetworkOnLine },
+ { "setDeferringTimers", "(Z)V",
+ (void*) JavaBridge::SetDeferringTimers },
+ { "nativeServiceFuncPtrQueue", "()V",
+ (void*) JavaBridge::ServiceFuncPtrQueue },
+};
+
+int register_javabridge(JNIEnv* env)
+{
+ jclass javaBridge = env->FindClass("android/webkit/JWebCoreJavaBridge");
+ LOG_FATAL_IF(javaBridge == NULL, "Unable to find class android/webkit/JWebCoreJavaBridge");
+ gJavaBridge_ObjectID = env->GetFieldID(javaBridge, "mNativeBridge", "I");
+ LOG_FATAL_IF(gJavaBridge_ObjectID == NULL, "Unable to find android/webkit/JWebCoreJavaBridge.mNativeBridge");
+
+ return jniRegisterNativeMethods(env, "android/webkit/JWebCoreJavaBridge",
+ gWebCoreJavaBridgeMethods, NELEM(gWebCoreJavaBridgeMethods));
+}
+
+} /* namespace android */