diff options
Diffstat (limited to 'WebCore/platform/android/jni')
18 files changed, 0 insertions, 6906 deletions
diff --git a/WebCore/platform/android/jni/JavaBridge.cpp b/WebCore/platform/android/jni/JavaBridge.cpp deleted file mode 100644 index 27b2bb2..0000000 --- a/WebCore/platform/android/jni/JavaBridge.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/* -** Copyright 2006-2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "webcoreglue" - -#include <config.h> -#include <wtf/Platform.h> - -#include "Cache.h" -#include "CookieClient.h" -#include "JavaSharedClient.h" -#include "KURL.h" -#include "Timer.h" -#include "TimerClient.h" - -#ifdef ANDROID_INSTRUMENT -#include "Frame.h" -#include "SystemTime.h" -#endif - -#undef LOG -#include <jni.h> -#include <JNIHelp.h> -#include <SkImageRef_GlobalPool.h> -#include <SkUtils.h> -#include <utils/Log.h> -#include <utils/misc.h> - -// maximum bytes used to cache decoded images -// (not including big images using ashmem) -#define IMAGE_POOL_BUDGET (512 * 1024) - -#ifdef ANDROID_INSTRUMENT -static uint32_t sTotalTimeUsed = 0; - -namespace WebCore { -void Frame::resetSharedTimerTimeCounter() -{ - sTotalTimeUsed = 0; -} - -void Frame::reportSharedTimerTimeCounter() -{ - LOG(LOG_DEBUG, "WebCore", "*-* Total native 2 (shared timer) time: %d ms\n", - sTotalTimeUsed); -} -} -#endif - -namespace android { - -// ---------------------------------------------------------------------------- - -static jfieldID gJavaBridge_ObjectID; - -static bool checkException(JNIEnv* env) -{ - if (env->ExceptionCheck() != 0) - { - LOGE("*** Uncaught exception returned from Java call!\n"); - env->ExceptionDescribe(); - return true; - } - return false; -} - -// ---------------------------------------------------------------------------- - -extern JavaVM* jnienv_to_javavm(JNIEnv* env); -extern JNIEnv* javavm_to_jnienv(JavaVM* vm); - -// ---------------------------------------------------------------------------- - -class JavaBridge : public WebCore::TimerClient, public WebCore::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 SetDeferringTimers(JNIEnv* env, jobject obj, jboolean defer); - static void ServiceFuncPtrQueue(JNIEnv*); - -private: - JavaVM* mJvm; - 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) -{ - mJvm = jnienv_to_javavm(env); - mJavaObject = env->NewGlobalRef(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"); - - WebCore::JavaSharedClient::SetTimerClient(this); - WebCore::JavaSharedClient::SetCookieClient(this); - gJavaBridge = this; -} - -JavaBridge::~JavaBridge() -{ - if (mJavaObject) { - JNIEnv* env = javavm_to_jnienv(mJvm); - env->DeleteGlobalRef(mJavaObject); - mJavaObject = 0; - } - - WebCore::JavaSharedClient::SetTimerClient(NULL); - WebCore::JavaSharedClient::SetCookieClient(NULL); -} - -void -JavaBridge::setSharedTimer(long long timemillis) -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - env->CallVoidMethod(mJavaObject, mSetSharedTimer, timemillis); -} - -void -JavaBridge::stopSharedTimer() -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - env->CallVoidMethod(mJavaObject, mStopSharedTimer); -} - -void -JavaBridge::setCookies(WebCore::KURL const& url, WebCore::KURL const& docUrl, WebCore::String const& value) -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - const WebCore::DeprecatedString& urlStr = url.deprecatedString(); - jstring jUrlStr = env->NewString((unsigned short *)urlStr.unicode(), urlStr.length()); - const WebCore::DeprecatedString& docUrlStr = docUrl.deprecatedString(); - jstring jDocUrlStr = env->NewString((unsigned short *)docUrlStr.unicode(), docUrlStr.length()); - jstring jValueStr = env->NewString((unsigned short *)value.characters(), value.length()); - - env->CallVoidMethod(mJavaObject, mSetCookies, jUrlStr, jDocUrlStr, jValueStr); - env->DeleteLocalRef(jUrlStr); - env->DeleteLocalRef(jDocUrlStr); - env->DeleteLocalRef(jValueStr); -} - -WebCore::String -JavaBridge::cookies(WebCore::KURL const& url) -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - const WebCore::DeprecatedString& urlStr = url.deprecatedString(); - jstring jUrlStr = env->NewString((unsigned short *)urlStr.unicode(), urlStr.length()); - - jstring string = (jstring)(env->CallObjectMethod(mJavaObject, mCookies, jUrlStr)); - - if (string == NULL || checkException(env)) - return WebCore::String(); - - const jchar* str = env->GetStringChars(string, NULL); - WebCore::String ret = WebCore::String((const UChar*)str, env->GetStringLength(string)); - env->ReleaseStringChars(string, str); - env->DeleteLocalRef(jUrlStr); - env->DeleteLocalRef(string); - return ret; -} - -bool -JavaBridge::cookiesEnabled() -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - jboolean ret = env->CallBooleanMethod(mJavaObject, 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() -{ - javavm_to_jnienv(mJvm)->CallVoidMethod(mJavaObject, 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 - uint32_t startTime = WebCore::get_thread_msec(); -#endif - SkAutoMemoryUsageProbe mup("JavaBridge::sharedTimerFired"); - sSharedTimerFiredCallback(); -#ifdef ANDROID_INSTRUMENT - sTotalTimeUsed += WebCore::get_thread_msec() - startTime; -#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::SetDeferringTimers(JNIEnv* env, jobject obj, jboolean defer) -{ - WebCore::setDeferringTimers(defer); -} - -void JavaBridge::ServiceFuncPtrQueue(JNIEnv*) -{ - WebCore::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 }, - { "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 */ diff --git a/WebCore/platform/android/jni/JavaSharedClient.cpp b/WebCore/platform/android/jni/JavaSharedClient.cpp deleted file mode 100644 index aaefd72..0000000 --- a/WebCore/platform/android/jni/JavaSharedClient.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" -#include "JavaSharedClient.h" -#define LOG_TAG "JavaSharedClient" -#include "utils/Log.h" -#include "SkDeque.h" -#include "SkThread.h" - -namespace android { - void AndroidSignalServiceFuncPtrQueue(); -} - -namespace WebCore { - - TimerClient* JavaSharedClient::GetTimerClient() - { - //LOG_ASSERT(gTimerClient != NULL, "gTimerClient not initialized!!!"); - return gTimerClient; - } - - CookieClient* JavaSharedClient::GetCookieClient() - { - //LOG_ASSERT(gCookieClient != NULL, "gCookieClient not initialized!!!"); - return gCookieClient; - } - - void JavaSharedClient::SetTimerClient(TimerClient* client) - { - //LOG_ASSERT(gTimerClient == NULL || client == NULL, "gTimerClient already set, aborting..."); - gTimerClient = client; - } - - void JavaSharedClient::SetCookieClient(CookieClient* client) - { - //LOG_ASSERT(gCookieClient == NULL || client == NULL, "gCookieClient already set, aborting..."); - gCookieClient = client; - } - - TimerClient* JavaSharedClient::gTimerClient = NULL; - CookieClient* JavaSharedClient::gCookieClient = NULL; - - /////////////////////////////////////////////////////////////////////////// - - struct FuncPtrRec { - void (*fProc)(void* payload); - void* fPayload; - }; - - static SkMutex gFuncPtrQMutex; - static SkDeque gFuncPtrQ(sizeof(FuncPtrRec)); - - void JavaSharedClient::EnqueueFunctionPtr(void (*proc)(void* payload), - void* payload) - { - gFuncPtrQMutex.acquire(); - - FuncPtrRec* rec = (FuncPtrRec*)gFuncPtrQ.push_back(); - rec->fProc = proc; - rec->fPayload = payload; - - gFuncPtrQMutex.release(); - - android::AndroidSignalServiceFuncPtrQueue(); - } - - void JavaSharedClient::ServiceFunctionPtrQueue() - { - for (;;) { - void (*proc)(void*); - void* payload; - const FuncPtrRec* rec; - - // we have to copy the proc/payload (if present). we do this so we - // don't call the proc inside the mutex (possible deadlock!) - gFuncPtrQMutex.acquire(); - rec = (const FuncPtrRec*)gFuncPtrQ.front(); - if (NULL != rec) { - proc = rec->fProc; - payload = rec->fPayload; - gFuncPtrQ.pop_front(); - } - gFuncPtrQMutex.release(); - - if (NULL == rec) { - break; - } - proc(payload); - } - } -} diff --git a/WebCore/platform/android/jni/JavaSharedClient.h b/WebCore/platform/android/jni/JavaSharedClient.h deleted file mode 100644 index 470c4dd..0000000 --- a/WebCore/platform/android/jni/JavaSharedClient.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef JAVA_SHARED_CLIENT_H -#define JAVA_SHARED_CLIENT_H - -namespace WebCore { - - class TimerClient; - class CookieClient; - - class JavaSharedClient - { - public: - static TimerClient* GetTimerClient(); - static CookieClient* GetCookieClient(); - - static void SetTimerClient(TimerClient* client); - static void SetCookieClient(CookieClient* client); - - // can be called from any thread, to be executed in webkit thread - static void EnqueueFunctionPtr(void (*proc)(void*), void* payload); - // only call this from webkit thread - static void ServiceFunctionPtrQueue(); - - private: - static TimerClient* gTimerClient; - static CookieClient* gCookieClient; - }; -} -#endif diff --git a/WebCore/platform/android/jni/WebCoreFrameBridge.cpp b/WebCore/platform/android/jni/WebCoreFrameBridge.cpp deleted file mode 100644 index 55c9c88..0000000 --- a/WebCore/platform/android/jni/WebCoreFrameBridge.cpp +++ /dev/null @@ -1,1249 +0,0 @@ -/* -** Copyright 2006-2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "webcoreglue" - -#include <config.h> -#include <wtf/Platform.h> - -#include "android_graphics.h" -#include "Arena.h" -#include "AtomicString.h" -#include "Cache.h" -#include "ChromeClientAndroid.h" -#include "ContextMenuClientAndroid.h" -#include "DeprecatedString.h" -#include "Document.h" -#include "DocumentLoader.h" -#include "DragClientAndroid.h" -#include "EditorClientAndroid.h" -#include "Element.h" -#include "Font.h" -#include "FrameAndroid.h" -#include "FrameLoader.h" -#include "FrameLoaderClientAndroid.h" -#include "FrameTree.h" -#include "FrameView.h" -#include "GCController.h" -#include "GraphicsContext.h" -#include "HistoryItem.h" -#include "HTMLElement.h" -#include "HTMLFormElement.h" -#include "HTMLInputElement.h" -#include "HTMLNames.h" -#include "IconDatabase.h" -#include "Image.h" -#include "InspectorClientAndroid.h" -#include "KURL.h" -#include "Page.h" -#include "PageCache.h" -#include "PlatformString.h" -#include "RenderPart.h" -#include "RenderSkinAndroid.h" -#include "RenderTreeAsText.h" -#include "ResourceHandle.h" -#include "SelectionController.h" -#include "Settings.h" -#include "SubstituteData.h" -#include "WebCoreFrameBridge.h" -#include "WebCoreResourceLoader.h" -#include "WebHistory.h" -#include "WebIconDatabase.h" -#include "WebViewCore.h" - -#ifdef LOG -#undef LOG -#endif - -#include <JNIHelp.h> -#include <SkGraphics.h> -#include <SkImageRef_GlobalPool.h> -#include <utils/Log.h> -#include <utils/misc.h> -#include <utils/AssetManager.h> -#include <android_runtime/android_util_AssetManager.h> - -#ifdef ANDROID_INSTRUMENT -#include "SystemTime.h" - -static uint32_t sTotalJavaTimeUsed = 0; -static uint32_t sTotalNativeTimeUsed = 0; - -namespace WebCore { -void Frame::resetFramebridgeTimeCounter() -{ - sTotalJavaTimeUsed = 0; - sTotalNativeTimeUsed = 0; -} - -void Frame::reportFramebridgeTimeCounter() -{ - LOG(LOG_DEBUG, "WebCore", "*-* Total Java callback (frame bridge) time: %d ms\n", - sTotalJavaTimeUsed); - LOG(LOG_DEBUG, "WebCore", "*-* Total native 1 (frame bridge) time: %d ms\n", - sTotalNativeTimeUsed); -} -} -#endif - -namespace android { - -#ifdef ANDROID_INSTRUMENT -class TimeCounterFB { -public: - TimeCounterFB(bool native = false) { - mNative = native; - mStartTime = WebCore::get_thread_msec(); - } - - ~TimeCounterFB() { - if (mNative) - sTotalNativeTimeUsed += WebCore::get_thread_msec() - mStartTime; - else - sTotalJavaTimeUsed += WebCore::get_thread_msec() - mStartTime; - } -private: - bool mNative; - uint32_t mStartTime; -}; -#endif - -// ---------------------------------------------------------------------------- - -#define WEBCORE_MEMORY_CAP 15 * 1024 * 1024 - -// ---------------------------------------------------------------------------- - -JavaVM* jnienv_to_javavm(JNIEnv* env) -{ - JavaVM* vm; - return env->GetJavaVM(&vm) >= 0 ? vm : NULL; -} - -JNIEnv* javavm_to_jnienv(JavaVM* vm) -{ - JNIEnv* env; - return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL; -} - -// ---------------------------------------------------------------------------- - -struct WebCoreFrameBridge::JavaBrowserFrame -{ - JavaVM* mJVM; - jobject mObj; - jobject mHistoryList; // WebBackForwardList object - jmethodID mStartLoadingResource; - jmethodID mLoadStarted; - jmethodID mTransitionToCommitted; - jmethodID mLoadFinished; - jmethodID mReportError; - jmethodID mSetTitle; - jmethodID mWindowObjectCleared; - jmethodID mSetProgress; - jmethodID mDidReceiveIcon; - jmethodID mUpdateVisitedHistory; - jmethodID mHandleUrl; - jmethodID mCreateWindow; - jmethodID mCloseWindow; - jmethodID mDecidePolicyForFormResubmission; - jmethodID mRequestFocus; -}; - -static jfieldID gFrameAndroidField; -#define GET_NATIVE_FRAME(env, obj) ((WebCore::FrameAndroid*)env->GetIntField(obj, gFrameAndroidField)) -#define SET_NATIVE_FRAME(env, obj, frame) (env->SetIntField(obj, gFrameAndroidField, frame)) - -// ---------------------------------------------------------------------------- - -/** - * Helper method for checking java exceptions - * @return true if an exception occurred. - */ -static bool checkException(JNIEnv* env) -{ - if (env->ExceptionCheck() != 0) - { - LOGE("*** Uncaught exception returned from Java call!\n"); - env->ExceptionDescribe(); - return true; - } - return false; -} - -// ---------------------------------------------------------------------------- - -WebCoreFrameBridge::WebCoreFrameBridge(JNIEnv* env, jobject obj, jobject historyList) -{ - jclass clazz = env->GetObjectClass(obj); - mJavaFrame = new JavaBrowserFrame; - mJavaFrame->mJVM = jnienv_to_javavm(env); - mJavaFrame->mObj = env->NewGlobalRef(obj); - mJavaFrame->mHistoryList = env->NewGlobalRef(historyList); - mJavaFrame->mStartLoadingResource = env->GetMethodID(clazz, "startLoadingResource", - "(ILjava/lang/String;Ljava/lang/String;Ljava/util/HashMap;Ljava/lang/String;IZZ)Landroid/webkit/LoadListener;"); - mJavaFrame->mLoadStarted = env->GetMethodID(clazz, "loadStarted", - "(Ljava/lang/String;Landroid/graphics/Bitmap;IZ)V"); - mJavaFrame->mTransitionToCommitted = env->GetMethodID(clazz, "transitionToCommitted", - "(IZ)V"); - mJavaFrame->mLoadFinished = env->GetMethodID(clazz, "loadFinished", - "(Ljava/lang/String;IZ)V"); - mJavaFrame->mReportError = env->GetMethodID(clazz, "reportError", - "(ILjava/lang/String;Ljava/lang/String;)V"); - mJavaFrame->mSetTitle = env->GetMethodID(clazz, "setTitle", - "(Ljava/lang/String;)V"); - mJavaFrame->mWindowObjectCleared = env->GetMethodID(clazz, "windowObjectCleared", - "(I)V"); - mJavaFrame->mSetProgress = env->GetMethodID(clazz, "setProgress", - "(I)V"); - mJavaFrame->mDidReceiveIcon = env->GetMethodID(clazz, "didReceiveIcon", - "(Landroid/graphics/Bitmap;)V"); - mJavaFrame->mUpdateVisitedHistory = env->GetMethodID(clazz, "updateVisitedHistory", - "(Ljava/lang/String;Z)V"); - mJavaFrame->mHandleUrl = env->GetMethodID(clazz, "handleUrl", - "(Ljava/lang/String;)Z"); - mJavaFrame->mCreateWindow = env->GetMethodID(clazz, "createWindow", - "(ZZ)Landroid/webkit/BrowserFrame;"); - mJavaFrame->mCloseWindow = env->GetMethodID(clazz, "closeWindow", - "(Landroid/webkit/WebViewCore;)V"); - mJavaFrame->mDecidePolicyForFormResubmission = env->GetMethodID(clazz, - "decidePolicyForFormResubmission", "(I)V"); - mJavaFrame->mRequestFocus = env->GetMethodID(clazz, "requestFocus", - "()V"); - - LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource"); - LOG_ASSERT(mJavaFrame->mLoadStarted, "Could not find method loadStarted"); - LOG_ASSERT(mJavaFrame->mTransitionToCommitted, "Could not find method transitionToCommitted"); - LOG_ASSERT(mJavaFrame->mLoadFinished, "Could not find method loadFinished"); - LOG_ASSERT(mJavaFrame->mReportError, "Could not find method reportError"); - LOG_ASSERT(mJavaFrame->mSetTitle, "Could not find method setTitle"); - LOG_ASSERT(mJavaFrame->mWindowObjectCleared, "Could not find method windowObjectCleared"); - LOG_ASSERT(mJavaFrame->mSetProgress, "Could not find method setProgress"); - LOG_ASSERT(mJavaFrame->mDidReceiveIcon, "Could not find method didReceiveIcon"); - LOG_ASSERT(mJavaFrame->mUpdateVisitedHistory, "Could not find method updateVisitedHistory"); - LOG_ASSERT(mJavaFrame->mHandleUrl, "Could not find method handleUrl"); - LOG_ASSERT(mJavaFrame->mCreateWindow, "Could not find method createWindow"); - LOG_ASSERT(mJavaFrame->mCloseWindow, "Could not find method closeWindow"); - LOG_ASSERT(mJavaFrame->mDecidePolicyForFormResubmission, "Could not find method decidePolicyForFormResubmission"); - LOG_ASSERT(mJavaFrame->mRequestFocus, "Could not find method requestFocus"); - - mUserAgent = WebCore::String(); - mInKeyHandler = false; -} - -WebCoreFrameBridge::~WebCoreFrameBridge() -{ - if (mJavaFrame->mObj) { - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - env->DeleteGlobalRef(mJavaFrame->mObj); - env->DeleteGlobalRef(mJavaFrame->mHistoryList); - mJavaFrame->mObj = 0; - } - delete mJavaFrame; -} - -static jobject createJavaMapFromHTTPHeaders(JNIEnv* env, const WebCore::HTTPHeaderMap& map) -{ - jclass mapClass = env->FindClass("java/util/HashMap"); - LOG_ASSERT(mapClass, "Could not find HashMap class!"); - jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V"); - LOG_ASSERT(init, "Could not find constructor for HashMap"); - jobject hashMap = env->NewObject(mapClass, init, map.size()); - LOG_ASSERT(hashMap, "Could not create a new HashMap"); - jmethodID put = env->GetMethodID(mapClass, "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); - LOG_ASSERT(put, "Could not find put method on HashMap"); - - WebCore::HTTPHeaderMap::const_iterator end = map.end(); - for (WebCore::HTTPHeaderMap::const_iterator i = map.begin(); i != end; ++i) { - jstring key = env->NewString((unsigned short *)i->first.characters(), i->first.length()); - jstring val = env->NewString((unsigned short *)i->second.characters(), i->second.length()); - if (key && val) { - env->CallObjectMethod(hashMap, put, key, val); - env->DeleteLocalRef(key); - env->DeleteLocalRef(val); - } - } - env->DeleteLocalRef(mapClass); - - return hashMap; -} - -WebCoreResourceLoader* -WebCoreFrameBridge::startLoadingResource(WebCore::ResourceHandle* loader, - const WebCore::ResourceRequest& request, - bool isHighPriority, bool synchronous) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: startLoadingResource(%p, %s)", - loader, request.url().string().ascii().data()); - - WebCore::String method = request.httpMethod(); - WebCore::String postData; - if (request.httpBody()) - postData = request.httpBody()->flattenToString(); - WebCore::HTTPHeaderMap headers = request.httpHeaderFields(); - - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebCore::DeprecatedString urlStr = request.url().deprecatedString(); - jstring jUrlStr = env->NewString((unsigned short *)urlStr.unicode(), urlStr.length()); - jstring jMethodStr = NULL; - if (!method.isEmpty()) - jMethodStr = env->NewString((unsigned short *)method.characters(), method.length()); - jstring jPostDataStr = NULL; - if (!postData.isEmpty()) - jPostDataStr = - env->NewString((unsigned short *)postData.characters(), postData.length()); - - jobject jHeaderMap = createJavaMapFromHTTPHeaders(env, headers); - - // Convert the WebCore Cache Policy to a WebView Cache Policy. - int cacheMode = 0; // WebView.LOAD_NORMAL - switch (request.cachePolicy()) { - case WebCore::ReloadIgnoringCacheData: - cacheMode = 2; // WebView.LOAD_NO_CACHE - break; - case WebCore::ReturnCacheDataDontLoad: - cacheMode = 3; // WebView.LOAD_CACHE_ONLY - break; - case WebCore::ReturnCacheDataElseLoad: - cacheMode = 1; // WebView.LOAD_CACHE_ELSE_NETWORK - break; - case WebCore::UseProtocolCachePolicy: - default: - break; - } - - LOGV("::WebCore:: startLoadingResource %s with cacheMode %d", urlStr.ascii(), cacheMode); - - - jobject jLoadListener = - env->CallObjectMethod(mJavaFrame->mObj, mJavaFrame->mStartLoadingResource, - (int)loader, jUrlStr, jMethodStr, jHeaderMap, - jPostDataStr, cacheMode, isHighPriority, synchronous); - - env->DeleteLocalRef(jUrlStr); - env->DeleteLocalRef(jMethodStr); - env->DeleteLocalRef(jPostDataStr); - env->DeleteLocalRef(jHeaderMap); - if (checkException(env)) - return NULL; - - WebCoreResourceLoader* h = NULL; - if (jLoadListener) - h = new WebCoreResourceLoader(env, jLoadListener); - env->DeleteLocalRef(jLoadListener); - return h; -} - -void -WebCoreFrameBridge::reportError(int errorCode, const WebCore::String& description, - const WebCore::String& failingUrl) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: reportError(%d, %s)", errorCode, description.ascii().data()); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - - jstring descStr = env->NewString((unsigned short*)description.characters(), description.length()); - jstring failUrl = env->NewString((unsigned short*)failingUrl.characters(), failingUrl.length()); - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mReportError, errorCode, descStr, failUrl); - env->DeleteLocalRef(descStr); - env->DeleteLocalRef(failUrl); -} - -void -WebCoreFrameBridge::loadStarted(WebCore::FrameAndroid* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - const WebCore::KURL& url = frame->loader()->activeDocumentLoader()->url(); - if (url.isEmpty()) - return; - LOGV("::WebCore:: loadStarted %s", url.string().ascii().data()); - - bool isMainFrame = (!frame->tree() || !frame->tree()->parent()); - WebCore::FrameLoadType loadType = frame->loader()->loadType(); - - if (loadType == WebCore::FrameLoadTypeReplace || - loadType == WebCore::FrameLoadTypeSame || - (loadType == WebCore::FrameLoadTypeRedirectWithLockedHistory && - !isMainFrame)) - return; - - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebCore::String urlString(url.string()); - // If this is the main frame and we already have a favicon in the database, - // send it along with the page started notification. - jobject favicon = NULL; - if (isMainFrame) { - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(urlString, WebCore::IntSize(16, 16)); - if (icon) - favicon = webcoreImageToJavaBitmap(env, icon); - LOGV("favicons", "Starting load with icon %p for %s", icon, url.deprecatedString().ascii()); - } - jstring urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); - - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mLoadStarted, urlStr, favicon, - (int)loadType, isMainFrame); - checkException(env); - env->DeleteLocalRef(urlStr); - if (favicon) - env->DeleteLocalRef(favicon); -} - -void -WebCoreFrameBridge::transitionToCommitted(WebCore::Frame* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebCore::FrameLoadType loadType = frame->loader()->loadType(); - bool isMainFrame = (!frame->tree() || !frame->tree()->parent()); - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mTransitionToCommitted, - (int)loadType, isMainFrame); - checkException(env); -} - -void -WebCoreFrameBridge::didFinishLoad(WebCore::Frame* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebCore::FrameLoader* loader = frame->loader(); - const WebCore::KURL& url = loader->activeDocumentLoader()->url(); - if (url.isEmpty()) - return; - LOGV("::WebCore:: didFinishLoad %s", url.string().ascii().data()); - - bool isMainFrame = (!frame->tree() || !frame->tree()->parent()); - WebCore::FrameLoadType loadType = loader->loadType(); - WebCore::String urlString(url.string()); - jstring urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mLoadFinished, urlStr, - (int)loadType, isMainFrame); - checkException(env); - env->DeleteLocalRef(urlStr); -} - -void -WebCoreFrameBridge::addHistoryItem(WebCore::HistoryItem* item) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: addHistoryItem"); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebHistory::AddItem(env, mJavaFrame->mHistoryList, item); -} - -void -WebCoreFrameBridge::removeHistoryItem(int index) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: removeHistoryItem at %d", index); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebHistory::RemoveItem(env, mJavaFrame->mHistoryList, index); -} - -void -WebCoreFrameBridge::updateHistoryIndex(int newIndex) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: updateHistoryIndex to %d", newIndex); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebHistory::UpdateHistoryIndex(env, mJavaFrame->mHistoryList, newIndex); -} - -void -WebCoreFrameBridge::setTitle(const WebCore::String& title) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif -#ifndef NDEBUG - LOGV("setTitle(%s)", title.ascii().data()); -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - jstring jTitleStr = env->NewString((unsigned short *)title.characters(), title.length()); - - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mSetTitle, - jTitleStr); - checkException(env); - env->DeleteLocalRef(jTitleStr); -} - -void -WebCoreFrameBridge::windowObjectCleared(WebCore::FrameAndroid* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: windowObjectCleared"); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mWindowObjectCleared, (int)frame); - checkException(env); -} - -void -WebCoreFrameBridge::setProgress(float newProgress) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - int progress = (int) (100 * newProgress); - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mSetProgress, progress); - checkException(env); -} - -const WebCore::String -WebCoreFrameBridge::userAgentForURL(const WebCore::KURL* url) -{ - return mUserAgent; -} - -void -WebCoreFrameBridge::didReceiveIcon(WebCore::Image* icon) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOG_ASSERT(icon, "DidReceiveIcon called without an image!"); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - jobject bitmap = webcoreImageToJavaBitmap(env, icon); - if (!bitmap) - return; - - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mDidReceiveIcon, bitmap); - env->DeleteLocalRef(bitmap); - checkException(env); -} - -void -WebCoreFrameBridge::updateVisitedHistory(const WebCore::KURL& url, bool reload) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - WebCore::String urlStr(url.string()); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - jstring jUrlStr = env->NewString((unsigned short*)urlStr.characters(), urlStr.length()); - - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mUpdateVisitedHistory, jUrlStr, reload); - checkException(env); -} - -bool -WebCoreFrameBridge::canHandleRequest(const WebCore::ResourceRequest& request) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - // Internal loads are ok but any request that is due to a user hitting a key - // should be checked. - bool userGesture = false; -#ifdef ANDROID_USER_GESTURE - userGesture = request.userGesture(); -#endif - WebCore::KURL requestUrl = request.url(); - if (!mInKeyHandler && !userGesture && - (requestUrl.protocolIs("http") || requestUrl.protocolIs("https") || - requestUrl.protocolIs("file") || requestUrl.protocolIs("about") || - requestUrl.protocolIs("javascript"))) - return true; - WebCore::String url(request.url().string()); - // Empty urls should not be sent to java - if (url.isEmpty()) - return true; - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - - // check to see whether browser app wants to hijack url loading. - // if browser app handles the url, we will return false to bail out WebCore loading - jboolean ret = env->CallBooleanMethod(mJavaFrame->mObj, mJavaFrame->mHandleUrl, jUrlStr); - checkException(env); - return (ret == 0); -} - -WebCore::Frame* -WebCoreFrameBridge::createWindow(bool dialog, bool userGesture) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - jobject obj = env->CallObjectMethod(mJavaFrame->mObj, - mJavaFrame->mCreateWindow, dialog, userGesture); - if (obj) { - WebCore::FrameAndroid* frame = GET_NATIVE_FRAME(env, obj); - return frame; - } - return NULL; -} - -void -WebCoreFrameBridge::requestFocus() const -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mRequestFocus); - checkException(env); -} - -void -WebCoreFrameBridge::closeWindow(WebCoreViewBridge* viewBridge) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - assert(viewBridge); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - // TODO: This is a hack until WebCoreViewBridge is no longer an interface. - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mCloseWindow, - ((WebViewCore*)viewBridge)->getJavaObject()); -} - -struct PolicyFunctionWrapper { - WebCore::FramePolicyFunction func; -}; - -void -WebCoreFrameBridge::decidePolicyForFormResubmission(WebCore::FramePolicyFunction func) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - PolicyFunctionWrapper* p = new PolicyFunctionWrapper; - p->func = func; - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mDecidePolicyForFormResubmission, p); -} - -// ---------------------------------------------------------------------------- -static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decision) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeCallPolicyFunction must take a valid frame pointer!"); - PolicyFunctionWrapper* pFunc = (PolicyFunctionWrapper*)func; - LOG_ASSERT(pFunc, "nativeCallPolicyFunction must take a valid function pointer!"); - - (pFrame->loader()->*(pFunc->func))((WebCore::PolicyAction)decision); -} - -static void CreateFrame(JNIEnv* env, jobject obj, jobject jAssetManager, jobject historyList) -{ - // Register this thread as the main thread. - KJS::Collector::registerAsMainThread(); -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::ChromeClientAndroid* chromeC = new WebCore::ChromeClientAndroid; - WebCore::EditorClientAndroid* editorC = new WebCore::EditorClientAndroid; - WebCore::ContextMenuClient* contextMenuC = new WebCore::ContextMenuClientAndroid; - WebCore::DragClient* dragC = new WebCore::DragClientAndroid; - WebCore::FrameLoaderClientAndroid* loaderC = new WebCore::FrameLoaderClientAndroid; - WebCore::InspectorClientAndroid* inspectorC = new WebCore::InspectorClientAndroid; - // Create a new page - WebCore::Page* page = new WebCore::Page(chromeC, contextMenuC, editorC, dragC, inspectorC); - /* TODO: Don't turn on PageCache until we can restore the ScrollView State. - * This caused bug http://b/issue?id=1202983 - page->settings()->setUsesPageCache(true); - // 10 is a random number chosen because it is small enough to give the user - // a good back/forward page cache without allowing the page cache to get too - // big. - WebCore::pageCache()->setCapacity(10); - */ - editorC->setPage(page); - page->setGroupName("com.android.browser"); - // Frames are automatically refed to 1, keep this ref because BrowserFrame will - // maintain a native frame pointer. - WebCore::FrameAndroid* frame = new WebCore::FrameAndroid(page, NULL, loaderC); - chromeC->setFrame(frame); - loaderC->setFrame(frame); - - // Create one instance of WebCoreFrameBridge for calling into Java from WebCore - WebCoreFrameBridge* frameBridge = new WebCoreFrameBridge(env, obj, historyList); - - // Pass the bridge to the frame and release our ownership. - frame->setBridge(frameBridge); - Release(frameBridge); - - LOGV("::WebCore:: createFrame %p", frame); - - // Set the mNativeFrame field in Frame - SET_NATIVE_FRAME(env, obj, (int)frame); - - // Setup the asset manager. - AssetManager* am = assetManagerForJavaObject(env, jAssetManager); - // Initialize our skinning classes - WebCore::RenderSkinAndroid::Init(am); -} - -static void DestroyFrame(JNIEnv* env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeDestroyFrame must take a valid frame pointer!"); - - LOGV("::WebCore:: deleting frame %p", pFrame); - - WebCore::FrameView* view = pFrame->view(); - // detachFromParent will cause the page to be closed. - WebCore::FrameLoader* fl = pFrame->loader(); - // retain a pointer because detachFromParent will set the page to null. - WebCore::Page* page = pFrame->page(); - if (fl) - fl->detachFromParent(); - delete page; - view->deref(); - - SET_NATIVE_FRAME(env, obj, 0); -} - -static void CreateView(JNIEnv *env, jobject obj, jobject widget) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeCreateView must take a valid frame pointer!"); - - // Create a new FrameView and attach an initial WebViewCore. FrameView begins with an initial ref - // of 1 and that ref is in WebViewCore. - WebCore::FrameView* view = new WebCore::FrameView(pFrame); - // The viewBridge will make a java call to maintain a pointer to the view. - WebViewCore* viewBridge = new WebViewCore(env, widget, view); - view->setWebCoreViewBridge(viewBridge); - view->deref(); - Release(viewBridge); - - // Attach the view to the frame. - pFrame->setView(view); - - // Set the frame to active to turn on keyboard focus. - pFrame->init(); - pFrame->selectionController()->setFocused(true); - - LOGV("::WebCore:: created view %p with bridge %p", view, viewBridge); -} - -static void DetachView(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeDetachView must take a valid frame pointer!"); - LOGV("::WebCore:: detaching view from frame %p", pFrame); - - WebCore::FrameView* view = pFrame->view(); - LOG_ASSERT(view, "cannot detach a null view!"); - - // Remove keyboard focus - pFrame->selectionController()->setFocused(false); - - // Remove the FrameView from the frame. - pFrame->setView(NULL); - -} - -static jboolean LoadUrl(JNIEnv *env, jobject obj, jstring url) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeLoadUrl must take a valid frame pointer!"); - - const char* urlStr = env->GetStringUTFChars(url, NULL); - WebCore::String webcoreUrl(urlStr); - WebCore::ResourceRequest request(webcoreUrl); - WebCore::DeprecatedString protocol = request.url().protocol(); - // If the url is http(s) and doesn't have a host, it is a bad url. - if ((WebCore::equalIgnoringCase(protocol, "http") || - WebCore::equalIgnoringCase(protocol, "https")) && - request.url().host().isEmpty()) { - env->ReleaseStringUTFChars(url, urlStr); - return false; - } - - pFrame->loader()->load(request); - env->ReleaseStringUTFChars(url, urlStr); - return true; -} - - -static void LoadData(JNIEnv *env, jobject obj, jstring baseUrl, jstring data, - jstring mimeType, jstring encoding, jstring failUrl) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeLoadData must take a valid frame pointer!"); - - // Setup the resource request - const char* baseUrlStr = env->GetStringUTFChars(baseUrl, NULL); - WebCore::String baseUrlString(baseUrlStr); - WebCore::ResourceRequest request(baseUrlString); - - // Setup the substituteData - const char* dataStr = env->GetStringUTFChars(data, NULL); - WTF::RefPtr<WebCore::SharedBuffer> sharedBuffer = - new WebCore::SharedBuffer(); - LOG_ASSERT(dataStr, "nativeLoadData has a null data string."); - sharedBuffer->append(dataStr, strlen(dataStr)); - const char* mimeTypeStr = env->GetStringUTFChars(mimeType, NULL); - WebCore::String mimeTypeString(mimeTypeStr); - const char* encodingStr = env->GetStringUTFChars(encoding, NULL); - WebCore::String encodingString(encodingStr); - const char* failUrlStr = env->GetStringUTFChars(failUrl, NULL); - WebCore::KURL failURL(failUrlStr); - WebCore::SubstituteData substituteData(sharedBuffer, mimeTypeString, - encodingString, failURL); - - // Perform the load - pFrame->loader()->load(request, substituteData); - - // Release the Java strings - env->ReleaseStringUTFChars(baseUrl, baseUrlStr); - env->ReleaseStringUTFChars(data, dataStr); - env->ReleaseStringUTFChars(mimeType, mimeTypeStr); - env->ReleaseStringUTFChars(encoding, encodingStr); - env->ReleaseStringUTFChars(failUrl, failUrlStr); -} - -static void StopLoading(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeStopLoading must take a valid frame pointer!"); - LOGV("::WebCore:: stopLoading %p", pFrame); - - // Stop loading the page and do not send an unload event - pFrame->loader()->stopForUserCancel(); -} - -static jstring ExternalRepresentation(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "android_webcore_nativeExternalRepresentation must take a valid frame pointer!"); - - // Request external representation of the render tree - WebCore::DeprecatedString renderDump = externalRepresentation(pFrame->renderer()); - unsigned len = renderDump.length(); - if (!len) - return NULL; - return env->NewString((unsigned short*)renderDump.unicode(), len); -} - -static jstring DocumentAsText(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "android_webcore_nativeDocumentAsText must take a valid frame pointer!"); - - WebCore::Element *documentElement = pFrame->document()->documentElement(); - WebCore::String renderDump = ((WebCore::HTMLElement*)documentElement)->innerText(); - renderDump.append("\n"); - unsigned len = renderDump.length(); - if (!len) - return NULL; - return env->NewString((unsigned short*)renderDump.characters(), len); -} - -static void Reload(JNIEnv *env, jobject obj, jboolean allowStale) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeReload must take a valid frame pointer!"); - - WebCore::FrameLoader* loader = pFrame->loader(); - if (allowStale) - loader->reloadAllowingStaleData(loader->documentLoader()->overrideEncoding()); - else - loader->reload(); -} - -static void GoBackOrForward(JNIEnv *env, jobject obj, jint pos) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeGoBackOrForward must take a valid frame pointer!"); - - if (pos == 1) - pFrame->page()->goForward(); - else if (pos == -1) - pFrame->page()->goBack(); - else - pFrame->loader()->goBackOrForward(pos); -} - -static jobject StringByEvaluatingJavaScriptFromString(JNIEnv *env, jobject obj, jstring script) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "stringByEvaluatingJavaScriptFromString must take a valid frame pointer!"); - - const char* scriptStr = env->GetStringUTFChars(script, NULL); - WebCore::String result = pFrame->stringByEvaluatingJavaScriptFromString(scriptStr); - env->ReleaseStringUTFChars(script, scriptStr); - - unsigned len = result.length(); - if (len == 0) - return NULL; - return env->NewString((unsigned short*)result.characters(), len); -} - -static void AddJavascriptInterface(JNIEnv *env, jobject obj, jint nativeFramePointer, - jobject javascriptObj, jstring interfaceName) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = (WebCore::FrameAndroid*)nativeFramePointer; - LOG_ASSERT(pFrame, "nativeAddJavascriptInterface must take a valid frame pointer!"); - - const char* interfaceNameStr = env->GetStringUTFChars(interfaceName, NULL); - JavaVM* vm; - env->GetJavaVM(&vm); - LOGV("::WebCore:: addJSInterface: %p", pFrame); - pFrame->addJavascriptInterface((void*)(vm), javascriptObj, interfaceNameStr); - - env->ReleaseStringUTFChars(interfaceName, interfaceNameStr); -} - -static void SetCacheDisabled(JNIEnv *env, jobject obj, jboolean disabled) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::cache()->setDisabled(disabled); -} - -static jboolean CacheDisabled(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - return WebCore::cache()->disabled(); -} - -static void ClearCache(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - if (!WebCore::cache()->disabled()) { - // Disabling the cache will remove all resources from the cache. They may - // still live on if they are referenced by some Web page though. - WebCore::cache()->setDisabled(true); - WebCore::cache()->setDisabled(false); - } - // force JavaScript to GC when clear cache - WebCore::gcController().garbageCollectSoon(); - // clear image cache - SkImageRef_GlobalPool::SetRAMUsed(0); -} - -static jboolean DocumentHasImages(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "DocumentHasImages must take a valid frame pointer!"); - - return pFrame->document()->images()->length() > 0; -} - -static jboolean HasPasswordField(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "HasPasswordField must take a valid frame pointer!"); - - bool found = false; - WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms(); - WebCore::Node* node = form->firstItem(); - while (node && !found) { - WTF::Vector<WebCore::HTMLGenericFormElement*> elements = - ((WebCore::HTMLFormElement*)node)->formElements; - size_t size = elements.size(); - for (size_t i = 0; i< size && !found; i++) { - WebCore::HTMLGenericFormElement* e = elements[i]; - if (e->hasLocalName(WebCore::HTMLNames::inputTag)) { - if (((WebCore::HTMLInputElement*)e)->inputType() == - WebCore::HTMLInputElement::PASSWORD) - found = true; - } - } - node = form->nextItem(); - } - return found; -} - -static jobjectArray GetUsernamePassword(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "GetUsernamePassword must take a valid frame pointer!"); - jobjectArray strArray = NULL; - - WebCore::String username, password; - bool found = false; - WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms(); - WebCore::Node* node = form->firstItem(); - while (node && !found) { - WTF::Vector<WebCore::HTMLGenericFormElement*> elements = - ((WebCore::HTMLFormElement*)node)->formElements; - size_t size = elements.size(); - for (size_t i = 0; i< size && !found; i++) { - WebCore::HTMLGenericFormElement* e = elements[i]; - if (e->hasLocalName(WebCore::HTMLNames::inputTag)) { - WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e; - if (input->autoComplete() == false) - continue; - if (input->inputType() == WebCore::HTMLInputElement::PASSWORD) - password = input->value(); - else if (input->inputType() == WebCore::HTMLInputElement::TEXT) - username = input->value(); - if (!username.isNull() && !password.isNull()) - found = true; - } - } - node = form->nextItem(); - } - if (found) { - jclass stringClass = env->FindClass("java/lang/String"); - strArray = env->NewObjectArray(2, stringClass, NULL); - env->SetObjectArrayElement(strArray, 0, env->NewString((unsigned short *) - username.characters(), username.length())); - env->SetObjectArrayElement(strArray, 1, env->NewString((unsigned short *) - password.characters(), password.length())); - } - return strArray; -} - -static void SetUsernamePassword(JNIEnv *env, jobject obj, - jstring username, jstring password) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "SetUsernamePassword must take a valid frame pointer!"); - - WebCore::HTMLInputElement* usernameEle = NULL; - WebCore::HTMLInputElement* passwordEle = NULL; - bool found = false; - WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms(); - WebCore::Node* node = form->firstItem(); - while (node && !found) { - WTF::Vector<WebCore::HTMLGenericFormElement*> elements = - ((WebCore::HTMLFormElement*)node)->formElements; - size_t size = elements.size(); - for (size_t i = 0; i< size && !found; i++) { - WebCore::HTMLGenericFormElement* e = elements[i]; - if (e->hasLocalName(WebCore::HTMLNames::inputTag)) { - WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e; - if (input->autoComplete() == false) - continue; - if (input->inputType() == WebCore::HTMLInputElement::PASSWORD) - passwordEle = input; - else if (input->inputType() == WebCore::HTMLInputElement::TEXT) - usernameEle = input; - if (usernameEle != NULL && passwordEle != NULL) - found = true; - } - } - node = form->nextItem(); - } - if (found) { - const char* usernameStr = env->GetStringUTFChars(username, NULL); - const char* passwordStr = env->GetStringUTFChars(password, NULL); - usernameEle->setValue(usernameStr); - passwordEle->setValue(passwordStr); - env->ReleaseStringUTFChars(username, usernameStr); - env->ReleaseStringUTFChars(password, passwordStr); - } -} - -static jobject GetFormTextData(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "GetFormTextData must take a valid frame pointer!"); - jobject hashMap = NULL; - - WTF::PassRefPtr<WebCore::HTMLCollection> collection = pFrame->document()->forms(); - if (collection->length() > 0) { - jclass mapClass = env->FindClass("java/util/HashMap"); - LOG_ASSERT(mapClass, "Could not find HashMap class!"); - jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V"); - LOG_ASSERT(init, "Could not find constructor for HashMap"); - hashMap = env->NewObject(mapClass, init, 1); - LOG_ASSERT(hashMap, "Could not create a new HashMap"); - jmethodID put = env->GetMethodID(mapClass, "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); - LOG_ASSERT(put, "Could not find put method on HashMap"); - - static const WebCore::AtomicString text("text"); - static const WebCore::AtomicString off("off"); - - WebCore::HTMLFormElement* form; - WebCore::HTMLInputElement* input; - for (WebCore::Node* node = collection->firstItem(); node; node = collection->nextItem()) { - form = static_cast<WebCore::HTMLFormElement*>(node); - if (form->autoComplete()) { - WTF::Vector<WebCore::HTMLGenericFormElement*> elements = form->formElements; - size_t size = elements.size(); - for (size_t i = 0; i < size; i++) { - WebCore::HTMLGenericFormElement* e = elements[i]; - if (e->type() == text) { - if (e->hasAttribute(WebCore::HTMLNames::autocompleteAttr)) { - const WebCore::AtomicString& attr = e->getAttribute(WebCore::HTMLNames::autocompleteAttr); - if (attr == off) - continue; - } - input = (WebCore::HTMLInputElement*) e; - WebCore::String value = input->value(); - int len = value.length(); - if (len) { - const WebCore::AtomicString& name = input->name(); - jstring key = env->NewString((jchar *)name.characters(), name.length()); - jstring val = env->NewString((jchar *)value.characters(), len); - LOG_ASSERT(key && val, "name or value not set"); - env->CallObjectMethod(hashMap, put, key, val); - env->DeleteLocalRef(key); - env->DeleteLocalRef(val); - } - } - } - } - } - env->DeleteLocalRef(mapClass); - - } - return hashMap; -} - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gBrowserFrameNativeMethods[] = { - /* name, signature, funcPtr */ - { "nativeCallPolicyFunction", "(II)V", - (void*) CallPolicyFunction }, - { "nativeCreateFrame", "(Landroid/content/res/AssetManager;Landroid/webkit/WebBackForwardList;)V", - (void*) CreateFrame }, - { "nativeCreateView", "(Landroid/webkit/WebViewCore;)V", - (void*) CreateView }, - { "nativeDestroyFrame", "()V", - (void*) DestroyFrame }, - { "nativeDetachView", "()V", - (void*) DetachView }, - { "stopLoading", "()V", - (void*) StopLoading }, - { "nativeLoadUrl", "(Ljava/lang/String;)Z", - (void*) LoadUrl }, - { "nativeLoadData", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", - (void*) LoadData }, - { "externalRepresentation", "()Ljava/lang/String;", - (void*) ExternalRepresentation }, - { "documentAsText", "()Ljava/lang/String;", - (void*) DocumentAsText }, - { "reload", "(Z)V", - (void*) Reload }, - { "goBackOrForward", "(I)V", - (void*) GoBackOrForward }, - { "nativeAddJavascriptInterface", "(ILjava/lang/Object;Ljava/lang/String;)V", - (void*) AddJavascriptInterface }, - { "stringByEvaluatingJavaScriptFromString", - "(Ljava/lang/String;)Ljava/lang/String;", - (void*) StringByEvaluatingJavaScriptFromString }, - { "setCacheDisabled", "(Z)V", - (void*) SetCacheDisabled }, - { "cacheDisabled", "()Z", - (void*) CacheDisabled }, - { "clearCache", "()V", - (void*) ClearCache }, - { "documentHasImages", "()Z", - (void*) DocumentHasImages }, - { "hasPasswordField", "()Z", - (void*) HasPasswordField }, - { "getUsernamePassword", "()[Ljava/lang/String;", - (void*) GetUsernamePassword }, - { "setUsernamePassword", "(Ljava/lang/String;Ljava/lang/String;)V", - (void*) SetUsernamePassword }, - { "getFormTextData", "()Ljava/util/HashMap;", - (void*) GetFormTextData } -}; - -int register_webcoreframebridge(JNIEnv* env) -{ - jclass clazz = env->FindClass("android/webkit/BrowserFrame"); - LOG_ASSERT(clazz, "Cannot find BrowserFrame"); - gFrameAndroidField = env->GetFieldID(clazz, "mNativeFrame", "I"); - LOG_ASSERT(gFrameAndroidField, "Cannot find mNativeFrame on BrowserFrame"); - - return jniRegisterNativeMethods(env, "android/webkit/BrowserFrame", - gBrowserFrameNativeMethods, NELEM(gBrowserFrameNativeMethods)); -} - -} /* namespace android */ - diff --git a/WebCore/platform/android/jni/WebCoreFrameBridge.h b/WebCore/platform/android/jni/WebCoreFrameBridge.h deleted file mode 100644 index ba89f19..0000000 --- a/WebCore/platform/android/jni/WebCoreFrameBridge.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -** Copyright 2006-2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef WEBCOREFRAMEBRIDGE_H -#define WEBCOREFRAMEBRIDGE_H - -#include "FrameLoaderClient.h" -#include "PlatformString.h" -#include "WebCoreRefObject.h" -#include <jni.h> - -namespace WebCore { - class FrameAndroid; - class HistoryItem; - class Image; - class RenderPart; - class ResourceHandle; - class ResourceRequest; -} - -class WebCoreViewBridge; - -namespace android { - -class WebCoreResourceLoader; - -class WebCoreFrameBridge : public WebCoreRefObject { - public: - WebCoreFrameBridge(JNIEnv* env, jobject obj, jobject historyList); - ~WebCoreFrameBridge(); - - WebCoreResourceLoader* startLoadingResource(WebCore::ResourceHandle*, - const WebCore::ResourceRequest& request, - bool isHighPriority, - bool synchronous); - - void reportError(int errorCode, const WebCore::String& description, - const WebCore::String& failingUrl); - - void loadStarted(WebCore::FrameAndroid* frame); - - void transitionToCommitted(WebCore::Frame* frame); - - void didFinishLoad(WebCore::Frame* frame); - - void addHistoryItem(WebCore::HistoryItem* item); - - void removeHistoryItem(int index); - - void updateHistoryIndex(int newIndex); - - void setTitle(const WebCore::String& title); - - void windowObjectCleared(WebCore::FrameAndroid* frame); - - void setProgress(float newProgress); - - const WebCore::String userAgentForURL(const WebCore::KURL* url); - - void didReceiveIcon(WebCore::Image* icon); - - void updateVisitedHistory(const WebCore::KURL& url, bool reload); - - bool canHandleRequest(const WebCore::ResourceRequest& request); - - WebCore::Frame* createWindow(bool dialog, bool userGesture); - - void requestFocus() const; - - void closeWindow(WebCoreViewBridge* viewBridge); - - void decidePolicyForFormResubmission(WebCore::FramePolicyFunction func); - - void setUserAgent(WebCore::String userAgent) { mUserAgent = userAgent; } - - /** - * This function is called during a key event so that canHandleRequest can - * avoid asking the application to override the url loading. If a load is - * due to a key event, then we ask the application if it wants to override - * the load. Otherwise, we attempt to load the resource internally. - */ - void setInKeyHandler(bool inKeyHandler) { mInKeyHandler = inKeyHandler; } - - private: - struct JavaBrowserFrame; - JavaBrowserFrame* mJavaFrame; - WebCore::String mUserAgent; - bool mInKeyHandler; -}; - -} // namespace android - -#endif // WEBCOREFRAMEBRIDGE_H diff --git a/WebCore/platform/android/jni/WebCoreJni.cpp b/WebCore/platform/android/jni/WebCoreJni.cpp deleted file mode 100644 index 8ba3d0b..0000000 --- a/WebCore/platform/android/jni/WebCoreJni.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "WebCoreJni.h" -#include <jni.h> - -#ifdef LOG -#undef LOG -#endif -#define LOG_TAG "webcoreglue" -#include <utils/Log.h> - -namespace android { - -JavaVM* WebCoreJni::mJavaVM; - -extern int register_webcoreframebridge(JNIEnv*); -extern int register_javabridge(JNIEnv*); -extern int register_resource_loader(JNIEnv*); -extern int register_webviewcore(JNIEnv*); -extern int register_webhistory(JNIEnv*); -extern int register_webicondatabase(JNIEnv*); -extern int register_websettings(JNIEnv*); -extern int register_webview(JNIEnv*); - -} - -struct RegistrationMethod { - const char* name; - int (*func)(JNIEnv*); -}; - -static RegistrationMethod gWebCoreRegMethods[] = { - { "JavaBridge", android::register_javabridge }, - { "WebCoreFrameBridge", android::register_webcoreframebridge }, - { "WebCoreResourceLoader", android::register_resource_loader }, - { "WebViewCore", android::register_webviewcore }, - { "WebHistory", android::register_webhistory }, - { "WebIconDatabase", android::register_webicondatabase }, - { "WebSettings", android::register_websettings }, - { "WebView", android::register_webview } -}; - -EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) -{ - // Save the JavaVM pointer for use globally. - android::WebCoreJni::setJavaVM(vm); - - JNIEnv* env = NULL; - jint result = -1; - - if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { - LOGE("GetEnv failed!"); - return result; - } - LOG_ASSERT(env, "Could not retrieve the env!"); - - const RegistrationMethod* method = gWebCoreRegMethods; - const RegistrationMethod* end = method + sizeof(gWebCoreRegMethods)/sizeof(RegistrationMethod); - while (method != end) { - if (method->func(env) < 0) { - LOGE("%s registration failed!", method->name); - return result; - } - method++; - } - - return JNI_VERSION_1_4; -} diff --git a/WebCore/platform/android/jni/WebCoreJni.h b/WebCore/platform/android/jni/WebCoreJni.h deleted file mode 100644 index 4031d43..0000000 --- a/WebCore/platform/android/jni/WebCoreJni.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef WEBCOREJNI_H -#define WEBCOREJNI_H - -#include <jni.h> - -namespace android { - -class WebCoreJni { - static JavaVM *mJavaVM; - public: - static void setJavaVM(JavaVM *vm) { mJavaVM = vm; } - static JavaVM *getJavaVM() { return mJavaVM; } -}; - -} // namespace android - -#endif // WEBCOREJNI_H diff --git a/WebCore/platform/android/jni/WebCoreRefObject.h b/WebCore/platform/android/jni/WebCoreRefObject.h deleted file mode 100644 index 7e96191..0000000 --- a/WebCore/platform/android/jni/WebCoreRefObject.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef WEBCORE_FOUNDATION_h -#define WEBCORE_FOUNDATION_h - -#include "SkRefCnt.h" - -typedef SkRefCnt WebCoreRefObject; - -static inline WebCoreRefObject* Retain(WebCoreRefObject* obj) -{ - if (obj) - obj->ref(); - return obj; -} - -static inline void Release(WebCoreRefObject* obj) -{ - if (obj) - obj->unref(); -} - -#endif // WEBCORE_FOUNDATION_h diff --git a/WebCore/platform/android/jni/WebCoreResourceLoader.cpp b/WebCore/platform/android/jni/WebCoreResourceLoader.cpp deleted file mode 100644 index 3807a2a..0000000 --- a/WebCore/platform/android/jni/WebCoreResourceLoader.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/* -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "webcoreglue" - -#include <config.h> -#include <wtf/Platform.h> - -#include "WebCoreResourceLoader.h" -#include "SkUtils.h" -#include "WebCoreJni.h" - -#include "ResourceError.h" -#include "ResourceHandle.h" -#include "ResourceHandleClient.h" -#include "ResourceHandleInternal.h" -#include "ResourceResponse.h" - -#ifdef ANDROID_INSTRUMENT -#include "Frame.h" -#include "SystemTime.h" -#endif - -#undef LOG -#include <utils/Log.h> -#include <utils/misc.h> -#include <JNIHelp.h> -#include <SkTypes.h> -#include <stdlib.h> - -#ifdef ANDROID_INSTRUMENT -static uint32_t sTotalTimeUsed = 0; - -namespace WebCore { -void Frame::resetResourceLoadTimeCounter() -{ - sTotalTimeUsed = 0; -} - -void Frame::reportResourceLoadTimeCounter() -{ - LOG(LOG_DEBUG, "WebCore", "*-* Total native 3 (resource load) time: %d ms\n", - sTotalTimeUsed); -} -} -#endif - -namespace android { - -#ifdef ANDROID_INSTRUMENT -class TimeCounterRC { -public: - TimeCounterRC() { - mStartTime = WebCore::get_thread_msec(); - } - - ~TimeCounterRC() { - sTotalTimeUsed += WebCore::get_thread_msec() - mStartTime; - } - -private: - uint32_t mStartTime; -}; -#endif - -// ---------------------------------------------------------------------------- - -static struct resourceloader_t { - jfieldID mObject; - jmethodID mCancelMethodID; - jmethodID mDownloadFileMethodID; - jmethodID mWillLoadFromCacheMethodID; -} gResourceLoader; - -// ---------------------------------------------------------------------------- - -/** - * Helper method for checking java exceptions - * @return true if an exception occurred. - */ -static bool checkException(JNIEnv* env) -{ - if (env->ExceptionCheck() != 0) - { - LOGE("*** Uncaught exception returned from Java call!\n"); - env->ExceptionDescribe(); - return true; - } - return false; -} - -// ---------------------------------------------------------------------------- - -extern JavaVM* jnienv_to_javavm(JNIEnv* env); -extern JNIEnv* javavm_to_jnienv(JavaVM* vm); - -//----------------------------------------------------------------------------- - -#define GET_NATIVE_HANDLE(env, obj) ((WebCore::ResourceHandle*)env->GetIntField(obj, gResourceLoader.mObject)) -#define SET_NATIVE_HANDLE(env, obj, handle) (env->SetIntField(obj, gResourceLoader.mObject, handle)) - -//----------------------------------------------------------------------------- -// ResourceLoadHandler - -WebCoreResourceLoader::WebCoreResourceLoader(JNIEnv *env, jobject jLoadListener) -{ - mJvm = jnienv_to_javavm(env); - mJLoader = env->NewGlobalRef(jLoadListener); -} - -WebCoreResourceLoader::~WebCoreResourceLoader() -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - SET_NATIVE_HANDLE(env, mJLoader, 0); - env->DeleteGlobalRef(mJLoader); - mJLoader = 0; -} - -void WebCoreResourceLoader::cancel() -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - env->CallVoidMethod(mJLoader, gResourceLoader.mCancelMethodID); - SET_NATIVE_HANDLE(env, mJLoader, 0); - checkException(env); -} - -void WebCoreResourceLoader::downloadFile() -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - env->CallVoidMethod(mJLoader, gResourceLoader.mDownloadFileMethodID); - checkException(env); -} - -/* -* This static method is called to check to see if a POST response is in -* the cache. This may be slow, but is only used during a navigation to -* a POST response. -*/ -bool WebCoreResourceLoader::willLoadFromCache(const WebCore::KURL& url) -{ - JNIEnv* env = javavm_to_jnienv(android::WebCoreJni::getJavaVM()); - WebCore::DeprecatedString urlStr = url.deprecatedString(); - jstring jUrlStr = env->NewString((unsigned short *)urlStr.unicode(), urlStr.length()); - jclass resourceLoader = env->FindClass("android/webkit/LoadListener"); - bool val = env->CallStaticBooleanMethod(resourceLoader, - gResourceLoader.mWillLoadFromCacheMethodID, jUrlStr); - checkException(env); - env->DeleteLocalRef(jUrlStr); - - return val; -} - -// ---------------------------------------------------------------------------- -void WebCoreResourceLoader::SetResponseHeader(JNIEnv* env, jobject obj, jint nativeResponse, jstring key, jstring val) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - - WebCore::ResourceResponse* response = (WebCore::ResourceResponse*)nativeResponse; - LOG_ASSERT(response, "nativeSetResponseHeader must take a valid response pointer!"); - - LOG_ASSERT(key, "How did a null value become a key?"); - if (val) { - const char* keyStr = env->GetStringUTFChars(key, NULL); - const char* valStr = env->GetStringUTFChars(val, NULL); - if (valStr) - response->setHTTPHeaderField(keyStr, valStr); - - env->ReleaseStringUTFChars(key, keyStr); - env->ReleaseStringUTFChars(val, valStr); - } -} - -jint WebCoreResourceLoader::CreateResponse(JNIEnv* env, jobject obj, jstring url, jint statusCode, - jstring statusText, jstring mimeType, jlong expectedLength, - jstring encoding, jlong expireTime) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - LOG_ASSERT(url, "Must have a url in the response!"); - const char* urlStr = env->GetStringUTFChars(url, NULL); - const char* encodingStr = NULL; - const char* mimeTypeStr = NULL; - if (mimeType) { - mimeTypeStr = env->GetStringUTFChars(mimeType, NULL); - LOGV("Response setMIMEType: %s", mimeTypeStr); - } - if (encoding) { - encodingStr = env->GetStringUTFChars(encoding, NULL); - LOGV("Response setTextEncodingName: %s", encodingStr); - } - WebCore::ResourceResponse* response = new WebCore::ResourceResponse(WebCore::KURL(urlStr), - mimeTypeStr, (long long)expectedLength, encodingStr, WebCore::String()); - response->setHTTPStatusCode(statusCode); - if (statusText) { - const char* statusStr = env->GetStringUTFChars(statusText, NULL); - response->setHTTPStatusText(statusStr); - LOGV("Response setStatusText: %s", statusStr); - env->ReleaseStringUTFChars(statusText, statusStr); - } - // FIXME: This assumes that time_t is a long and that long is the same size as int. - if ((unsigned long)expireTime > INT_MAX) - expireTime = INT_MAX; - response->setExpirationDate((time_t)expireTime); - if (encoding) - env->ReleaseStringUTFChars(encoding, encodingStr); - if (mimeType) - env->ReleaseStringUTFChars(mimeType, mimeTypeStr); - env->ReleaseStringUTFChars(url, urlStr); - return (int)response; -} - -void WebCoreResourceLoader::ReceivedResponse(JNIEnv* env, jobject obj, jint nativeResponse) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeReceivedResponse must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - WebCore::ResourceResponse* response = (WebCore::ResourceResponse*)nativeResponse; - LOG_ASSERT(response, "nativeReceivedResponse must take a valid resource pointer!"); - handle->client()->didReceiveResponse(handle, *response); - // As the client makes a copy of the response, delete it here. - delete response; -} - -void WebCoreResourceLoader::AddData(JNIEnv* env, jobject obj, jbyteArray dataArray, jint length) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - LOGV("webcore_resourceloader data(%d)", length); - - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeAddData must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - SkAutoMemoryUsageProbe mup("android_webcore_resourceloader_nativeAddData"); - - bool result = false; - jbyte * data = env->GetByteArrayElements(dataArray, NULL); - - LOG_ASSERT(handle->client(), "Why do we not have a client?"); - handle->client()->didReceiveData(handle, (const char *)data, length, length); - env->ReleaseByteArrayElements(dataArray, data, JNI_ABORT); -} - -void WebCoreResourceLoader::Finished(JNIEnv* env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - LOGV("webcore_resourceloader finished"); - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeFinished must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - LOG_ASSERT(handle->client(), "Why do we not have a client?"); - handle->client()->didFinishLoading(handle); -} - -jstring WebCoreResourceLoader::RedirectedToUrl(JNIEnv* env, jobject obj, - jstring baseUrl, jstring redirectTo, jint nativeResponse) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - LOGV("webcore_resourceloader redirectedToUrl"); - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeRedirectedToUrl must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return NULL; - - const char* baseStr = env->GetStringUTFChars(baseUrl, NULL); - const char* redirectStr = env->GetStringUTFChars(redirectTo, NULL); - LOG_ASSERT(handle->client(), "Why do we not have a client?"); - WebCore::ResourceRequest r = handle->request(); - WebCore::KURL url(baseStr, redirectStr); - r.setURL(url); - if (r.httpMethod() == "POST") - r.setHTTPMethod("GET"); - env->ReleaseStringUTFChars(baseUrl, baseStr); - env->ReleaseStringUTFChars(redirectTo, redirectStr); - WebCore::ResourceResponse* response = (WebCore::ResourceResponse*)nativeResponse; - // If the url fails to resolve the relative path, return null. - if (url.protocol().isEmpty()) { - delete response; - return NULL; - } - handle->client()->willSendRequest(handle, r, *response); - delete response; - WebCore::String s = url.string(); - return env->NewString((unsigned short*)s.characters(), s.length()); -} - -void WebCoreResourceLoader::Error(JNIEnv* env, jobject obj, jint id, jstring description, - jstring failingUrl) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - LOGV("webcore_resourceloader error"); - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeError must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - const char* descStr = env->GetStringUTFChars(description, NULL); - const char* failUrl = env->GetStringUTFChars(failingUrl, NULL); - handle->client()->didFail(handle, WebCore::ResourceError("", id, - WebCore::String(failUrl), WebCore::String(descStr))); - env->ReleaseStringUTFChars(failingUrl, failUrl); - env->ReleaseStringUTFChars(description, descStr); -} - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gResourceloaderMethods[] = { - /* name, signature, funcPtr */ - { "nativeSetResponseHeader", "(ILjava/lang/String;Ljava/lang/String;)V", - (void*) WebCoreResourceLoader::SetResponseHeader }, - { "nativeCreateResponse", "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;JLjava/lang/String;J)I", - (void*) WebCoreResourceLoader::CreateResponse }, - { "nativeReceivedResponse", "(I)V", - (void*) WebCoreResourceLoader::ReceivedResponse }, - { "nativeAddData", "([BI)V", - (void*) WebCoreResourceLoader::AddData }, - { "nativeFinished", "()V", - (void*) WebCoreResourceLoader::Finished }, - { "nativeRedirectedToUrl", "(Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;", - (void*) WebCoreResourceLoader::RedirectedToUrl }, - { "nativeError", "(ILjava/lang/String;Ljava/lang/String;)V", - (void*) WebCoreResourceLoader::Error } -}; - -int register_resource_loader(JNIEnv* env) -{ - jclass resourceLoader = env->FindClass("android/webkit/LoadListener"); - LOG_FATAL_IF(resourceLoader == NULL, - "Unable to find class android/webkit/LoadListener"); - - gResourceLoader.mObject = - env->GetFieldID(resourceLoader, "mNativeLoader", "I"); - LOG_FATAL_IF(gResourceLoader.mObject == NULL, - "Unable to find android/webkit/LoadListener.mNativeLoader"); - - gResourceLoader.mCancelMethodID = - env->GetMethodID(resourceLoader, "cancel", "()V"); - LOG_FATAL_IF(gResourceLoader.mCancelMethodID == NULL, - "Could not find method cancel on LoadListener"); - - gResourceLoader.mDownloadFileMethodID = - env->GetMethodID(resourceLoader, "downloadFile", "()V"); - LOG_FATAL_IF(gResourceLoader.mDownloadFileMethodID == NULL, - "Could not find method downloadFile on LoadListener"); - - gResourceLoader.mWillLoadFromCacheMethodID = - env->GetStaticMethodID(resourceLoader, "willLoadFromCache", "(Ljava/lang/String;)Z"); - LOG_FATAL_IF(gResourceLoader.mWillLoadFromCacheMethodID == NULL, - "Could not find static method willLoadFromCache on LoadListener"); - - return jniRegisterNativeMethods(env, "android/webkit/LoadListener", - gResourceloaderMethods, NELEM(gResourceloaderMethods)); -} - -} /* namespace android */ - diff --git a/WebCore/platform/android/jni/WebCoreResourceLoader.h b/WebCore/platform/android/jni/WebCoreResourceLoader.h deleted file mode 100644 index e3b3cc7..0000000 --- a/WebCore/platform/android/jni/WebCoreResourceLoader.h +++ /dev/null @@ -1,67 +0,0 @@ -/* //device/libs/android_runtime/android_webcore_resource_loader.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef ANDROID_WEBKIT_RESOURCELOADLISTENER_H -#define ANDROID_WEBKIT_RESOURCELOADLISTENER_H - -#include "KURL.h" - -#include "WebCoreRefObject.h" -#include <jni.h> - -namespace android { - -class WebCoreResourceLoader : public WebCoreRefObject -{ -public: - WebCoreResourceLoader(JNIEnv *env, jobject jLoadListener); - virtual ~WebCoreResourceLoader(); - - /** - * Call to java to cancel the current load. - */ - void cancel(); - - /** - * Call to java to download the current load rather than feed it - * back to WebCore - */ - void downloadFile(); - - /** - * Call to java to find out if this URL is in the cache - */ - static bool willLoadFromCache(const WebCore::KURL& url); - - // Native jni functions - static void SetResponseHeader(JNIEnv*, jobject, jint, jstring, jstring); - static jint CreateResponse(JNIEnv*, jobject, jstring, jint, jstring, - jstring, jlong, jstring, jlong); - static void ReceivedResponse(JNIEnv*, jobject, jint); - static void AddData(JNIEnv*, jobject, jbyteArray, jint); - static void Finished(JNIEnv*, jobject); - static jstring RedirectedToUrl(JNIEnv*, jobject, jstring, jstring, jint); - static void Error(JNIEnv*, jobject, jint, jstring, jstring); - -private: - JavaVM* mJvm; - jobject mJLoader; -}; - -} // end namespace android - -#endif diff --git a/WebCore/platform/android/jni/WebCoreViewBridge.h b/WebCore/platform/android/jni/WebCoreViewBridge.h deleted file mode 100644 index 58aa953..0000000 --- a/WebCore/platform/android/jni/WebCoreViewBridge.h +++ /dev/null @@ -1,191 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef WEBCORE_VIEW_BRIDGE_H -#define WEBCORE_VIEW_BRIDGE_H - -#include "IntRect.h" -#include "SkTDArray.h" -#include "WebCoreRefObject.h" -#include "Widget.h" -#include <ui/KeycodeLabels.h> -#include <stdlib.h> -namespace WebCore -{ - class GraphicsContext; - class Node; - class StringImpl; - class String; - class RenderText; - class Frame; - class FrameView; -} - -class WebCoreReply : public WebCoreRefObject { -public: - virtual ~WebCoreReply() {} - - virtual void replyInt(int value) { - SkDEBUGF(("WebCoreReply::replyInt(%d) not handled\n", value)); - } - - virtual void replyIntArray(SkTDArray<int> array) { - SkDEBUGF(("WebCoreReply::replyIntArray() not handled\n")); - } - // add more replyFoo signatures as needed -}; - -class WebCoreViewBridge : public WebCoreRefObject { -public: - WebCoreViewBridge(): mBounds(0,0,0,0), mScreenWidth(0), mScale(100), - mWidget(NULL), mParent(NULL) {} - virtual ~WebCoreViewBridge() { Release(mParent); } - - virtual void setParent(WebCoreViewBridge* parent) {Release(mParent); mParent = parent; Retain(mParent); } - virtual WebCoreViewBridge* getParent() { return mParent; } - - // these are needed for WidgetAndroid.cpp - virtual void draw(WebCore::GraphicsContext* ctx, - const WebCore::IntRect& rect, bool invalCache) = 0; - virtual void layout() {} - virtual bool isEnabled() const { return true; } - virtual void setEnabled(bool) {} - virtual bool hasFocus() const { return true; } - virtual void setFocus(bool) {} - virtual void didFirstLayout() {} - virtual void restoreScale(int) {} - - // Used by the page cache - virtual void setView(WebCore::FrameView* view) {} - - const WebCore::IntRect& getBounds() const - { - return mBounds; - } - virtual void setBounds(int left, int top, int right, int bottom) - { - this->setLocation(left, top); - this->setSize(right - left, bottom - top); - } - virtual int getMaxXScroll() const { return width() >> 2; } - virtual int getMaxYScroll() const { return height() >> 2; } - virtual void notifyFocusSet() {} - virtual void notifyProgressFinished() {} - // Subclasses should implement this if they want to do something after being resized - virtual void onResize() {} - - // These are referenced by Scrollview (and others) - virtual bool scrollIntoView(WebCore::IntRect rect, bool force) { return false; } - virtual void scrollTo(int x, int y, bool animate=false) {} - virtual void scrollBy(int x, int y) {} - virtual void contentInvalidate(const WebCore::IntRect &rect) - { - if (mParent) - mParent->contentInvalidate(rect); - } - virtual void contentInvalidate() - { - if (mParent) - mParent->contentInvalidate(); - } - // invalidate the view/display, NOT the content/DOM - virtual void viewInvalidate() - { - if (mParent) - mParent->viewInvalidate(); - } - - // these need not be virtual - // - void setSize(int w, int h) - { - int ow = width(); - int oh = height(); - mBounds.setWidth(w); - mBounds.setHeight(h); - // Only call onResize if the new size is different. - if (w != ow || h != oh) - onResize(); - } - - // used by layout when it needs to wrap content column around screen - void setSizeScreenWidthAndScale(int w, int h, int screenWidth, int scale) - { - int ow = width(); - int oh = height(); - int osw = mScreenWidth; - mBounds.setWidth(w); - mBounds.setHeight(h); - mScreenWidth = screenWidth; - mScale = scale; - // Only call onResize if the new size is different. - if (w != ow || h != oh || screenWidth != osw) - onResize(); - } - - void setLocation(int x, int y) - { - mBounds.setX(x); - mBounds.setY(y); - } - - int width() const { return mBounds.width(); } - int height() const { return mBounds.height(); } - int locX() const { return mBounds.x(); } - int locY() const { return mBounds.y(); } - int screenWidth() const { return mParent ? mParent->screenWidth() : mScreenWidth; } - int scale() const { return mParent ? mParent->scale() : mScale; } - - // called by RenderPopupMenuAndroid - virtual void popupRequest(WebCoreReply* reply, - int currIndex, - const uint16_t** labels, // the first short is the length (number of following shorts) - size_t labelCount, // the number of label strings - const int enabled[], // bools telling which corresponding labels are selectable - size_t enabledCount) // length of the enabled array, which should equal labelCount - { - if (mParent) - mParent->popupRequest(reply, currIndex, labels, labelCount, enabled, enabledCount); - } - - //implemented in android_widget_htmlwidget - virtual void removeFrameGeneration(WebCore::Frame* ) {} - virtual void updateFrameGeneration(WebCore::Frame* ) {} - virtual void jsAlert(const WebCore::String& url, const WebCore::String& text) { } - virtual bool jsConfirm(const WebCore::String& url, const WebCore::String& text) { return false; } - virtual bool jsPrompt(const WebCore::String& url, const WebCore::String& message, const WebCore::String& defaultValue, WebCore::String& result) { return false;} - virtual bool jsUnload(const WebCore::String& url, const WebCore::String& message) { return false; } - - virtual void updateTextfield(WebCore::Node* pointer, bool changeToPassword, const WebCore::String& text) - { - if (mParent) - mParent->updateTextfield(pointer, changeToPassword, text); - } - - void setWidget(WebCore::Widget* w) { mWidget = w; } - WebCore::Widget* widget() { return mWidget; } - -private: - WebCore::IntRect mBounds; - int mScreenWidth; - int mScale; - WebCore::Widget* mWidget; -protected: - WebCoreViewBridge* mParent; -}; - -#endif // WEBCORE_VIEW_BRIDGE_H diff --git a/WebCore/platform/android/jni/WebHistory.cpp b/WebCore/platform/android/jni/WebHistory.cpp deleted file mode 100644 index 4248c68..0000000 --- a/WebCore/platform/android/jni/WebHistory.cpp +++ /dev/null @@ -1,969 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "webhistory" - -#include <config.h> -#include <wtf/OwnPtr.h> -#include <wtf/Platform.h> - -#include "WebHistory.h" - -#include "BackForwardList.h" -#include "CString.h" -#include "DocumentLoader.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameLoaderClientAndroid.h" -#include "FrameTree.h" -#include "HistoryItem.h" -#include "Page.h" -#include "TextEncoding.h" -#include "WebCoreFrameBridge.h" - -#undef LOG -#include <JNIHelp.h> -#include <SkUtils.h> -#include <utils/Log.h> -#include <utils/misc.h> - -namespace android { - -// Forward declarations -static void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item); -static void write_children_recursive(WTF::Vector<char>& v, WebCore::HistoryItem* parent); -static bool read_item_recursive(WebCore::HistoryItem* child, const char** pData, int length); - -// Field ids for WebHistoryItems -struct WebHistoryItemFields { - jmethodID mInit; - jmethodID mUpdate; - jfieldID mTitle; - jfieldID mUrl; -} gWebHistoryItem; - -struct WebBackForwardListFields { - jmethodID mAddHistoryItem; - jmethodID mRemoveHistoryItem; - jfieldID mCurrentIndex; -} gWebBackForwardList; - -//-------------------------------------------------------------------------- -// WebBackForwardList native methods. -//-------------------------------------------------------------------------- - -static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame) -{ - LOG_ASSERT(frame, "Close needs a valid Frame pointer!"); - WebCore::Frame* pFrame = (WebCore::Frame*)frame; - - WebCore::BackForwardList* list = pFrame->page()->backForwardList(); - RefPtr<WebCore::HistoryItem> current = list->currentItem(); - // Remove each item instead of using close(). close() is intended to be used - // right before the list is deleted. - WebCore::HistoryItemVector& entries = list->entries(); - int size = entries.size(); - for (int i = size - 1; i >= 0; --i) - list->removeItem(entries[i].get()); - // Add the current item back to the list. - if (current) { - current->setBridge(NULL); - // addItem will update the children to match the newly created bridge - list->addItem(current); - - /* - * The Grand Prix site uses anchor navigations to change the display. - * WebKit tries to be smart and not load child frames that have the - * same history urls during an anchor navigation. This means that the - * current history item stored in the child frame's loader does not - * match the item found in the history tree. If we remove all the - * entries in the back/foward list, we have to restore the entire tree - * or else a HistoryItem might have a deleted parent. - * - * In order to restore the history tree correctly, we have to look up - * all the frames first and then look up the history item. We do this - * because the history item in the tree may be null at this point. - * Unfortunately, a HistoryItem can only search its immediately - * children so we do a breadth-first rebuild of the tree. - */ - - // Keep a small list of child frames to traverse. - WTF::Vector<WebCore::Frame*> frameQueue; - // Fix the top-level item. - pFrame->loader()->setCurrentHistoryItem(current); - WebCore::Frame* child = pFrame->tree()->firstChild(); - // Remember the parent history item so we can search for a child item. - RefPtr<WebCore::HistoryItem> parent = current; - while (child) { - // Use the old history item since the current one may have a - // deleted parent. - WebCore::HistoryItem* item = parent->childItemWithName(child->tree()->name()); - child->loader()->setCurrentHistoryItem(item); - // Append the first child to the queue if it exists. - if (WebCore::Frame* f = child->tree()->firstChild()) - frameQueue.append(f); - child = child->tree()->nextSibling(); - // If we don't have a sibling for this frame and the queue isn't - // empty, use the next entry in the queue. - if (!child && !frameQueue.isEmpty()) { - child = frameQueue.at(0); - frameQueue.remove(0); - // Figure out the parent history item used when searching for - // the history item to use. - parent = child->tree()->parent()->loader()->currentHistoryItem(); - } - } - } -} - -static void WebHistoryRestoreIndex(JNIEnv* env, jobject obj, jint frame, jint index) -{ - LOG_ASSERT(frame, "RestoreState needs a valid Frame pointer!"); - WebCore::Frame* pFrame = (WebCore::Frame*)frame; - - // Set the current index in the list. - WebCore::BackForwardList* list = pFrame->page()->backForwardList(); - WebCore::HistoryItem* currentItem = list->entries()[index].get(); - list->goToItem(currentItem); - - // Update the current and previous history item. - WebCore::FrameLoader* loader = pFrame->loader(); - loader->setCurrentHistoryItem(currentItem); - loader->setPreviousHistoryItem(list->backItem()); - - // Update the request with the current item's info. - WebCore::ResourceRequest& request = loader->documentLoader()->request(); - request.setURL(currentItem->url()); - request.setMainDocumentURL(currentItem->url()); - if (currentItem->originalFormData()) { - request.setHTTPMethod("POST"); - request.setHTTPContentType(currentItem->formContentType()); - request.setHTTPReferrer(currentItem->formReferrer()); - request.setHTTPBody(currentItem->formData()); - } - - // Reload the current page - loader->reloadAllowingStaleData(loader->documentLoader()->overrideEncoding()); -} - -static void WebHistoryInflate(JNIEnv* env, jobject obj, jint frame, jbyteArray data) -{ - LOG_ASSERT(frame, "Inflate needs a valid frame pointer!"); - LOG_ASSERT(data, "Inflate needs a valid data pointer!"); - - // Get the actual bytes and the length from the java array. - jbyte* bytes = env->GetByteArrayElements(data, NULL); - jsize size = env->GetArrayLength(data); - - // Inflate the history tree into one HistoryItem or null if the inflation - // failed. - WebCore::HistoryItem* newItem = new WebCore::HistoryItem(); -#ifdef ANDROID_HISTORY_CLIENT - RefPtr<WebHistoryItem> bridge = new WebHistoryItem(env, obj, newItem); - newItem->setBridge(bridge.get()); -#endif - // Inflate the item recursively. If it fails, that is ok. We'll have an - // incomplete HistoryItem but that is better than crashing due to a null - // item. - read_item_recursive(newItem, (const char**)&bytes, (int)size); -#ifdef ANDROID_HISTORY_CLIENT - bridge->setActive(); -#endif - - // Add the new item to the back/forward list. - WebCore::Frame* pFrame = (WebCore::Frame*)frame; - pFrame->page()->backForwardList()->addItem(newItem); - -#ifdef ANDROID_HISTORY_CLIENT - // Update the item. - bridge->updateHistoryItem(newItem); -#endif -} - -// 7 empty strings + no document state + children count = 9 unsigned values -// 1 char for isTargetItem -// ANDROID_HISTORY_CLIENT adds 2 ints for scale and traversals. -#ifdef ANDROID_HISTORY_CLIENT -#ifdef ANDROID_FIX -#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 14 + sizeof(char))) -#else -#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 11 + sizeof(char))) -#endif -#else -#ifdef ANDROID_FIX -#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 12 + sizeof(char))) -#else -#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 9 + sizeof(char))) -#endif -#endif - -jbyteArray WebHistory::Flatten(JNIEnv* env, WTF::Vector<char>& v, WebCore::HistoryItem* item) -{ - if (!item) - return NULL; - - // Reserve a vector of chars with an initial size of HISTORY_MIN_SIZE. - v.reserveCapacity(HISTORY_MIN_SIZE); - - // Write the top-level history item and then write all the children - // recursively. -#ifdef ANDROID_HISTORY_CLIENT - LOG_ASSERT(item->bridge(), "Why don't we have a bridge object here?"); -#endif - write_item(v, item); - write_children_recursive(v, item); - - // Try to create a new java byte array. - jbyteArray b = env->NewByteArray(v.size()); - if (!b) - return NULL; - - // Write our flattened data to the java array. - jbyte* bytes = env->GetByteArrayElements(b, NULL); - memcpy(bytes, v.data(), v.size()); - env->ReleaseByteArrayElements(b, bytes, 0); - return b; -} - -WebHistoryItem::WebHistoryItem(JNIEnv* env, jobject obj, - WebCore::HistoryItem* item) { - JavaVM* vm; - mJVM = env->GetJavaVM(&vm) >= 0 ? vm : NULL; - mObject = env->NewGlobalRef(obj); - mScale = 100; - mTraversals = -1; - mActive = false; - mParent = NULL; - mHistoryItem = item; -} - -WebHistoryItem::~WebHistoryItem() { - if (mObject) { - JNIEnv* env; - env = mJVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL; - if (!env) - return; - env->DeleteGlobalRef(mObject); - } -} - -void WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) { -#ifdef ANDROID_HISTORY_CLIENT - // Do not want to update during inflation. - if (!mActive) - return; - WebHistoryItem* webItem = this; - // Now we need to update the top-most WebHistoryItem based on the top-most - // HistoryItem. - if (mParent) { - webItem = mParent.get(); - if (webItem->hasOneRef()) { - // if the parent only has one ref, it is from this WebHistoryItem. - // This means that the matching WebCore::HistoryItem has been freed. - // This can happen during clear(). - LOGW("Can't updateHistoryItem as the top HistoryItem is gone"); - return; - } - while (webItem->parent()) - webItem = webItem->parent(); - item = webItem->historyItem(); - } - JNIEnv* env; - env = webItem->mJVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL; - if (!env) - return; - const WebCore::String& urlString = item->urlString(); - jstring urlStr = NULL; - if (!urlString.isNull()) - urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); - const WebCore::String& titleString = item->title(); - jstring titleStr = NULL; - if (!titleString.isNull()) - titleStr = env->NewString((unsigned short*)titleString.characters(), titleString.length()); - - // Try to get the favicon from the history item. For some pages like Grand - // Prix, there are history items with anchors. If the icon fails for the - // item, try to get the icon using the url without the ref. - jobject favicon = NULL; - WebCore::String url = item->urlString(); - if (item->url().hasRef()) { - int refIndex = url.reverseFind('#'); - url = url.substring(0, refIndex); - } - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(url, - WebCore::IntSize(16, 16)); - - if (icon) - favicon = webcoreImageToJavaBitmap(env, icon); - - WTF::Vector<char> data; - jbyteArray array = WebHistory::Flatten(env, data, item); - env->CallVoidMethod(webItem->mObject, gWebHistoryItem.mUpdate, urlStr, titleStr, favicon, array); - env->DeleteLocalRef(urlStr); - env->DeleteLocalRef(titleStr); - if (favicon) - env->DeleteLocalRef(favicon); - env->DeleteLocalRef(array); -#endif -} - -static void historyItemChanged(WebCore::HistoryItem* item) { -#ifdef ANDROID_HISTORY_CLIENT - LOG_ASSERT(item, - "historyItemChanged called with a null item"); - if (item->bridge()) - item->bridge()->updateHistoryItem(item); -#endif -} - -void WebHistory::AddItem(JNIEnv* env, jobject list, WebCore::HistoryItem* item) -{ -#ifdef ANDROID_HISTORY_CLIENT - LOG_ASSERT(item, "newItem must take a valid HistoryItem!"); - // Item already added. Should only happen when we are inflating the list. - if (item->bridge()) - return; - - // Allocate a blank WebHistoryItem - jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); - jobject newItem = env->NewObject(clazz, gWebHistoryItem.mInit); - - // Create the bridge, make it active, and attach it to the item. - WebHistoryItem* bridge = new WebHistoryItem(env, newItem, item); - bridge->setActive(); - item->setBridge(bridge); - - // Update the history item which will flatten the data and call update on - // the java item. - bridge->updateHistoryItem(item); - - // Add it to the list. - env->CallVoidMethod(list, gWebBackForwardList.mAddHistoryItem, newItem); - - // Delete our local reference. - env->DeleteLocalRef(newItem); -#endif -} - -void WebHistory::RemoveItem(JNIEnv* env, jobject list, int index) -{ - env->CallVoidMethod(list, gWebBackForwardList.mRemoveHistoryItem, index); -} - -void WebHistory::UpdateHistoryIndex(JNIEnv* env, jobject list, int newIndex) -{ - env->SetIntField(list, gWebBackForwardList.mCurrentIndex, newIndex); -} - -static void write_string(WTF::Vector<char>& v, const WebCore::String& str) -{ - unsigned strLen = str.length(); - // Only do work if the string has data. - if (strLen) { - // Determine how much to grow the vector. Use the worst case for utf8 to - // avoid reading the string twice. Add sizeof(unsigned) to hold the - // string length in utf8. - unsigned vectorLen = v.size() + sizeof(unsigned); - unsigned length = (strLen << 2) + vectorLen; - // Grow the vector. This will change the value of v.size() but we - // remember the original size above. - v.grow(length); - // Grab the position to write to. - char* data = v.begin() + vectorLen; - // Write the actual string - int l = SkUTF16_ToUTF8(str.characters(), strLen, data); - LOGV("Writing string %d %.*s", l, l, data); - // Go back and write the utf8 length. Subtract sizeof(unsigned) from - // data to get the position to write the length. - memcpy(data - sizeof(unsigned), (char*)&l, sizeof(unsigned)); - // Shrink the internal state of the vector so we match what was - // actually written. - v.shrink(vectorLen + l); - } else - v.append((char*)&strLen, sizeof(unsigned)); -} - -static void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item) -{ - // Original url - write_string(v, item->originalURLString()); - - // Url - write_string(v, item->urlString()); - - // Title - write_string(v, item->title()); - - // Form content type - write_string(v, item->formContentType()); - - // Form referrer - write_string(v, item->formReferrer()); - - // Form data - const WebCore::FormData* formData = item->formData(); - if (formData) - write_string(v, formData->flattenToString()); - else - write_string(v, WebCore::String()); // Empty constructor does not allocate a buffer. - -#ifdef ANDROID_FIX - // original form content type - write_string(v, item->originalFormContentType()); - - // original form referrer - write_string(v, item->originalFormReferrer()); - - // original form data - const WebCore::FormData* origformData = item->originalFormData(); - if (origformData) - write_string(v, origformData->flattenToString()); - else - write_string(v, WebCore::String()); // Empty constructor does not allocate a buffer. -#endif - - // Target - write_string(v, item->target()); - -#ifdef ANDROID_HISTORY_CLIENT - WebHistoryItem* bridge = item->bridge(); - LOG_ASSERT(bridge, "We should have a bridge here!"); - // Screen scale - int scale = bridge->scale(); - LOGV("Writing scale %d", scale); - v.append((char*)&scale, sizeof(int)); - - // Focus position - int traversals = bridge->traversals(); - LOGV("Writing traversals %d", traversals); - v.append((char*)&traversals, sizeof(int)); -#endif - - // Document state - const WTF::Vector<WebCore::String>& docState = item->documentState(); - WTF::Vector<WebCore::String>::const_iterator end = docState.end(); - unsigned stateSize = docState.size(); - LOGV("Writing docState %d", stateSize); - v.append((char*)&stateSize, sizeof(unsigned)); - for (WTF::Vector<WebCore::String>::const_iterator i = docState.begin(); i != end; ++i) { - write_string(v, *i); - } - - // Is target item - LOGV("Writing isTargetItem %d", item->isTargetItem()); - v.append((char)item->isTargetItem()); - - // Children count - unsigned childCount = item->children().size(); - LOGV("Writing childCount %d", childCount); - v.append((char*)&childCount, sizeof(unsigned)); -} - -static void write_children_recursive(WTF::Vector<char>& v, WebCore::HistoryItem* parent) -{ - const WebCore::HistoryItemVector& children = parent->children(); - WebCore::HistoryItemVector::const_iterator end = children.end(); - for (WebCore::HistoryItemVector::const_iterator i = children.begin(); i != end; ++i) { - WebCore::HistoryItem* item = (*i).get(); -#ifdef ANDROID_HISTORY_CLIENT - LOG_ASSERT(parent->bridge(), - "The parent item should have a bridge object!"); - if (!item->bridge()) { - WebHistoryItem* bridge = new WebHistoryItem(parent->bridge()); - item->setBridge(bridge); - bridge->setActive(); - } else { - // The only time this item's parent may not be the same as the - // parent's bridge is during history close. In that case, the - // parent must not have a parent bridge. - LOG_ASSERT(parent->bridge()->parent() == NULL || - item->bridge()->parent() == parent->bridge(), - "Somehow this item has an incorrect parent"); - item->bridge()->setParent(parent->bridge()); - } -#endif - write_item(v, item); - write_children_recursive(v, item); - } -} - -static bool read_item_recursive(WebCore::HistoryItem* newItem, - const char** pData, int length) -{ - if (!pData || length < HISTORY_MIN_SIZE) - return false; - - const WebCore::TextEncoding& e = WebCore::UTF8Encoding(); - const char* data = *pData; - const char* end = data + length; - int sizeofUnsigned = (int)sizeof(unsigned); - - // Read the original url - // Read the expected length of the string. - int l; - memcpy(&l, data, sizeofUnsigned); - // Increment data pointer by the size of an unsigned int. - data += sizeofUnsigned; - if (l) { - LOGV("Original url %d %.*s", l, l, data); - // If we have a length, check if that length exceeds the data length - // and return null if there is not enough data. - if (data + l < end) - newItem->setOriginalURLString(e.decode(data, l)); - else - return false; - // Increment the data pointer by the length of the string. - data += l; - } - // Check if we have enough data left to continue. - if (end - data < sizeofUnsigned) - return false; - - // Read the url - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Url %d %.*s", l, l, data); - if (data + l < end) - newItem->setURLString(e.decode(data, l)); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the title - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Title %d %.*s", l, l, data); - if (data + l < end) - newItem->setTitle(e.decode(data, l)); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Generate a new ResourceRequest object for populating form information. - WebCore::String formContentType; - WebCore::String formReferrer; - WebCore::FormData* formData = NULL; - - // Read the form content type - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Content type %d %.*s", l, l, data); - if (data + l < end) - formContentType = e.decode(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the form referrer - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Referrer %d %.*s", l, l, data); - if (data + l < end) - formReferrer = e.decode(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the form data - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Form data %d %.*s", l, l, data); - if (data + l < end) - formData = new WebCore::FormData(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Set up the form info - if (formData != NULL) { - WebCore::ResourceRequest r; - r.setHTTPMethod("POST"); - r.setHTTPContentType(formContentType); - r.setHTTPReferrer(formReferrer); - r.setHTTPBody(formData); - newItem->setFormInfoFromRequest(r); - } - -#ifdef ANDROID_FIX - WebCore::String origformContentType; - WebCore::String origformReferrer; - WebCore::FormData* origformData = NULL; - - // Read the original form content type - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Original content type %d %.*s", l, l, data); - if (data + l < end) - origformContentType = e.decode(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the original form referrer - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Original referrer %d %.*s", l, l, data); - if (data + l < end) - origformReferrer = e.decode(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the original form data - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Original form data %d %.*s", l, l, data); - if (data + l < end) - origformData = new WebCore::FormData(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - if (origformData) - newItem->setOriginalFormInfo(origformData, origformContentType, origformReferrer); -#endif - - // Read the target - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Target %d %.*s", l, l, data); - if (data + l < end) - newItem->setTarget(e.decode(data, l)); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - -#ifdef ANDROID_HISTORY_CLIENT - WebHistoryItem* bridge = newItem->bridge(); - LOG_ASSERT(bridge, "There should be a bridge object during inflate"); - // Read the screen scale - memcpy(&l, data, sizeofUnsigned); - LOGV("Screen scale %d", l); - bridge->setScale(l); - data += sizeofUnsigned; - if (end - data < (int)sizeof(int)) - return false; - - // Read the focus index - memcpy(&l, data, sizeof(int)); - LOGV("Traversals %d", l); - bridge->setTraversals(l); - data += sizeof(int); - if (end - data < sizeofUnsigned) - return false; -#endif - - // Read the document state - memcpy(&l, data, sizeofUnsigned); - LOGV("Document state %d", l); - data += sizeofUnsigned; - if (l) { - // Check if we have enough data to at least parse the sizes of each - // document state string. - if (data + l * sizeofUnsigned >= end) - return false; - // Create a new vector and reserve enough space for the document state. - WTF::Vector<WebCore::String> docState; - docState.reserveCapacity(l); - while (l--) { - // Check each time if we have enough to parse the length of the next - // string. - if (end - data < sizeofUnsigned) - return false; - int strLen; - memcpy(&strLen, data, sizeofUnsigned); - data += sizeofUnsigned; - if (data + strLen < end) - docState.append(e.decode(data, strLen)); - else - return false; - LOGV("\t\t%d %.*s", strLen, strLen, data); - data += strLen; - } - newItem->setDocumentState(docState); - } - // Check if we have enough to read the next byte - if (data >= end) - return false; - - // Read is target item - // Cast the value to unsigned char in order to make a negative value larger - // than 1. A value that is not 0 or 1 is a failure. - unsigned char c = (unsigned char)data[0]; - if (c > 1) - return false; - LOGV("Target item %d", c); - newItem->setIsTargetItem((bool)c); - data++; - if (end - data < sizeofUnsigned) - return false; - - // Read the child count - memcpy(&l, data, sizeofUnsigned); - LOGV("Child count %d", l); - data += sizeofUnsigned; - *pData = data; - if (l) { - // Check if we have the minimum amount need to parse l children. - if (data + l * HISTORY_MIN_SIZE >= end) - return false; - while (l--) { - // No need to check the length each time because read_item_recursive - // will return null if there isn't enough data left to parse. - WebCore::HistoryItem* child = new WebCore::HistoryItem(); -#ifdef ANDROID_HISTORY_CLIENT - // Set a bridge that will not call into java. - child->setBridge(new WebHistoryItem(bridge)); -#endif - // Read the child item. - if (!read_item_recursive(child, pData, end - data)) { - delete child; - return false; - } -#ifdef ANDROID_HISTORY_CLIENT - child->bridge()->setActive(); -#endif - newItem->addChildItem(child); - } - } - return true; -} - -#ifndef NDEBUG -static void unit_test() -{ - LOGD("Entering history unit test!"); - const char* test1 = new char[0]; - WebCore::HistoryItem* testItem = new WebCore::HistoryItem(); -#ifdef ANDROID_HISTORY_CLIENT - testItem->setBridge(new WebHistoryItem(NULL)); -#endif - LOG_ASSERT(!read_item_recursive(testItem, &test1, 0), "0 length array should fail!"); - delete[] test1; - const char* test2 = new char[2]; - LOG_ASSERT(!read_item_recursive(testItem, &test2, 2), "Small array should fail!"); - delete[] test2; - LOG_ASSERT(!read_item_recursive(testItem, NULL, HISTORY_MIN_SIZE), "Null data should fail!"); - // Original Url - char* test3 = new char[HISTORY_MIN_SIZE]; - const char* ptr = (const char*)test3; - memset(test3, 0, HISTORY_MIN_SIZE); - *(int*)test3 = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length originalUrl should fail!"); - // Url - int offset = 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length url should fail!"); - // Title - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length title should fail!"); - // Form content type - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length contentType should fail!"); - // Form referrer - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length referrer should fail!"); - // Form data - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length form data should fail!"); -#ifdef ANDROID_FIX - // Original form content type - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length contentType should fail!"); - // Original form referrer - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length referrer should fail!"); - // Original form data - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length form data should fail!"); -#endif - // Target - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length target should fail!"); -#ifdef ANDROID_HISTORY_CLIENT - offset += 4; // Scale - offset += 4; // traversals -#endif - // Document state - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length document state should fail!"); - // Is target item - offset += 1; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(char*)(test3 + offset) = '!'; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "IsTargetItem should fail with ! as the value!"); - // Child count - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 kids should fail!"); - -#ifdef ANDROID_HISTORY_CLIENT - offset = 36; -#else - offset = 28; -#endif -#ifdef ANDROID_FIX - offset += 12; -#endif - // Test document state - delete[] test3; - test3 = new char[HISTORY_MIN_SIZE + sizeof(unsigned)]; - memset(test3, 0, HISTORY_MIN_SIZE + sizeof(unsigned)); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 1; - *(int*)(test3 + offset + 4) = 20; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE + sizeof(unsigned)), "1 20 length document state string should fail!"); - delete[] test3; - test3 = new char[HISTORY_MIN_SIZE + 2 * sizeof(unsigned)]; - memset(test3, 0, HISTORY_MIN_SIZE + 2 * sizeof(unsigned)); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 2; - *(int*)(test3 + offset + 4) = 0; - *(int*)(test3 + offset + 8) = 20; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE + 2 * sizeof(unsigned) ), "2 20 length document state string should fail!"); - delete[] test3; - delete testItem; -} -#endif - -//--------------------------------------------------------- -// JNI registration -//--------------------------------------------------------- -static JNINativeMethod gWebBackForwardListMethods[] = { - { "nativeClose", "(I)V", - (void*) WebHistoryClose }, - { "restoreIndex", "(II)V", - (void*) WebHistoryRestoreIndex } -}; - -static JNINativeMethod gWebHistoryItemMethods[] = { - { "inflate", "(I[B)V", - (void*) WebHistoryInflate } -}; - -int register_webhistory(JNIEnv* env) -{ -#ifdef ANDROID_HISTORY_CLIENT - // Get notified of all changes to history items. - WebCore::notifyHistoryItemChanged = historyItemChanged; -#endif -#ifndef NDEBUG - unit_test(); -#endif - // Find WebHistoryItem, its constructor, and the update method. - jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); - LOG_ASSERT(clazz, "Unable to find class android/webkit/WebHistoryItem"); - gWebHistoryItem.mInit = env->GetMethodID(clazz, "<init>", "()V"); - LOG_ASSERT(gWebHistoryItem.mInit, "Could not find WebHistoryItem constructor"); - gWebHistoryItem.mUpdate = env->GetMethodID(clazz, "update", - "(Ljava/lang/String;Ljava/lang/String;Landroid/graphics/Bitmap;[B)V"); - LOG_ASSERT(gWebHistoryItem.mUpdate, "Could not find method update in WebHistoryItem"); - - // Find the field ids for mTitle and mUrl. - gWebHistoryItem.mTitle = env->GetFieldID(clazz, "mTitle", "Ljava/lang/String;"); - LOG_ASSERT(gWebHistoryItem.mTitle, "Could not find field mTitle in WebHistoryItem"); - gWebHistoryItem.mUrl = env->GetFieldID(clazz, "mUrl", "Ljava/lang/String;"); - LOG_ASSERT(gWebHistoryItem.mUrl, "Could not find field mUrl in WebHistoryItem"); - - // Find the WebBackForwardList object, the addHistoryItem and - // removeHistoryItem methods and the mCurrentIndex field. - clazz = env->FindClass("android/webkit/WebBackForwardList"); - LOG_ASSERT(clazz, "Unable to find class android/webkit/WebBackForwardList"); - gWebBackForwardList.mAddHistoryItem = env->GetMethodID(clazz, "addHistoryItem", - "(Landroid/webkit/WebHistoryItem;)V"); - LOG_ASSERT(gWebBackForwardList.mAddHistoryItem, "Could not find method addHistoryItem"); - gWebBackForwardList.mRemoveHistoryItem = env->GetMethodID(clazz, "removeHistoryItem", - "(I)V"); - LOG_ASSERT(gWebBackForwardList.mRemoveHistoryItem, "Could not find method removeHistoryItem"); - gWebBackForwardList.mCurrentIndex = env->GetFieldID(clazz, "mCurrentIndex", "I"); - LOG_ASSERT(gWebBackForwardList.mCurrentIndex, "Could not find field mCurrentIndex"); - - int result = jniRegisterNativeMethods(env, "android/webkit/WebBackForwardList", - gWebBackForwardListMethods, NELEM(gWebBackForwardListMethods)); - return (result < 0) ? result : jniRegisterNativeMethods(env, "android/webkit/WebHistoryItem", - gWebHistoryItemMethods, NELEM(gWebHistoryItemMethods)); -} - -} /* namespace android */ diff --git a/WebCore/platform/android/jni/WebHistory.h b/WebCore/platform/android/jni/WebHistory.h deleted file mode 100644 index 62db099..0000000 --- a/WebCore/platform/android/jni/WebHistory.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_WEBKIT_WEBHISTORY_H -#define ANDROID_WEBKIT_WEBHISTORY_H - -#include <jni.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> - -namespace WebCore { - class HistoryItem; -} - -namespace android { - -class WebHistory { -public: - static jbyteArray Flatten(JNIEnv*, WTF::Vector<char>&, WebCore::HistoryItem*); - static void AddItem(JNIEnv*, jobject, WebCore::HistoryItem*); - static void RemoveItem(JNIEnv*, jobject, int); - static void UpdateHistoryIndex(JNIEnv*, jobject, int); -}; - -class WebHistoryItem : public WTF::RefCounted<WebHistoryItem> { -public: - WebHistoryItem(WebHistoryItem* parent) - : mParent(parent) - , mObject(NULL) - , mJVM(NULL) - , mScale(100) - , mTraversals(-1) - , mActive(false) - , mHistoryItem(NULL) {} - WebHistoryItem(JNIEnv*, jobject, WebCore::HistoryItem*); - ~WebHistoryItem(); - void updateHistoryItem(WebCore::HistoryItem* item); - void setScale(int s) { mScale = s; } - void setTraversals(int t) { mTraversals = t; } - void setActive() { mActive = true; } - void setParent(WebHistoryItem* parent) { mParent = parent; } - WebHistoryItem* parent() { return mParent.get(); } - int scale() { return mScale; } - int traversals() { return mTraversals; } - jobject object() { return mObject; } - WebCore::HistoryItem* historyItem() { return mHistoryItem; } -private: - RefPtr<WebHistoryItem> mParent; - jobject mObject; - JavaVM* mJVM; - int mScale; - int mTraversals; - bool mActive; - WebCore::HistoryItem* mHistoryItem; -}; - -}; - -#endif diff --git a/WebCore/platform/android/jni/WebIconDatabase.cpp b/WebCore/platform/android/jni/WebIconDatabase.cpp deleted file mode 100644 index 2d5c39c..0000000 --- a/WebCore/platform/android/jni/WebIconDatabase.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "favicons" - -#include <config.h> -#include <wtf/Platform.h> - -#include "WebCoreJni.h" -#include "WebIconDatabase.h" - -#include "IconDatabase.h" -#include "Image.h" -#include "IntRect.h" -#include "JavaSharedClient.h" -#include "KURL.h" - -#include <pthread.h> -#include "GraphicsJNI.h" -#include <SkBitmap.h> -#include <SkImageDecoder.h> -#include <SkTemplates.h> -#undef LOG -#include <utils/Log.h> -#include <utils/misc.h> -#include <JNIHelp.h> - -namespace android { - -jobject webcoreImageToJavaBitmap(JNIEnv* env, WebCore::Image* icon) -{ - if (!icon) - return NULL; - SkBitmap bm; - WebCore::SharedBuffer* buffer = icon->data(); - if (!buffer || !SkImageDecoder::DecodeMemory(buffer->data(), buffer->size(), - &bm, SkBitmap::kNo_Config, - SkImageDecoder::kDecodePixels_Mode)) - return NULL; - - return GraphicsJNI::createBitmap(env, new SkBitmap(bm), false, NULL); -} - -static WebIconDatabase* gIconDatabaseClient = new WebIconDatabase(); - -// XXX: Called by the IconDatabase thread -void WebIconDatabase::dispatchDidAddIconForPageURL(const WebCore::String& pageURL) -{ - // Attempt to attach to the current vm. - JavaVM* vm = WebCoreJni::getJavaVM(); - JavaVMAttachArgs args; - - args.version = JNI_VERSION_1_4; - args.name = "IconDatabase"; - args.group = NULL; - - JNIEnv* env; - bool threadIsAttached = true; - if (vm->AttachCurrentThread(&env, (void*) &args) != JNI_OK) { - LOGE("Could not attach IconDatabase thread to the VM"); - threadIsAttached = false; - } - - mNotificationsMutex.lock(); - mNotifications.append(pageURL); - if (!mDeliveryRequested) { - if (threadIsAttached) { - mDeliveryRequested = true; - WebCore::JavaSharedClient::EnqueueFunctionPtr(DeliverNotifications, this); - } - } - mNotificationsMutex.unlock(); -} - -// Called in the WebCore thread -void WebIconDatabase::RegisterForIconNotification(WebIconDatabaseClient* client) -{ - gIconDatabaseClient->mClientsMutex.lock(); - gIconDatabaseClient->mClients.append(client); - gIconDatabaseClient->mClientsMutex.unlock(); -} - -// Called in the WebCore thread -void WebIconDatabase::UnregisterForIconNotification(WebIconDatabaseClient* client) -{ - WebIconDatabase* db = gIconDatabaseClient; - db->mClientsMutex.lock(); - for (unsigned i = 0; i < db->mClients.size(); ++i) { - if (db->mClients[i] == client) { - db->mClients.remove(i); - break; - } - } - db->mClientsMutex.unlock(); -} - -// Called in the WebCore thread -void WebIconDatabase::DeliverNotifications(void* v) -{ - ASSERT(v); - ((WebIconDatabase*)v)->deliverNotifications(); -} - -// Called in the WebCore thread -void WebIconDatabase::deliverNotifications() -{ - ASSERT(mDeliveryRequested); - - // Swap the notifications queue - Vector<WebCore::String> queue; - mNotificationsMutex.lock(); - queue.swap(mNotifications); - mDeliveryRequested = false; - mNotificationsMutex.unlock(); - - // Swap the clients queue - Vector<WebIconDatabaseClient*> clients; - mClientsMutex.lock(); - clients.swap(mClients); - mClientsMutex.unlock(); - - for (unsigned i = 0; i < queue.size(); ++i) { - for (unsigned j = 0; j < clients.size(); ++j) { - clients[j]->didAddIconForPageUrl(queue[i]); - } - } -} - -static void Open(JNIEnv* env, jobject obj, jstring path) -{ - WebCore::IconDatabase* iconDb = WebCore::iconDatabase(); - if (iconDb->isOpen()) - return; - iconDb->setEnabled(true); - iconDb->setClient(gIconDatabaseClient); - LOG_ASSERT(path, "No path given to nativeOpen"); - const char* pathStr = env->GetStringUTFChars(path, NULL); - LOG_ASSERT(pathStr, "GetStringUTFChars failed for the path"); - LOGV("Opening WebIconDatabase file '%s'", pathStr); - bool res = iconDb->open(pathStr); - if (!res) - LOGE("Open failed!"); - env->ReleaseStringUTFChars(path, pathStr); -} - -static void Close(JNIEnv* env, jobject obj) -{ - WebCore::iconDatabase()->close(); -} - -static void RemoveAllIcons(JNIEnv* env, jobject obj) -{ - LOGV("Removing all icons"); - WebCore::iconDatabase()->removeAllIcons(); -} - -static jobject IconForPageUrl(JNIEnv* env, jobject obj, jstring url) -{ - LOG_ASSERT(url, "No url given to iconForPageUrl"); - const char* urlStr = env->GetStringUTFChars(url, NULL); - LOG_ASSERT(urlStr, "GetStringUTFChars failed for url"); - - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(urlStr, - WebCore::IntSize(16, 16)); - LOGV("Retrieving icon for '%s' %p", urlStr, icon); - env->ReleaseStringUTFChars(url, urlStr); - return webcoreImageToJavaBitmap(env, icon); -} - -static void RetainIconForPageUrl(JNIEnv* env, jobject obj, jstring url) -{ - LOG_ASSERT(url, "No url given to retainIconForPageUrl"); - const char* urlStr = env->GetStringUTFChars(url, NULL); - LOG_ASSERT(urlStr, "GetStringUTFChars failed for url"); - - LOGV("Retaining icon for '%s'", urlStr); - WebCore::iconDatabase()->retainIconForPageURL(urlStr); - env->ReleaseStringUTFChars(url, urlStr); -} - -static void ReleaseIconForPageUrl(JNIEnv* env, jobject obj, jstring url) -{ - LOG_ASSERT(url, "No url given to releaseIconForPageUrl"); - const char* urlStr = env->GetStringUTFChars(url, NULL); - LOG_ASSERT(urlStr, "GetStringUTFChars failed for url"); - - LOGV("Releasing icon for '%s'", urlStr); - WebCore::iconDatabase()->releaseIconForPageURL(urlStr); - env->ReleaseStringUTFChars(url, urlStr); -} - -/* - * JNI registration - */ -static JNINativeMethod gWebIconDatabaseMethods[] = { - { "nativeOpen", "(Ljava/lang/String;)V", - (void*) Open }, - { "nativeClose", "()V", - (void*) Close }, - { "nativeRemoveAllIcons", "()V", - (void*) RemoveAllIcons }, - { "nativeIconForPageUrl", "(Ljava/lang/String;)Landroid/graphics/Bitmap;", - (void*) IconForPageUrl }, - { "nativeRetainIconForPageUrl", "(Ljava/lang/String;)V", - (void*) RetainIconForPageUrl }, - { "nativeReleaseIconForPageUrl", "(Ljava/lang/String;)V", - (void*) ReleaseIconForPageUrl } -}; - -int register_webicondatabase(JNIEnv* env) -{ - jclass webIconDB = env->FindClass("android/webkit/WebIconDatabase"); - LOG_ASSERT(webIconDB, "Unable to find class android.webkit.WebIconDatabase"); - - return jniRegisterNativeMethods(env, "android/webkit/WebIconDatabase", - gWebIconDatabaseMethods, NELEM(gWebIconDatabaseMethods)); -} - -} diff --git a/WebCore/platform/android/jni/WebIconDatabase.h b/WebCore/platform/android/jni/WebIconDatabase.h deleted file mode 100644 index eefe1f6..0000000 --- a/WebCore/platform/android/jni/WebIconDatabase.h +++ /dev/null @@ -1,69 +0,0 @@ -/* //device/libs/WebKitLib/WebKit/WebCore/platform/android/jni/android_webkit_webicondatabase.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef ANDROID_WEBKIT_WEBICONDATABASE_H -#define ANDROID_WEBKIT_WEBICONDATABASE_H - -#include "IconDatabaseClient.h" -#include "utils/threads.h" -#include "wtf/Vector.h" - -#include <jni.h> - -namespace WebCore { - class Image; - class String; -} - -namespace android { - - class WebIconDatabaseClient { - public: - virtual ~WebIconDatabaseClient() {} - virtual void didAddIconForPageUrl(const WebCore::String& pageUrl) = 0; - }; - - class WebIconDatabase : public WebCore::IconDatabaseClient { - public: - WebIconDatabase() : mDeliveryRequested(false) {} - // IconDatabaseClient method - virtual void dispatchDidAddIconForPageURL(const WebCore::String& pageURL); - - static void RegisterForIconNotification(WebIconDatabaseClient* client); - static void UnregisterForIconNotification(WebIconDatabaseClient* client); - static void DeliverNotifications(void*); - - private: - // Deliver all the icon notifications - void deliverNotifications(); - - // List of clients and a mutex to protect it. - Vector<WebIconDatabaseClient*> mClients; - android::Mutex mClientsMutex; - - // Queue of page urls that have received an icon. - Vector<WebCore::String> mNotifications; - android::Mutex mNotificationsMutex; - // Flag to indicate that we have requested a delivery of notifications. - bool mDeliveryRequested; - }; - - jobject webcoreImageToJavaBitmap(JNIEnv* env, WebCore::Image* icon); - -}; - -#endif diff --git a/WebCore/platform/android/jni/WebSettings.cpp b/WebCore/platform/android/jni/WebSettings.cpp deleted file mode 100644 index 8d9efc0..0000000 --- a/WebCore/platform/android/jni/WebSettings.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "websettings" - -#include <config.h> -#include <wtf/Platform.h> - -#include "Document.h" -#include "Frame.h" -#include "FrameAndroid.h" -#include "FrameLoader.h" -#include "FrameView.h" -#include "DocLoader.h" -#include "Page.h" -#ifdef ANDROID_PLUGINS -#include "PluginDatabaseAndroid.h" -#endif -#include "Settings.h" -#include "WebCoreFrameBridge.h" - -#undef LOG -#include <JNIHelp.h> -#include <utils/Log.h> -#include <utils/misc.h> - -namespace android { - -struct FieldIds { - FieldIds(JNIEnv* env, jclass clazz) { - mLayoutAlgorithm = env->GetFieldID(clazz, "mLayoutAlgorithm", - "Landroid/webkit/WebSettings$LayoutAlgorithm;"); - mTextSize = env->GetFieldID(clazz, "mTextSize", - "Landroid/webkit/WebSettings$TextSize;"); - mStandardFontFamily = env->GetFieldID(clazz, "mStandardFontFamily", - "Ljava/lang/String;"); - mFixedFontFamily = env->GetFieldID(clazz, "mFixedFontFamily", - "Ljava/lang/String;"); - mSansSerifFontFamily = env->GetFieldID(clazz, "mSansSerifFontFamily", - "Ljava/lang/String;"); - mSerifFontFamily = env->GetFieldID(clazz, "mSerifFontFamily", - "Ljava/lang/String;"); - mCursiveFontFamily = env->GetFieldID(clazz, "mCursiveFontFamily", - "Ljava/lang/String;"); - mFantasyFontFamily = env->GetFieldID(clazz, "mFantasyFontFamily", - "Ljava/lang/String;"); - mDefaultTextEncoding = env->GetFieldID(clazz, "mDefaultTextEncoding", - "Ljava/lang/String;"); - mUserAgent = env->GetFieldID(clazz, "mUserAgent", - "Ljava/lang/String;"); - mMinimumFontSize = env->GetFieldID(clazz, "mMinimumFontSize", "I"); - mMinimumLogicalFontSize = env->GetFieldID(clazz, "mMinimumLogicalFontSize", "I"); - mDefaultFontSize = env->GetFieldID(clazz, "mDefaultFontSize", "I"); - mDefaultFixedFontSize = env->GetFieldID(clazz, "mDefaultFixedFontSize", "I"); - mLoadsImagesAutomatically = env->GetFieldID(clazz, "mLoadsImagesAutomatically", "Z"); -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - mBlockNetworkImage = env->GetFieldID(clazz, "mBlockNetworkImage", "Z"); -#endif - mJavaScriptEnabled = env->GetFieldID(clazz, "mJavaScriptEnabled", "Z"); - mPluginsEnabled = env->GetFieldID(clazz, "mPluginsEnabled", "Z"); -#ifdef ANDROID_PLUGINS - mPluginsPath = env->GetFieldID(clazz, "mPluginsPath", "Ljava/lang/String;"); -#endif - mJavaScriptCanOpenWindowsAutomatically = env->GetFieldID(clazz, - "mJavaScriptCanOpenWindowsAutomatically", "Z"); - mUseWideViewport = env->GetFieldID(clazz, "mUseWideViewport", "Z"); - mSupportMultipleWindows = env->GetFieldID(clazz, "mSupportMultipleWindows", "Z"); - mUseDoubleTree = env->GetFieldID(clazz, "mUseDoubleTree", "Z"); - - LOG_ASSERT(mLayoutAlgorithm, "Could not find field mLayoutAlgorithm"); - LOG_ASSERT(mTextSize, "Could not find field mTextSize"); - LOG_ASSERT(mStandardFontFamily, "Could not find field mStandardFontFamily"); - LOG_ASSERT(mFixedFontFamily, "Could not find field mFixedFontFamily"); - LOG_ASSERT(mSansSerifFontFamily, "Could not find field mSansSerifFontFamily"); - LOG_ASSERT(mSerifFontFamily, "Could not find field mSerifFontFamily"); - LOG_ASSERT(mCursiveFontFamily, "Could not find field mCursiveFontFamily"); - LOG_ASSERT(mFantasyFontFamily, "Could not find field mFantasyFontFamily"); - LOG_ASSERT(mDefaultTextEncoding, "Could not find field mDefaultTextEncoding"); - LOG_ASSERT(mUserAgent, "Could not find field mUserAgent"); - LOG_ASSERT(mMinimumFontSize, "Could not find field mMinimumFontSize"); - LOG_ASSERT(mMinimumLogicalFontSize, "Could not find field mMinimumLogicalFontSize"); - LOG_ASSERT(mDefaultFontSize, "Could not find field mDefaultFontSize"); - LOG_ASSERT(mDefaultFixedFontSize, "Could not find field mDefaultFixedFontSize"); - LOG_ASSERT(mLoadsImagesAutomatically, "Could not find field mLoadsImagesAutomatically"); -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - LOG_ASSERT(mBlockNetworkImage, "Could not find field mBlockNetworkImage"); -#endif - LOG_ASSERT(mJavaScriptEnabled, "Could not find field mJavaScriptEnabled"); - LOG_ASSERT(mPluginsEnabled, "Could not find field mPluginsEnabled"); -#ifdef ANDROID_PLUGINS - LOG_ASSERT(mPluginsPath, "Could not find field mPluginsPath"); -#endif - LOG_ASSERT(mJavaScriptCanOpenWindowsAutomatically, - "Could not find field mJavaScriptCanOpenWindowsAutomatically"); - LOG_ASSERT(mUseWideViewport, "Could not find field mUseWideViewport"); - LOG_ASSERT(mSupportMultipleWindows, "Could not find field mSupportMultipleWindows"); - LOG_ASSERT(mUseDoubleTree, "Could not find field mUseDoubleTree"); - - jclass c = env->FindClass("java/lang/Enum"); - LOG_ASSERT(c, "Could not find Enum class!"); - mOrdinal = env->GetMethodID(c, "ordinal", "()I"); - LOG_ASSERT(mOrdinal, "Could not find method ordinal"); - c = env->FindClass("android/webkit/WebSettings$TextSize"); - LOG_ASSERT(c, "Could not find TextSize enum"); - mTextSizeValue = env->GetFieldID(c, "value", "I"); - } - - // Field ids - jfieldID mLayoutAlgorithm; - jfieldID mTextSize; - jfieldID mStandardFontFamily; - jfieldID mFixedFontFamily; - jfieldID mSansSerifFontFamily; - jfieldID mSerifFontFamily; - jfieldID mCursiveFontFamily; - jfieldID mFantasyFontFamily; - jfieldID mDefaultTextEncoding; - jfieldID mUserAgent; - jfieldID mMinimumFontSize; - jfieldID mMinimumLogicalFontSize; - jfieldID mDefaultFontSize; - jfieldID mDefaultFixedFontSize; - jfieldID mLoadsImagesAutomatically; -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - jfieldID mBlockNetworkImage; -#endif - jfieldID mJavaScriptEnabled; - jfieldID mPluginsEnabled; -#ifdef ANDROID_PLUGINS - jfieldID mPluginsPath; -#endif - jfieldID mJavaScriptCanOpenWindowsAutomatically; - jfieldID mUseWideViewport; - jfieldID mSupportMultipleWindows; - jfieldID mUseDoubleTree; - - // Ordinal() method and value field for enums - jmethodID mOrdinal; - jfieldID mTextSizeValue; -}; - -static struct FieldIds* gFieldIds; - -class WebSettings { -public: - static void Sync(JNIEnv* env, jobject obj, jint frame) - { - WebCore::FrameAndroid* pFrame = (WebCore::FrameAndroid*)frame; - LOG_ASSERT(pFrame, "%s must take a valid frame pointer!", __FUNCTION__); - WebCore::Settings* s = pFrame->page()->settings(); - WebCore::DocLoader* docLoader = pFrame->document()->docLoader(); - -#ifdef ANDROID_LAYOUT - jobject layout = env->GetObjectField(obj, gFieldIds->mLayoutAlgorithm); - WebCore::Settings::LayoutAlgorithm l = (WebCore::Settings::LayoutAlgorithm) - env->CallIntMethod(layout, gFieldIds->mOrdinal); - if (s->layoutAlgorithm() != l) { - s->setLayoutAlgorithm(l); - if (pFrame->document()) { - pFrame->document()->updateStyleSelector(); - if (pFrame->document()->renderer()) { - pFrame->cleanupForFullLayout(pFrame->document()->renderer()); - LOG_ASSERT(pFrame->view(), "No view for this frame when trying to relayout"); - pFrame->view()->layout(); - // FIXME: This call used to scroll the page to put the focus into view. - // It worked on the WebViewCore, but now scrolling is done outside of the - // WebViewCore, on the UI side, so there needs to be a new way to do this. - //pFrame->makeFocusVisible(); - } - } - } -#endif - jobject textSize = env->GetObjectField(obj, gFieldIds->mTextSize); - jint zoomFactor = env->GetIntField(textSize, gFieldIds->mTextSizeValue); - if (pFrame->zoomFactor() != zoomFactor) - pFrame->setZoomFactor(zoomFactor); - - jstring str = (jstring)env->GetObjectField(obj, gFieldIds->mStandardFontFamily); - const char* font = env->GetStringUTFChars(str, NULL); - s->setStandardFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mFixedFontFamily); - font = env->GetStringUTFChars(str, NULL); - s->setFixedFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mSansSerifFontFamily); - font = env->GetStringUTFChars(str, NULL); - s->setSansSerifFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mSerifFontFamily); - font = env->GetStringUTFChars(str, NULL); - s->setSerifFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mCursiveFontFamily); - font = env->GetStringUTFChars(str, NULL); - s->setCursiveFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mFantasyFontFamily); - font = env->GetStringUTFChars(str, NULL); - s->setFantasyFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mDefaultTextEncoding); - const char* encoding = env->GetStringUTFChars(str, NULL); - s->setDefaultTextEncodingName(encoding); - env->ReleaseStringUTFChars(str, encoding); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mUserAgent); - const char* userAgentStr = env->GetStringUTFChars(str, NULL); - pFrame->bridge()->setUserAgent(userAgentStr); - env->ReleaseStringUTFChars(str, userAgentStr); - - jint size = env->GetIntField(obj, gFieldIds->mMinimumFontSize); - s->setMinimumFontSize(size); - - size = env->GetIntField(obj, gFieldIds->mMinimumLogicalFontSize); - s->setMinimumLogicalFontSize(size); - - size = env->GetIntField(obj, gFieldIds->mDefaultFontSize); - s->setDefaultFontSize(size); - - size = env->GetIntField(obj, gFieldIds->mDefaultFixedFontSize); - s->setDefaultFixedFontSize(size); - - jboolean flag = env->GetBooleanField(obj, gFieldIds->mLoadsImagesAutomatically); - s->setLoadsImagesAutomatically(flag); - if (flag) - docLoader->setAutoLoadImages(true); - -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - flag = env->GetBooleanField(obj, gFieldIds->mBlockNetworkImage); - s->setBlockNetworkImage(flag); - if(!flag) - docLoader->setBlockNetworkImage(false); -#endif - - flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptEnabled); - s->setJavaScriptEnabled(flag); - - flag = env->GetBooleanField(obj, gFieldIds->mPluginsEnabled); - s->setPluginsEnabled(flag); - -#ifdef ANDROID_PLUGINS - str = (jstring)env->GetObjectField(obj, gFieldIds->mPluginsPath); - if (str) { - const char* pluginsPathStr = env->GetStringUTFChars(str, NULL); - s->setPluginsPath(pluginsPathStr); - // Also sync PluginDatabaseAndroid with the new default path. - ::WebCore::PluginDatabaseAndroid::setDefaultPluginsPath(pluginsPathStr); - env->ReleaseStringUTFChars(str, pluginsPathStr); - } -#endif - - flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptCanOpenWindowsAutomatically); - s->setJavaScriptCanOpenWindowsAutomatically(flag); - - flag = env->GetBooleanField(obj, gFieldIds->mUseWideViewport); - s->setUseWideViewport(flag); - -#ifdef ANDROID_MULTIPLE_WINDOWS - flag = env->GetBooleanField(obj, gFieldIds->mSupportMultipleWindows); - s->setSupportMultipleWindows(flag); -#endif - -#if USE(LOW_BANDWIDTH_DISPLAY) - flag = env->GetBooleanField(obj, gFieldIds->mUseDoubleTree); - pFrame->loader()->setUseLowBandwidthDisplay(flag); -#endif - } -}; - -//------------------------------------------------------------- -// JNI registration -//------------------------------------------------------------- - -static JNINativeMethod gWebSettingsMethods[] = { - { "nativeSync", "(I)V", - (void*) WebSettings::Sync } -}; - -int register_websettings(JNIEnv* env) -{ - jclass clazz = env->FindClass("android/webkit/WebSettings"); - LOG_ASSERT(clazz, "Unable to find class WebSettings!"); - gFieldIds = new FieldIds(env, clazz); - return jniRegisterNativeMethods(env, "android/webkit/WebSettings", - gWebSettingsMethods, NELEM(gWebSettingsMethods)); -} - -} diff --git a/WebCore/platform/android/jni/WebViewCore.cpp b/WebCore/platform/android/jni/WebViewCore.cpp deleted file mode 100644 index dc2cd48..0000000 --- a/WebCore/platform/android/jni/WebViewCore.cpp +++ /dev/null @@ -1,2211 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "webcoreglue" - -#include <config.h> -#include <wtf/Platform.h> - -#include "android_graphics.h" -#include "GraphicsJNI.h" -#include "SkPicture.h" - -#include "AtomicString.h" -#include "CacheBuilder.h" -#include "CachedNode.h" -#include "CachedRoot.h" -#include "Color.h" -#include "Document.h" -#include "Element.h" -#include "Editor.h" -#include "EditorClientAndroid.h" -#include "EventHandler.h" -#include "EventNames.h" -#include "Font.h" -#include "FrameAndroid.h" -#include "FrameLoader.h" -#include "FrameTree.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "HitTestResult.h" -#include "HTMLAnchorElement.h" -#include "HTMLAreaElement.h" -#include "HTMLElement.h" -#include "HTMLImageElement.h" -#include "HTMLInputElement.h" -#include "HTMLMapElement.h" -#include "HTMLNames.h" -#include "HTMLOptGroupElement.h" -#include "HTMLOptionElement.h" -#include "HTMLSelectElement.h" -#include "HTMLTextAreaElement.h" -#include "HTMLTextFieldInnerElement.h" -#include "InlineTextBox.h" -#include "KeyboardCodes.h" -#include "Node.h" -#include "Page.h" -#include "PlatformGraphicsContext.h" -#include "PlatformKeyboardEvent.h" -#include "PlatformString.h" -#include "PluginInfoStore.h" -#include "Position.h" -#include "RenderLayer.h" -#include "RenderText.h" -#include "RenderTextControl.h" -#include "RenderThemeAndroid.h" -#include "RenderView.h" -#include "ResourceRequest.h" -#include "SelectionController.h" -#include "Settings.h" -#include "StringImpl.h" -#include "Text.h" -#include "TypingCommand.h" -#include "WebCoreFrameBridge.h" -#include "WebViewCore.h" -#include "HistoryItem.h" - -#ifdef LOG -#undef LOG -#endif - -#include <ui/KeycodeLabels.h> -#include <utils/Log.h> -#include "SkTDArray.h" -#include "SkTime.h" -#include <SkTypes.h> -#include <SkCanvas.h> -#include <SkUtils.h> -#include <JNIHelp.h> - -#include "SystemTime.h" - -#ifdef ANDROID_INSTRUMENT -static uint32_t sTotalTimeUsed = 0; -static uint32_t sTotalPaintTimeUsed = 0; -static uint32_t sCounter = 0; - -namespace WebCore { -void Frame::resetWebViewCoreTimeCounter() -{ - sTotalTimeUsed = 0; -} - -void Frame::reportWebViewCoreTimeCounter() -{ - LOG(LOG_DEBUG, "WebCore", "*-* Total native 4 (webview core) time: %d ms\n", - sTotalTimeUsed); -} -// This should be in Frame.cpp, but android LOG is conflict with webcore LOG -void Frame::resetPaintTimeCounter() -{ - sTotalPaintTimeUsed = 0; - sCounter = 0; -} - -void Frame::reportPaintTimeCounter() -{ - LOG(LOG_DEBUG, "WebCore", "*-* Total draw time: %d ms called %d times\n", - sTotalPaintTimeUsed, sCounter); -} -} -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////// - -namespace android { - -#ifdef ANDROID_INSTRUMENT -class TimeCounterWV { -public: - TimeCounterWV() { - mStartTime = WebCore::get_thread_msec(); - } - - ~TimeCounterWV() { - sTotalTimeUsed += WebCore::get_thread_msec() - mStartTime; - } - -private: - uint32_t mStartTime; -}; -#endif - -// ---------------------------------------------------------------------------- - -#define GET_NATIVE_VIEW(env, obj) ((WebViewCore*)env->GetIntField(obj, gWebViewCoreFields.mNativeClass)) - -// Field ids for WebViewCore -struct WebViewCoreFields { - jfieldID mNativeClass; - jfieldID mViewportWidth; - jfieldID mViewportHeight; - jfieldID mViewportInitialScale; - jfieldID mViewportMinimumScale; - jfieldID mViewportMaximumScale; - jfieldID mViewportUserScalable; - jfieldID mWebView; -} gWebViewCoreFields; - -// ---------------------------------------------------------------------------- - -extern JavaVM* jnienv_to_javavm(JNIEnv* env); -extern JNIEnv* javavm_to_jnienv(JavaVM* vm); - -// ---------------------------------------------------------------------------- - -/** - * Helper method for checking java exceptions - * @return true if an exception occurred. - */ -static bool checkException(JNIEnv *env) -{ - if (env->ExceptionCheck() != 0) - { - LOGE("*** Uncaught exception returned from Java call!\n"); - env->ExceptionDescribe(); - return true; - } - return false; -} - -// ---------------------------------------------------------------------------- - -struct WebViewCore::JavaGlue -{ - JavaVM* mJVM; - jobject mObj; - jmethodID mSpawnScrollTo; - jmethodID mScrollTo; - jmethodID mScrollBy; - jmethodID mContentInvalidate; - jmethodID mRequestListBox; - jmethodID mRequestSingleListBox; - jmethodID mJsAlert; - jmethodID mJsConfirm; - jmethodID mJsPrompt; - jmethodID mJsUnload; - jmethodID mDidFirstLayout; - jmethodID mSendMarkNodeInvalid; - jmethodID mSendNotifyFocusSet; - jmethodID mSendNotifyProgressFinished; - jmethodID mSendRecomputeFocus; - jmethodID mSendViewInvalidate; - jmethodID mUpdateTextfield; - jmethodID mRestoreScale; -}; - -/* - * WebViewCore Implementation - */ - -static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], const char signature[]) -{ - jmethodID m = env->GetMethodID(clazz, name, signature); - LOG_ASSERT(m, "Could not find method %s", name); - return m; -} - -Mutex WebViewCore::gFrameCacheMutex; -Mutex WebViewCore::gFrameGenerationMutex; -Mutex WebViewCore::gRecomputeFocusMutex; -Mutex WebViewCore::gButtonMutex; - -WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::FrameView* view) - : mView(view) -{ - mFrame = (WebCore::FrameAndroid*)mView->frame(); - // This will be derefed in WebCoreFrameBridge during destroy. - mView->ref(); - - mPopupReply = NULL; - mBuildGeneration = 0; - mMoveGeneration = 0; - mGeneration = 0; - mLastGeneration = 0; - mTouchGeneration = 0; - mBlockTextfieldUpdates = false; - // just initial values. These should be set by client - mMaxXScroll = 320/4; - mMaxYScroll = 240/4; - mButtons = NULL; - mTextGeneration = 0; - - LOG_ASSERT(mFrame, "Uh oh, somehow a frameview was made without an initial frame!"); - - jclass clazz = env->GetObjectClass(javaWebViewCore); - mJavaGlue = new JavaGlue; - mJavaGlue->mJVM = jnienv_to_javavm(env); - mJavaGlue->mObj = env->NewGlobalRef(javaWebViewCore); - mJavaGlue->mSpawnScrollTo = GetJMethod(env, clazz, "contentSpawnScrollTo", "(II)V"); - mJavaGlue->mScrollTo = GetJMethod(env, clazz, "contentScrollTo", "(II)V"); - mJavaGlue->mScrollBy = GetJMethod(env, clazz, "contentScrollBy", "(II)V"); - mJavaGlue->mContentInvalidate = GetJMethod(env, clazz, "contentInvalidate", "()V"); - mJavaGlue->mRequestListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[Z[I)V"); - mJavaGlue->mRequestSingleListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[ZI)V"); - mJavaGlue->mJsAlert = GetJMethod(env, clazz, "jsAlert", "(Ljava/lang/String;Ljava/lang/String;)V"); - mJavaGlue->mJsConfirm = GetJMethod(env, clazz, "jsConfirm", "(Ljava/lang/String;Ljava/lang/String;)Z"); - mJavaGlue->mJsPrompt = GetJMethod(env, clazz, "jsPrompt", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); - mJavaGlue->mJsUnload = GetJMethod(env, clazz, "jsUnload", "(Ljava/lang/String;Ljava/lang/String;)Z"); - mJavaGlue->mDidFirstLayout = GetJMethod(env, clazz, "didFirstLayout", "(Ljava/lang/String;)V"); - mJavaGlue->mSendMarkNodeInvalid = GetJMethod(env, clazz, "sendMarkNodeInvalid", "(I)V"); - mJavaGlue->mSendNotifyFocusSet = GetJMethod(env, clazz, "sendNotifyFocusSet", "()V"); - mJavaGlue->mSendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V"); - mJavaGlue->mSendRecomputeFocus = GetJMethod(env, clazz, "sendRecomputeFocus", "()V"); - mJavaGlue->mSendViewInvalidate = GetJMethod(env, clazz, "sendViewInvalidate", "()V"); - mJavaGlue->mUpdateTextfield = GetJMethod(env, clazz, "updateTextfield", "(IZLjava/lang/String;I)V"); - mJavaGlue->mRestoreScale = GetJMethod(env, clazz, "restoreScale", "(I)V"); - - env->SetIntField(javaWebViewCore, gWebViewCoreFields.mNativeClass, (jint)this); - - mVisibleRect.setWidth(0); - mVisibleRect.setHeight(0); - - reset(true); -} - -WebViewCore::~WebViewCore() -{ - // Release the focused view - Release(mPopupReply); - - if (mJavaGlue->mObj) { - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->DeleteGlobalRef(mJavaGlue->mObj); - mJavaGlue->mObj = 0; - } - delete mJavaGlue; - delete mFrameCacheKit; - delete mNavPictureKit; - if (mButtons != NULL) { - mButtons->deleteAll(); - delete mButtons; - } -} - -void WebViewCore::reset(bool fromConstructor) -{ - if (fromConstructor) { - mFrameCacheKit = NULL; - mNavPictureKit = NULL; - } else { - gFrameCacheMutex.lock(); - delete mFrameCacheKit; - delete mNavPictureKit; - mFrameCacheKit = NULL; - mNavPictureKit = NULL; - gFrameCacheMutex.unlock(); - } - - mLastFocused = NULL; - mLastFocusedBounds = WebCore::IntRect(0,0,0,0); - mUpdatedFrameCache = true; - mFrameCacheOutOfDate = true; - mBlockFocusChange = false; - mSnapAnchorNode = NULL; - mUseReplay = false; -} - -void WebViewCore::draw(WebCore::GraphicsContext* ctx, - const WebCore::IntRect& r, bool invalCache) -{ - LOG_ASSERT(mFrame, "%s has no frame for this view!", __FUNCTION__); - LOG_ASSERT(mFrame == mView->frame(), "Our frames do not match!"); -#ifdef ANDROID_INSTRUMENT - uint32_t startTime = WebCore::get_thread_msec(); -#endif - if (NULL == mFrame->renderer()) { - // We only do this if there is nothing else to draw. - // If there is a renderer, it will fill the bg itself, so we don't want to - // double-draw (slow) - SkCanvas* canvas = ctx->platformContext()->mCanvas; - canvas->drawColor(SK_ColorWHITE); - } - else { - mFrame->paint(ctx, r); - } - if (invalCache) { - WebCore::CacheBuilder& builder = mFrame->getCacheBuilder(); - WebCore::Node* oldFocusNode = builder.currentFocus(); - mFrameCacheOutOfDate = true; - WebCore::IntRect oldBounds = oldFocusNode ? - oldFocusNode->getRect() : WebCore::IntRect(0,0,0,0); - DBG_NAV_LOGD_ONCE("mLastFocused=%p oldFocusNode=%p" - " mLastFocusedBounds={%d,%d,%d,%d} oldBounds={%d,%d,%d,%d}", - mLastFocused, oldFocusNode, - mLastFocusedBounds.x(), mLastFocusedBounds.y(), mLastFocusedBounds.width(), mLastFocusedBounds.height(), - oldBounds.x(), oldBounds.y(), oldBounds.width(), oldBounds.height()); - if (mLastFocused != oldFocusNode || mLastFocusedBounds != oldBounds) { - mLastFocused = oldFocusNode; - mLastFocusedBounds = oldBounds; - DBG_NAV_LOG("call updateFrameCache"); - updateFrameCache(); - } - } -#ifdef ANDROID_INSTRUMENT - sTotalPaintTimeUsed += WebCore::get_thread_msec() - startTime; - sCounter++; -#endif -} - -void WebViewCore::recordPicture(SkPicture* picture, bool invalCache) -{ - // if there is no document yet, just return - if (!mFrame->document()) - return; - - // Call layout to ensure that the contentWidth and contentHeight are correct - WebCore::ScrollView* view = mFrame->view(); - view->ignoreUpdateContents(true); - layout(); - view->ignoreUpdateContents(false); - -#if USE(DOUBLE_TREE) - // if haveStylesheetsLoaded() is false, render is not created, so don't call draw. - // It can happen when we switch from fast display mode, new style sheets are requested, - // if we call draw, we will have blank screen. - if (mFrame->document() && !mFrame->loader()->isComplete() && - !mFrame->document()->haveStylesheetsLoaded()) { - LOGV("skip %s", __FUNCTION__); - return; - } -#endif - - // draw into the picture's recording canvas - SkAutoPictureRecord arp(picture, contentWidth(), contentHeight()); - SkAutoMemoryUsageProbe mup(__FUNCTION__); - - WebCore::PlatformGraphicsContext pgc(arp.getRecordingCanvas()); - WebCore::GraphicsContext gc(&pgc); - WebCore::IntRect r = WebCore::IntRect(0, 0, INT_MAX, INT_MAX); - draw(&gc, r, invalCache); - - // If this was done for the Java Picture that is being displayed, grab the - // info for the buttons, so the UI thread can grab them and update them - // according to their state. - if (invalCache) { - gButtonMutex.lock(); - if (mButtons != NULL) { - mButtons->deleteAll(); - delete mButtons; - } - mButtons = pgc.getAndClearButtonInfo(); - gButtonMutex.unlock(); - } -} - -void WebViewCore::onResize() -{ - LOGV("view is resized, notifying the frame to relayout..."); - LOG_ASSERT(mFrame == mView->frame(), "Our frames do not match!"); - // r could be NULL because our frame has not processed any data. This happens - // when an HTMLWidget is first created, attached and sizeChanged is called. - WebCore::RenderObject *r = mFrame->renderer(); - if (r) { - r->setNeedsLayoutAndPrefWidthsRecalc(); - mFrame->forceLayout(true); - } -} - -WebCore::RenderLayer* WebViewCore::getRenderLayer() -{ - LOG_ASSERT(mView, "A view was not associated with this view bridge!"); - LOG_ASSERT(mFrame, "A frame was not associated with our frame view!"); - LOG_ASSERT(mFrame == mView->frame(), "Our frames do not match!"); - WebCore::Document* doc = mFrame->document(); - if (doc == NULL) - return NULL; - WebCore::RenderObject* renderer = doc->renderer(); - return renderer->enclosingLayer(); -} - -bool WebViewCore::pinXToDocument(int* xPtr) -{ - WebCore::RenderLayer* layer = getRenderLayer(); - if (layer == NULL) - return false; - int docWidth = layer->width(); - int x = *xPtr; - if (x < 0 || docWidth <= this->width()) - x = 0; - else if (x + this->width() > docWidth) - x = docWidth - this->width(); - *xPtr = x; - return true; -} - -bool WebViewCore::pinYToDocument(int* yPtr) -{ - WebCore::RenderLayer* layer = getRenderLayer(); - if (layer == NULL) - return false; - int docHeight = layer->height(); - int y = *yPtr; - if (y < 0 || docHeight <= this->height()) - y = 0; - else if (y + this->height() > docHeight) - y = docHeight - this->height(); - *yPtr = y; - return true; -} - -void WebViewCore::scrollTo(int x, int y, bool animate) -{ - LOG_ASSERT(mParent == NULL, "Why do we have a parent"); - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - -// LOGD("WebViewCore::scrollTo(%d %d)\n", x, y); - - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, animate ? mJavaGlue->mSpawnScrollTo : mJavaGlue->mScrollTo, x, y); - checkException(env); -} - -void WebViewCore::sendMarkNodeInvalid(WebCore::Node* node) -{ - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mSendMarkNodeInvalid, (int) node); - checkException(env); -} - -void WebViewCore::sendNotifyFocusSet() -{ - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mSendNotifyFocusSet); - checkException(env); -} - -void WebViewCore::sendNotifyProgressFinished() -{ - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mSendNotifyProgressFinished); - checkException(env); -} - -void WebViewCore::sendRecomputeFocus() -{ - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mSendRecomputeFocus); - checkException(env); -} - -void WebViewCore::sendViewInvalidate() -{ - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mSendViewInvalidate); - checkException(env); -} - -void WebViewCore::scrollBy(int dx, int dy) -{ - LOG_ASSERT(mParent == NULL, "Why do we have a parent"); - if ((dx | dy) == 0) - return; - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mScrollBy, dx, dy); - checkException(env); -} - -void WebViewCore::contentInvalidate(const WebCore::IntRect &rect) -{ -// DBG_NAV_LOGD("rect={%d,%d,%d,%d}", rect.x(), rect.y(), rect.width(), rect.height()); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mContentInvalidate); - checkException(env); -} - -void WebViewCore::contentInvalidate() -{ -// DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mContentInvalidate); - checkException(env); -} - -static int pin_pos(int x, int width, int targetWidth) -{ - if (x + width > targetWidth) - x = targetWidth - width; - if (x < 0) - x = 0; - return x; -} - -void WebViewCore::didFirstLayout() -{ - LOG_ASSERT(mParent == NULL, "Why do we have a parent"); - - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - - const WebCore::KURL& url = mFrame->loader()->url(); - if (url.isEmpty()) - return; - LOGV("::WebCore:: didFirstLayout %s", url.string().ascii().data()); - - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - WebCore::String urlString(url.string()); - jstring urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mDidFirstLayout, urlStr); - checkException(env); - env->DeleteLocalRef(urlStr); - - DBG_NAV_LOG("call updateFrameCache"); - updateFrameCache(); - mHistory.setDidFirstLayout(true); -} - -void WebViewCore::restoreScale(int scale) -{ - LOG_ASSERT(mParent == NULL, "Why do we have a parent"); - - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mRestoreScale, scale); - checkException(env); -} - -static void layoutIfNeededRecursive(WebCore::Frame* f) -{ - if (!f) - return; - - WebCore::FrameView* v = f->view(); - if (!v) - return; - - if (v->needsLayout()) - v->layout(); - - if (!f->tree()) - return; - - WebCore::Frame* child = f->tree()->firstChild(); - while (child) { - WebCore::FrameView* childView = child->view(); - if (childView) - layoutIfNeededRecursive(child); - if (!child->tree()) - break; - child = child->tree()->nextSibling(); - } -} - -void WebViewCore::layout() -{ - LOG_ASSERT(mParent == NULL, "Why do we have a parent"); - - SkASSERT(mView); - layoutIfNeededRecursive(mFrame); -} - -void WebViewCore::notifyFocusSet() -{ - sendNotifyFocusSet(); -} - -void WebViewCore::notifyProgressFinished() -{ - DBG_NAV_LOG("call updateFrameCache"); - updateFrameCache(); - sendNotifyProgressFinished(); -} - -void WebViewCore::doMaxScroll(WebCore::CacheBuilder::Direction dir) -{ - int dx = 0, dy = 0; - - switch (dir) { - case WebCore::CacheBuilder::LEFT: - dx = -this->getMaxXScroll(); - break; - case WebCore::CacheBuilder::UP: - dy = -this->getMaxXScroll(); - break; - case WebCore::CacheBuilder::RIGHT: - dx = this->getMaxYScroll(); - break; - case WebCore::CacheBuilder::DOWN: - dy = this->getMaxYScroll(); - break; - case WebCore::CacheBuilder::UNINITIALIZED: - default: - LOG_ASSERT(0, "unexpected focus selector"); - } - this->scrollBy(dx, dy); -} - -void WebViewCore::getVisibleRect(WebCore::IntRect* rect) const -{ - SkASSERT(rect); - *rect = mVisibleRect; -} - -void WebViewCore::setVisibleRect(const WebCore::IntRect& r) -{ - DBG_NAV_LOGD("{%d,%d,%d,%d}", r.x(), r.y(), r.width(), r.height()); - if (mVisibleRect != r) { - if (mVisibleRect.x() != r.x() || mVisibleRect.y() != r.y()) - mFrame->sendScrollEvent(); - mVisibleRect = r; - // The visible rect is located within our coordinate space so it - // contains the actual scroll position. Setting the location makes hit - // testing work correctly. - setLocation(r.x(), r.y()); - } -} - -void WebViewCore::dump() -{ -#if DUMP_NAV_CACHE - if (mFrame != NULL) - mFrame->getCacheBuilder().mDebug.print(); -#endif -} - -WebCore::String WebViewCore::retrieveHref(WebCore::Frame* frame, WebCore::Node* node) -{ - WebCore::CacheBuilder& builder = mFrame->getCacheBuilder(); - if (builder.validNode(frame, node) == false) - return WebCore::String(); - if (node->hasTagName(WebCore::HTMLNames::aTag) == false) - return WebCore::String(); - WebCore::HTMLAnchorElement* anchor = static_cast<WebCore::HTMLAnchorElement*>(node); - return anchor->href(); -} - -WebCore::String WebViewCore::retrieveImageRef(int x, int y) -{ - WebCore::IntPoint point(x,y); - WebCore::HitTestResult result = mFrame->eventHandler()->hitTestResultAtPoint(point, false); - WebCore::Node* node = result.innerNode(); - if (node == NULL || node->hasTagName(WebCore::HTMLNames::imgTag) == false) - return WebCore::String(); - WebCore::HTMLImageElement* img = static_cast<WebCore::HTMLImageElement*>(node); - return img->src(); -} - -bool WebViewCore::prepareFrameCache() -{ - if (mFrameCacheOutOfDate == false) { - DBG_NAV_LOG("mFrameCacheOutOfDate == false"); - return false; - } - mFrameCacheOutOfDate = false; -#if DEBUG_NAV_UI - DBG_NAV_LOG("mFrameCacheOutOfDate was true"); - mNow = SkTime::GetMSecs(); -#endif - mTemp = new CachedRoot(); - mTemp->init(mFrame, &mHistory); - mTemp->setGeneration(++mBuildGeneration); - WebCore::CacheBuilder& builder = mFrame->getCacheBuilder(); - WebCore::Settings* settings = frame()->page()->settings(); - builder.allowAllTextDetection(); - if (settings->formatDetectionAddress() == false) - builder.disallowAddressDetection(); - if (settings->formatDetectionEmail() == false) - builder.disallowEmailDetection(); - if (settings->formatDetectionTelephone() == false) - builder.disallowPhoneDetection(); - builder.buildCache(mTemp); - mTempPict = new SkPicture(); - recordPicture(mTempPict, false); - mTemp->setPicture(mTempPict); - mTemp->setTextGeneration(mTextGeneration); - return true; -} - -void WebViewCore::releaseFrameCache(bool newCache) -{ - if (newCache == false) { - DBG_NAV_LOG("newCache == false"); - return; - } - gFrameCacheMutex.lock(); - delete mFrameCacheKit; - delete mNavPictureKit; - mFrameCacheKit = mTemp; - mNavPictureKit = mTempPict; - mUpdatedFrameCache = true; -#if DEBUG_NAV_UI - const CachedNode* cachedFocusNode = mFrameCacheKit->currentFocus(); - DBG_NAV_LOGD("cachedFocusNode=%d (nodePointer=%p)", - cachedFocusNode ? cachedFocusNode->index() : 0, - cachedFocusNode ? cachedFocusNode->nodePointer() : NULL); -#endif - gFrameCacheMutex.unlock(); - notifyFocusSet(); - // it's tempting to send an invalidate here, but it's a bad idea - // the cache is now up to date, but the focus is not -- the event - // may need to be recomputed from the prior history. An invalidate - // will draw the stale location causing the ring to flash at the wrong place. -} - -void WebViewCore::updateFrameCache() -{ - mUseReplay = false; - releaseFrameCache(prepareFrameCache()); -} - -void WebViewCore::removeFrameGeneration(WebCore::Frame* frame) -{ - DBG_NAV_LOGD("frame=%p mGeneration=%d", frame, mGeneration); - gFrameGenerationMutex.lock(); - int last = mFrameGenerations.size() - 1; - for (int index = 0; index <= last; index++) { - if (mFrameGenerations[index].mFrame == frame) { - DBG_NAV_LOGD("index=%d last=%d", index, last); - if (index != last) - mFrameGenerations[index] = mFrameGenerations[last]; - mFrameGenerations.removeLast(); - break; - } - } - gFrameGenerationMutex.unlock(); -} - -void WebViewCore::updateFrameGeneration(WebCore::Frame* frame) -{ - DBG_NAV_LOGD("frame=%p mGeneration=%d", frame, mGeneration); - gFrameGenerationMutex.lock(); - ++mBuildGeneration; - for (size_t index = 0; index < mFrameGenerations.size(); index++) { - if (mFrameGenerations[index].mFrame == frame) { - DBG_NAV_LOG("replace"); - mFrameGenerations[index].mGeneration = mBuildGeneration; - goto done; - } - } - { - FrameGen frameGen = {frame, mBuildGeneration}; - mFrameGenerations.append(frameGen); - DBG_NAV_LOG("append"); - } -done: - gFrameGenerationMutex.unlock(); -} - -int WebViewCore::retrieveFrameGeneration(WebCore::Frame* frame) -{ - int result = INT_MAX; - gFrameGenerationMutex.lock(); - for (size_t index = 0; index < mFrameGenerations.size(); index++) { - if (mFrameGenerations[index].mFrame == frame) { - result = mFrameGenerations[index].mGeneration; - break; - } - } - gFrameGenerationMutex.unlock(); - DBG_NAV_LOGD("frame=%p mGeneration=%d result=%d", frame, mGeneration, result); - return result; -} - -void WebViewCore::setFinalFocus(WebCore::Frame* frame, WebCore::Node* node, - int x, int y, bool block) -{ - DBG_NAV_LOGD("frame=%p node=%p x=%d y=%d", frame, node, x, y); - bool result = finalKitFocus(frame, node, x, y); - if (block) { - mBlockFocusChange = true; - if (result == false && node != NULL) - touchUp(mTouchGeneration, 0, NULL, NULL, x, y, 0, true, true); - } -} - -void WebViewCore::setKitFocus(int moveGeneration, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus) -{ - DBG_NAV_LOGD("mMoveGeneration=%d moveGeneration=%d" - " buildGeneration=%d frame=%p node=%p x=%d y=%d", - mMoveGeneration, moveGeneration, buildGeneration, frame, node, x, y); - if (mBlockFocusChange) { - DBG_NAV_LOG("mBlockFocusChange"); - return; - } - if (mMoveGeneration > moveGeneration) { - DBG_NAV_LOGD("mMoveGeneration=%d > moveGeneration=%d", - mMoveGeneration, moveGeneration); - return; // short-circuit if a newer move has already been generated - } - if (commonKitFocus(moveGeneration, buildGeneration, frame, node, x, y, - ignoreNullFocus) == false) - return; - mLastGeneration = moveGeneration; -} - -bool WebViewCore::commonKitFocus(int generation, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus) -{ - DBG_NAV_LOGD("generation=%d buildGeneration=%d frame=%p" - " node=%p x=%d y=%d", generation, buildGeneration, frame, node, x, y); - mUseReplay = true; - bool newCache = prepareFrameCache(); // must wait for possible recompute before using - if (mMoveGeneration > generation) { - DBG_NAV_LOGD("mMoveGeneration=%d > generation=%d", - mMoveGeneration, generation); - releaseFrameCache(newCache); - return false; // short-circuit if a newer move has already been generated - } - // if the nav cache has been rebuilt since this focus request was generated, - // send a request back to the UI side to recompute the kit-side focus - if (mBuildGeneration > buildGeneration || (node != NULL && mFrame->getCacheBuilder().validNode(frame, node) == false)) { - DBG_NAV_LOGD("mBuildGeneration=%d > buildGeneration=%d", - mBuildGeneration, buildGeneration); - gRecomputeFocusMutex.lock(); - bool first = mRecomputeEvents.size() == 0; - mRecomputeEvents.append(generation); - gRecomputeFocusMutex.unlock(); - releaseFrameCache(newCache); - if (first) - sendRecomputeFocus(); - return false; - } - releaseFrameCache(newCache); - if (node == NULL && ignoreNullFocus) - return true; - finalKitFocus(frame, node, x, y); - return true; -} - -bool WebViewCore::finalKitFocus(WebCore::Frame* frame, WebCore::Node* node, - int x, int y) -{ - if (NULL == frame) - frame = mFrame; - WebCore::CacheBuilder& builder = mFrame->getCacheBuilder(); - WebCore::Node* oldFocusNode = builder.currentFocus(); - mMousePos = WebCore::IntPoint(x, y); - // validNode will still return true if the node is null, as long as we have - // a valid frame. Do not want to make a call on frame unless it is valid. - bool valid = builder.validNode(frame, node); - if (valid) { - WebCore::PlatformMouseEvent mouseEvent(mMousePos, mMousePos, WebCore::NoButton, - WebCore::MouseEventMoved, 1, false, false, false, false, WebCore::currentTime()); - frame->eventHandler()->handleMouseMoveEvent(mouseEvent); - } - WebCore::Document* oldDoc = oldFocusNode ? oldFocusNode->document() : NULL; - if (node == NULL) { - if (oldFocusNode != NULL) - oldDoc->setFocusedNode(NULL); - return false; - } else if (valid == false) { - DBG_NAV_LOGD("sendMarkNodeInvalid node=%p", node); - sendMarkNodeInvalid(node); - if (oldFocusNode != NULL) - oldDoc->setFocusedNode(NULL); - return false; - } - // If we jump frames (docs), kill the focus on the old doc - builder.setLastFocus(node); - if (oldFocusNode != NULL && node->document() != oldDoc) { - oldDoc->setFocusedNode(NULL); - } - WebCore::RenderObject* renderer = node->renderer(); - /* <area> element doesn't have a renderer, but it can accept focus */ - LOG_ASSERT(!(renderer && renderer->isWidget()), "widgets unsupported"); - if (node->isTextNode() == false) - static_cast<WebCore::Element*>(node)->focus(false); - //setFocus on things that WebCore doesn't recognize as supporting focus - //for instance, if there is an onclick element that does not support focus - DBG_NAV_LOGD("setFocusedNode node=%p", node); - node->document()->setFocusedNode(node); - mLastFocused = node; - mLastFocusedBounds = node->getRect(); - return true; -} - -// helper function to find the frame that has focus -static WebCore::Frame* FocusedFrame(WebCore::FrameAndroid* frame) -{ - if (!frame) - return NULL; - WebCore::Node* focusNode = frame->getCacheBuilder().currentFocus(); - if (!focusNode) - return NULL; - WebCore::Document* doc = focusNode->document(); - if (!doc) - return NULL; - return doc->frame(); -} - -static WebCore::RenderTextControl* FocusedTextControl(WebCore::FrameAndroid* frame) -{ - WebCore::Node* focusNode = frame->getCacheBuilder().currentFocus(); - WebCore::RenderObject* renderer = focusNode->renderer(); - if (renderer && (renderer->isTextField() || renderer->isTextArea())) { - return static_cast<WebCore::RenderTextControl*>(renderer); - } - return NULL; -} - -WebCore::Frame* WebViewCore::changedKitFocus(WebCore::Frame* frame, - WebCore::Node* node, int x, int y) -{ - if (frame == NULL || node == NULL) - return mFrame; - WebCore::Node* current = mFrame->getCacheBuilder().currentFocus(); - if (current == node) - return frame; - return finalKitFocus(frame, node, x, y) ? frame : mFrame; -} - -static int findTextBoxIndex(WebCore::Node* node, const WebCore::IntPoint& pt) -{ - if (node->isTextNode() == false) { - DBG_NAV_LOGD("node=%p pt=(%d,%d) isText=false", node, pt.x(), pt.y()); - return -2; // error - } - WebCore::RenderText* renderText = (WebCore::RenderText*) node->renderer(); - if (renderText == NULL) { - DBG_NAV_LOGD("node=%p pt=(%d,%d) renderText=NULL", node, pt.x(), pt.y()); - return -3; // error - } - int renderX, renderY; - renderText->absolutePosition(renderX, renderY); - WebCore::InlineTextBox *textBox = renderText->firstTextBox(); - int globalX, globalY; - WebCore::CacheBuilder::GetGlobalOffset(node, &globalX, &globalY); - int x = pt.x() - globalX; - int y = pt.y() - globalY; - do { - int textBoxStart = textBox->start(); - int textBoxEnd = textBoxStart + textBox->len(); - if (textBoxEnd <= textBoxStart) - continue; - WebCore::IntRect bounds = textBox->selectionRect(renderX, renderY, - textBoxStart, textBoxEnd); - if (bounds.contains(x, y) == false) - continue; - int offset = textBox->offsetForPosition(x - renderX); -#if DEBUG_NAV_UI - int prior = offset > 0 ? textBox->positionForOffset(offset - 1) : -1; - int current = textBox->positionForOffset(offset); - int next = textBox->positionForOffset(offset + 1); - DBG_NAV_LOGD( - "offset=%d pt.x=%d globalX=%d renderX=%d x=%d " - "textBox->x()=%d textBox->start()=%d prior=%d current=%d next=%d", - offset, pt.x(), globalX, renderX, x, - textBox->xPos(), textBox->start(), prior, current, next - ); -#endif - return textBox->start() + offset; - } while ((textBox = textBox->nextTextBox()) != NULL); - return -1; // couldn't find point, may have walked off end -} - -static inline bool isSpace(UChar c) -{ - return c <= ' ' || WTF::Unicode::direction(c) == WTF::Unicode::WhiteSpaceNeutral; -} - -static int centerX(const SkIRect& rect) { return (rect.fLeft + rect.fRight) >> 1; } -static int centerY(const SkIRect& rect) { return (rect.fTop + rect.fBottom) >> 1; } - -WebCore::String WebViewCore::getSelection(SkRegion* selRgn) -{ - SkRegion::Iterator iter(*selRgn); - WebCore::String result; - for (; iter.done() == false; iter.next()) { - const SkIRect& rect = iter.rect(); - DBG_NAV_LOGD("rect=(%d, %d, %d, %d)", rect.fLeft, rect.fTop, - rect.fRight, rect.fBottom); - int cy = centerY(rect); - WebCore::IntPoint startPt = WebCore::IntPoint(rect.fLeft + 1, cy); - WebCore::HitTestResult hitTestResult = mFrame->eventHandler()-> - hitTestResultAtPoint(startPt, false); - WebCore::Node* node = hitTestResult.innerNode(); - if (node == NULL) { - DBG_NAV_LOG("node == NULL"); - return result; - } - WebCore::IntPoint endPt = WebCore::IntPoint(rect.fRight - 1, cy); - hitTestResult = mFrame->eventHandler()->hitTestResultAtPoint(endPt, false); - WebCore::Node* endNode = hitTestResult.innerNode(); - if (endNode == NULL) { - DBG_NAV_LOG("endNode == NULL"); - return result; - } - int start = findTextBoxIndex(node, startPt); - if (start < 0) - continue; - int end = findTextBoxIndex(endNode, endPt); - if (end < -1) // use node if endNode is not valid - endNode = node; - if (end <= 0) - end = static_cast<WebCore::Text*>(endNode)->string()->length(); - DBG_NAV_LOGD("node=%p start=%d endNode=%p end=%d", node, start, endNode, end); - do { - if (node->isTextNode() == false) - continue; - if (node->getRect().isEmpty()) - continue; - WebCore::Text* textNode = static_cast<WebCore::Text*>(node); - WebCore::StringImpl* string = textNode->string(); - if (string->length() == 0) - continue; - const UChar* chars = string->characters(); - int newLen = node == endNode ? end : string->length(); - int oldLen = result.length(); - if (oldLen == 0) { - if (newLen < start) { - DBG_NAV_LOGD("newLen=%d < start=%d", newLen, start); - return result; - } - result.append(chars + start, newLen - start); - continue; - } - if (isSpace(result.characters()[oldLen - 1]) == false && - isSpace(chars[0]) == false) { - result.append(" "); - } - result.append(chars, newLen); - } while (node != endNode && (node = node->traverseNextNode()) != NULL); - } -#if DUMP_NAV_CACHE - { - char buffer[256]; - WebCore::CacheBuilder::Debug debug; - debug.init(buffer, sizeof(buffer)); - debug.print("copy: "); - debug.wideString(result); - DUMP_NAV_LOGD("%s", buffer); - } -#endif - return result; -} - -WebCore::Frame* WebViewCore::setSelection(WebCore::Frame* frame, WebCore::Node* node, - int x, int y, int start, int end) -{ - // FIXME: Consider using a generation number to avoid doing this many more times than necessary. - frame = changedKitFocus(frame, node, x, y); - ((WebCore::FrameAndroid*) frame)->select(start, end); - return frame; -} - -WebCore::Frame* WebViewCore::deleteSelection(WebCore::Frame* frame, WebCore::Node* node, - int x, int y, int start, int end) -{ - frame = setSelection(frame, node, x, y, start, end); - if (start != end) { - WebCore::PlatformKeyboardEvent downEvent(kKeyCodeDel, WebCore::VK_BACK, true, false, false, false, false); - frame->eventHandler()->keyEvent(downEvent); - WebCore::PlatformKeyboardEvent upEvent(kKeyCodeDel, WebCore::VK_BACK, false, false, false, false, false); - frame->eventHandler()->keyEvent(upEvent); - } - return frame; -} - -void WebViewCore::replaceTextfieldText(WebCore::Frame* frame, WebCore::Node* node, int x, int y, - int oldStart, int oldEnd, jstring replace, int start, int end) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - const jchar* outputChars = NULL == replace ? NULL : env->GetStringChars(replace, NULL); - - WebCore::String webcoreString; - if (outputChars == NULL) { - webcoreString = WebCore::String(); - } - else { - webcoreString = WebCore::String((const UChar*) outputChars, env->GetStringLength(replace)); - } - frame = setSelection(frame, node, x, y, oldStart, oldEnd); - WebCore::TypingCommand::insertText(frame->document(), webcoreString, false); - ((WebCore::FrameAndroid*) frame)->select(start, end); - if (replace && outputChars) - env->ReleaseStringChars(replace, outputChars); - checkException(env); -} - -void WebViewCore::passToJs(WebCore::Frame* frame, WebCore::Node* node, int x, int y, int generation, - jstring currentText, int keyCode, int keyValue, bool down, bool cap, bool fn, bool sym) -{ - frame = changedKitFocus(frame, node, x, y); - WebCore::PlatformKeyboardEvent event(keyCode, keyValue, down, false, cap, fn, sym); - // Block text field updates during a key press. - mBlockTextfieldUpdates = true; - frame->eventHandler()->keyEvent(event); - mBlockTextfieldUpdates = false; - mTextGeneration = generation; - - WebCore::Node* currentFocus = mFrame->getCacheBuilder().currentFocus(); - // Make sure we have the same focus and it is a text field. - if (node == currentFocus && currentFocus) { - WebCore::RenderObject* renderer = currentFocus->renderer(); - if (renderer != NULL && (renderer->isTextField() || renderer->isTextArea())) { - WebCore::RenderTextControl* renderText = static_cast<WebCore::RenderTextControl*>(renderer); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - const jchar* str = env->GetStringChars(currentText, NULL); - WebCore::String current = WebCore::String(str, env->GetStringLength(currentText)); - env->ReleaseStringChars(currentText, str); - WebCore::String test = renderText->text(); - // If the text changed during the key event, update the UI text field. - if (test != current) - updateTextfield(currentFocus, false, test); - } - } -} - -void WebViewCore::saveDocumentState(WebCore::Frame* frame, WebCore::Node* node, int x, int y) -{ - frame = changedKitFocus(frame, node, x, y); - WebCore::HistoryItem *item = frame->loader()->currentHistoryItem(); - - // item can be null when there is no offical URL for the current page. This happens - // when the content is loaded using with WebCoreFrameBridge::LoadData() and there - // is no failing URL (common case is when content is loaded using data: scheme) - if (item != 0) { - item->setDocumentState(frame->document()->formElementsState()); - } -} - -// Convert a WebCore::String into an array of characters where the first -// character represents the length, for easy conversion to java. -static uint16_t* stringConverter(const WebCore::String& text) -{ - size_t length = text.length(); - uint16_t* itemName = new uint16_t[length+1]; - itemName[0] = (uint16_t)length; - uint16_t* firstChar = &(itemName[1]); - memcpy((void*)firstChar, text.characters(), sizeof(UChar)*length); - return itemName; -} - -// Response to dropdown created for a listbox. -class ListBoxReply : public WebCoreReply { -public: - ListBoxReply(WebCore::HTMLSelectElement* select, WebCore::Frame* frame, WebViewCore* view) - : m_select(select) - , m_frame(frame) - , m_viewImpl(view) - {} - - // Response used if the listbox only allows single selection. - // index is listIndex of the selected item, or -1 if nothing is selected. - virtual void replyInt(int index) { - // If the select element no longer exists, do to a page change, etc, silently return. - if (!m_select || m_viewImpl->mFrame->getCacheBuilder().validNode(m_frame, m_select) == false) - return; - if (-1 == index) { - if (m_select->selectedIndex() != -1) { - m_select->deselectItems(); - m_select->onChange(); - m_viewImpl->contentInvalidate(); - } - return; - } - WebCore::HTMLOptionElement* option = static_cast<WebCore::HTMLOptionElement*>( - m_select->item(m_select->listToOptionIndex(index))); - if (!option->selected()) { - option->setSelected(true); - m_select->onChange(); - m_viewImpl->contentInvalidate(); - } - } - - // Response if the listbox allows multiple selection. array stores the listIndices - // of selected positions. - virtual void replyIntArray(SkTDArray<int> array) { - // If the select element no longer exists, do to a page change, etc, silently return. - if (!m_select || m_viewImpl->mFrame->getCacheBuilder().validNode(m_frame, m_select) == false) - return; - m_select->deselectItems(); - int count = array.count(); - WebCore::HTMLOptionElement* option; - for (int i = 0; i < count; i++) { - option = static_cast<WebCore::HTMLOptionElement*>( - m_select->item(array[m_select->listToOptionIndex(i)])); - option->setSelected(true); - } - m_viewImpl->contentInvalidate(); - } -private: - // The select element associated with this listbox. - WebCore::HTMLSelectElement* m_select; - // The frame of this select element, to verify that it is valid. - WebCore::Frame* m_frame; - // For calling invalidate. - WebViewCore* m_viewImpl; -}; - -// Create an array of java Strings. -static jobjectArray makeLabelArray(JNIEnv* env, const uint16_t** labels, size_t count) -{ - jclass stringClass = env->FindClass("java/lang/String"); - LOG_ASSERT(stringClass, "Could not find java/lang/String"); - jobjectArray array = env->NewObjectArray(count, stringClass, NULL); - LOG_ASSERT(array, "Could not create new string array"); - - for (size_t i = 0; i < count; i++) { - jobject newString = env->NewString(&labels[i][1], labels[i][0]); - env->SetObjectArrayElement(array, i, newString); - env->DeleteLocalRef(newString); - checkException(env); - } - env->DeleteLocalRef(stringClass); - return array; -} - -void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, size_t count, const int enabled[], size_t enabledCount, - bool multiple, const int selected[], size_t selectedCountOrSelection) { - // Reuse mPopupReply - Release(mPopupReply); - mPopupReply = NULL; - - LOG_ASSERT(mJavaGlue->mObj, "No java widget associated with this view!"); - - // Create an array of java Strings for the drop down. - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - jobjectArray labelArray = makeLabelArray(env, labels, count); - - // Create an array determining whether each item is enabled. - jbooleanArray enabledArray = env->NewBooleanArray(enabledCount); - checkException(env); - jboolean* ptrArray = env->GetBooleanArrayElements(enabledArray, NULL); - checkException(env); - for (size_t i = 0; i < enabledCount; i++) { - ptrArray[i] = enabled[i]; - } - env->ReleaseBooleanArrayElements(enabledArray, NULL, enabledCount); - checkException(env); - - if (multiple) { - // Pass up an array representing which items are selected. - jintArray selectedArray = env->NewIntArray(selectedCountOrSelection); - checkException(env); - jint* selArray = env->GetIntArrayElements(selectedArray, NULL); - checkException(env); - for (size_t i = 0; i < selectedCountOrSelection; i++) { - selArray[i] = selected[i]; - } - env->ReleaseIntArrayElements(selectedArray, NULL, selectedCountOrSelection); - - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mRequestListBox, labelArray, enabledArray, selectedArray); - env->DeleteLocalRef(selectedArray); - } else { - // Pass up the single selection. - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mRequestSingleListBox, labelArray, enabledArray, selectedCountOrSelection); - } - - env->DeleteLocalRef(labelArray); - env->DeleteLocalRef(enabledArray); - checkException(env); - - Retain(reply); - mPopupReply = reply; -} - -bool WebViewCore::keyUp(KeyCode keyCode, int keyVal) -{ - DBG_NAV_LOGD("keyCode=%d", keyCode); - bool keyHandled = false; - WebCore::Node* focusNode = mFrame->getCacheBuilder().currentFocus(); - if (focusNode != NULL) { - WebCore::FrameAndroid* focusFrame = Android(focusNode->document()->frame()); - - WebCoreFrameBridge* bridge = mFrame->bridge(); - switch (keyCode) { - case kKeyCodeNewline: - case kKeyCodeDpadCenter: { - focusFrame->loader()->resetMultipleFormSubmissionProtection(); - bridge->setInKeyHandler(true); - if ((focusNode->hasTagName(WebCore::HTMLNames::inputTag) && - ((WebCore::HTMLInputElement*)focusNode)->isTextField()) || - focusNode->hasTagName(WebCore::HTMLNames::textareaTag)) { - // Create the key down event. - WebCore::PlatformKeyboardEvent keydown(keyCode, keyVal, true, false, false, false, false); - // Create the key up event. - WebCore::PlatformKeyboardEvent keyup(keyCode, keyVal, false, false, false, false, false); - // Send both events. - keyHandled = focusFrame->eventHandler()->keyEvent(keydown); - keyHandled |= focusFrame->eventHandler()->keyEvent(keyup); - } else { - keyHandled = handleMouseClick(focusFrame, focusNode); - } - bridge->setInKeyHandler(false); - break; - } - default: - keyHandled = false; - } - } - mBlockFocusChange = false; - return keyHandled; -} - -void WebViewCore::touchUp(int touchGeneration, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, int size, - bool isClick, bool retry) -{ - if (mTouchGeneration > touchGeneration) { - DBG_NAV_LOGD("mTouchGeneration=%d > touchGeneration=%d" - " x=%d y=%d", mTouchGeneration, touchGeneration, x, y); - return; // short circuit if a newer touch has been generated - } - if (retry) - finalKitFocus(frame, node, x, y); - else if (commonKitFocus(touchGeneration, buildGeneration, - frame, node, x, y, false) == false) { - return; - } - mLastGeneration = touchGeneration; - // If this is just a touch and not a click, we have already done the change in focus, - // so just leave the function now. - if (!isClick) - return; - WebCore::EditorClientAndroid* client = static_cast<WebCore::EditorClientAndroid*>(mFrame->editor()->client()); - client->setFromClick(true); - DBG_NAV_LOGD("touchGeneration=%d handleMouseClick frame=%p node=%p" - " x=%d y=%d", touchGeneration, frame, node, x, y); - handleMouseClick(frame, node); - client->setFromClick(false); -} - -bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr) { - if (framePtr != NULL && mFrame->getCacheBuilder().validNode(framePtr, nodePtr) == false) - return false; - WebCoreFrameBridge* bridge = mFrame->bridge(); - // Need to special case area tags because an image map could have an area element in the middle - // so when attempting to get the default, the point chosen would be follow the wrong link. - if (nodePtr != NULL && nodePtr->hasTagName(WebCore::HTMLNames::areaTag)) { - bridge->setInKeyHandler(true); - WebCore::EventTargetNodeCast(nodePtr)->dispatchSimulatedClick(0, true, true); - bridge->setInKeyHandler(false); - return true; - } - WebCore::RenderObject* renderer = nodePtr != NULL ? nodePtr->renderer() : NULL; - if (renderer) { - if (renderer->isMenuList()) { - WebCore::HTMLSelectElement* select = static_cast<WebCore::HTMLSelectElement*>(nodePtr); - const WTF::Vector<WebCore::HTMLElement*>& listItems = select->listItems(); - SkTDArray<const uint16_t*> names; - SkTDArray<int> enabledArray; - SkTDArray<int> selectedArray; - int size = listItems.size(); - bool multiple = select->multiple(); - for (int i = 0; i < size; i++) { - if (listItems[i]->hasTagName(WebCore::HTMLNames::optionTag)) { - WebCore::HTMLOptionElement* option = static_cast<WebCore::HTMLOptionElement*>(listItems[i]); - *names.append() = stringConverter(option->optionText()); - *enabledArray.append() = option->disabled() ? 0 : 1; - if (multiple && option->selected()) - *selectedArray.append() = i; - } else if (listItems[i]->hasTagName(WebCore::HTMLNames::optgroupTag)) { - WebCore::HTMLOptGroupElement* optGroup = static_cast<WebCore::HTMLOptGroupElement*>(listItems[i]); - *names.append() = stringConverter(optGroup->groupLabelText()); - *enabledArray.append() = 0; - if (multiple) - *selectedArray.append() = 0; - } - } - WebCoreReply* reply = new ListBoxReply(select, select->document()->frame(), this); - listBoxRequest(reply, names.begin(), size, enabledArray.begin(), enabledArray.count(), - multiple, selectedArray.begin(), multiple ? selectedArray.count() : - select->optionToListIndex(select->selectedIndex())); - return true; - } - } - if (NULL == framePtr) - framePtr = mFrame; - bridge->setInKeyHandler(true); - DBG_NAV_LOGD("mMousePos={%d,%d}", mMousePos.x(), mMousePos.y()); - WebCore::PlatformMouseEvent mouseDown(mMousePos, mMousePos, WebCore::LeftButton, - WebCore::MouseEventPressed, 1, false, false, false, false, - WebCore::currentTime()); - // ignore the return from as it will return true if the hit point can trigger selection change - framePtr->eventHandler()->handleMousePressEvent(mouseDown); - WebCore::PlatformMouseEvent mouseUp(mMousePos, mMousePos, WebCore::LeftButton, - WebCore::MouseEventReleased, 1, false, false, false, false, - WebCore::currentTime()); - bool handled = framePtr->eventHandler()->handleMouseReleaseEvent(mouseUp); - bridge->setInKeyHandler(false); - return handled; -} - -void WebViewCore::popupReply(int index) -{ - if (mPopupReply) { - mPopupReply->replyInt(index); - Release(mPopupReply); - mPopupReply = NULL; - } -} - -void WebViewCore::popupReply(SkTDArray<int> array) { - if (mPopupReply) { - mPopupReply->replyIntArray(array); - Release(mPopupReply); - mPopupReply = NULL; - } -} - -void WebViewCore::jsAlert(const WebCore::String& url, const WebCore::String& text) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length()); - jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mJsAlert, jUrlStr, jInputStr); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); -} - -bool WebViewCore::jsConfirm(const WebCore::String& url, const WebCore::String& text) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length()); - jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - jboolean result = env->CallBooleanMethod(mJavaGlue->mObj, mJavaGlue->mJsConfirm, jUrlStr, jInputStr); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); - return result; -} - -bool WebViewCore::jsPrompt(const WebCore::String& url, const WebCore::String& text, const WebCore::String& defaultValue, WebCore::String& result) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length()); - jstring jDefaultStr = env->NewString((unsigned short *)defaultValue.characters(), defaultValue.length()); - jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - jstring returnVal = (jstring) env->CallObjectMethod(mJavaGlue->mObj, mJavaGlue->mJsPrompt, jUrlStr, jInputStr, jDefaultStr); - // If returnVal is null, it means that the user cancelled the dialog. - if (!returnVal) - return false; - - const jchar* outputChars = env->GetStringChars(returnVal, NULL); - if (outputChars == NULL) { - result = WebCore::String(); - } else { - result = WebCore::String((const UChar*) outputChars, env->GetStringLength(returnVal)); - } - env->ReleaseStringChars(returnVal, outputChars); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jDefaultStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); - return true; -} - -bool WebViewCore::jsUnload(const WebCore::String& url, const WebCore::String& message) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - jstring jInputStr = env->NewString((unsigned short *)message.characters(), message.length()); - jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - jboolean result = env->CallBooleanMethod(mJavaGlue->mObj, mJavaGlue->mJsUnload, jUrlStr, jInputStr); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); - return result; -} - -WebCoreViewBridge* -WebViewCore::createBridgeForView(WebCore::FrameView* view) -{ - SkASSERT(view); - WebViewCore* viewBridge = new WebViewCore(javavm_to_jnienv(mJavaGlue->mJVM), mJavaGlue->mObj, view); - WebCore::IntRect r = getBounds(); - viewBridge->setBounds(r.x(), r.y(), r.right(), r.bottom()); - return viewBridge; -} - -jobject -WebViewCore::getJavaObject() -{ - return mJavaGlue->mObj; -} - -jobject -WebViewCore::getWebViewJavaObject() -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - return env->GetObjectField(mJavaGlue->mObj, gWebViewCoreFields.mWebView); -} - -void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword, - const WebCore::String& text) -{ - if (mBlockTextfieldUpdates) - return; - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - if (changeToPassword) { - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mUpdateTextfield, - (int) ptr, true, NULL, mTextGeneration); - checkException(env); - return; - } - int length = text.length(); - jstring string = env->NewString((unsigned short *) text.characters(), length); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mUpdateTextfield, - (int) ptr, false, string, mTextGeneration); - env->DeleteLocalRef(string); - checkException(env); -} - -void WebViewCore::setSnapAnchor(int x, int y) -{ - mSnapAnchorNode = NULL; - if (x == 0 && y == 0) { - return; - } - - WebCore::IntPoint point = WebCore::IntPoint(x, y); - WebCore::Node* node = mFrame->eventHandler()->hitTestResultAtPoint(point, false).innerNode(); - if (node) { -// LOGD("found focus node name: %s, type %d\n", node->nodeName().utf8().data(), node->nodeType()); - while (node) { - if (node->hasTagName(WebCore::HTMLNames::divTag) || - node->hasTagName(WebCore::HTMLNames::tableTag)) { - mSnapAnchorNode = node; - return; - } -// LOGD("parent node name: %s, type %d\n", node->nodeName().utf8().data(), node->nodeType()); - node = node->parentNode(); - } - } -} - -void WebViewCore::snapToAnchor() -{ - if (mSnapAnchorNode) { - if (mSnapAnchorNode->inDocument()) { - int rx, ry; - mSnapAnchorNode->renderer()->absolutePosition(rx, ry); - scrollTo(rx, ry); - } else { - mSnapAnchorNode = NULL; - } - } -} - -void WebViewCore::setBackgroundColor(SkColor c) -{ - WebCore::FrameView* view = mFrame->view(); - if (view == NULL) - return; - WebCore::Color bcolor(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), - SkColorGetA(c)); - view->setBaseBackgroundColor(bcolor); -} - -//---------------------------------------------------------------------- -// Native JNI methods -//---------------------------------------------------------------------- -static jstring WebCoreStringToJString(JNIEnv *env, WebCore::String string) -{ - int length = string.length(); - if (0 == length) - return 0; - jstring ret = env->NewString((jchar *)string.characters(), length); - env->DeleteLocalRef(ret); - return ret; -} - -void WebViewCore::SetSize(JNIEnv *env, jobject obj, jint width, jint height, - jint screenWidth, jfloat scale) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOGV("webviewcore::nativeSetSize(%u %u)\n viewImpl: %p", (unsigned)width, (unsigned)height, viewImpl); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSetSize"); - // convert the scale to an int - int s = (int) (scale * 100); - // a negative value indicates that we should not change the scale - if (scale < 0) - s = viewImpl->scale(); - - viewImpl->setSizeScreenWidthAndScale(width, height, screenWidth, s); -} - -void WebViewCore::SetVisibleRect(JNIEnv *env, jobject obj, - jint x, jint y, jint width, jint height) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "need viewImpl"); - - viewImpl->setVisibleRect(WebCore::IntRect(x, y, width, height)); -} - -jboolean WebViewCore::KeyUp(JNIEnv *env, jobject obj, jint key, jint val) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif -// LOGV("webviewcore::nativeKeyUp(%u)\n", (unsigned)key); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeKeyUp"); - return viewImpl->keyUp((KeyCode)key, val); -} - -void WebViewCore::DeleteSelection(JNIEnv *env, jobject obj, - jint frame, jint node, jint x, jint y, jint start, jint end) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - LOGV("webviewcore::nativeDeleteSelection()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeDeleteSelection"); - viewImpl->deleteSelection((WebCore::Frame*) frame, (WebCore::Node*) node, - x, y, start, end); -} - -void WebViewCore::SetSelection(JNIEnv *env, jobject obj, - jint frame, jint node, jint x, jint y, jint start, jint end) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - LOGV("webviewcore::nativeSetSelection()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeDeleteSelection"); - viewImpl->setSelection((WebCore::Frame*) frame, (WebCore::Node*) node, - x, y, start, end); -} - - -void WebViewCore::ReplaceTextfieldText(JNIEnv *env, jobject obj, - jint framePtr, jint nodePtr, jint x, jint y, jint oldStart, jint oldEnd, - jstring replace, jint start, jint end) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - LOGV("webviewcore::nativeReplaceTextfieldText()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeReplaceTextfieldText"); - viewImpl->replaceTextfieldText((WebCore::Frame*) framePtr, (WebCore::Node*) nodePtr, x, y, oldStart, - oldEnd, replace, start, end); -} - -void WebViewCore::PassToJs(JNIEnv *env, jobject obj, jint frame, jint node, - jint x, jint y, jint generation, jstring currentText, jint keyCode, - jint keyValue, jboolean down, jboolean cap, jboolean fn, jboolean sym) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - LOGV("webviewcore::nativePassToJs()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativePassToJs"); - viewImpl->passToJs((WebCore::Frame*) frame, (WebCore::Node*) node, - x, y, generation, currentText, keyCode, keyValue, down, cap, fn, sym); -} - -void WebViewCore::SaveDocumentState(JNIEnv *env, jobject obj, jint frame, jint node, jint x, jint y) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - LOGV("webviewcore::nativeSaveDocumentState()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSaveDocumentState"); - viewImpl->saveDocumentState((WebCore::Frame*) frame, (WebCore::Node*) node, x, y); -} - -void WebViewCore::Draw(JNIEnv *env, jobject obj, jobject contentPict) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeDraw"); - LOG_ASSERT(contentPict, "need a valid java picture for nativeDraw"); - SkPicture* picture = GraphicsJNI::getNativePicture(env, contentPict); - LOG_ASSERT(picture, "need native picture in nativeDraw"); - viewImpl->recordPicture(picture, true); -} - -void WebViewCore::SendListBoxChoice(JNIEnv* env, jobject obj, jint choice) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSendListBoxChoice"); - viewImpl->popupReply(choice); -} - -void WebViewCore::SendListBoxChoices(JNIEnv* env, jobject obj, jbooleanArray jArray, jint size) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSendListBoxChoices"); - jboolean* ptrArray = env->GetBooleanArrayElements(jArray, NULL); - SkTDArray<int> array; - for (int i = 0; i < size; i++) { - if (ptrArray[i]) { - *array.append() = i; - } - } - viewImpl->popupReply(array); -} - -void WebViewCore::ClearMatches(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeClearMatches"); - - WebCore::Frame* frame = viewImpl->frame(); - while (frame) { - if (frame->document()) - frame->document()->removeMarkers(); - WebCore::SelectionController* controller = frame->selectionController(); - if (controller->isRange()) { - WebCore::Position pos = controller->start(); - WebCore::Position end = controller->end(); - do { - if (pos.inRenderedText()) { - WebCore::RenderObject* renderer = pos.node()->renderer(); - if (renderer != NULL) { - renderer->setSelectionState(WebCore::RenderObject::SelectionNone); - } - } - pos = pos.next(); - } while (pos != end); - controller->clear(); - } - frame = frame->tree()->traverseNext(); - } -} - -jboolean WebViewCore::Find(JNIEnv *env, jobject obj, jstring find, - jboolean forward, jboolean fromSelection) { - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeFind"); - - if (NULL == find) - return false; - int length = env->GetStringLength(find); - if (0 == length) - return false; // perhaps we want to return true, in order to show the correct dialog - const jchar* findChars = env->GetStringChars(find, NULL); - // Will this ever return NULL if find is not NULL and its length is not zero? - if (NULL == findChars) - return false; - WebCore::String findString = WebCore::String((const UChar*) findChars, length); - env->ReleaseStringChars(find, findChars); - WebCore::Frame* mainFrame = viewImpl->frame(); - WebCore::Frame* frame = mainFrame; - bool found = false; - if (fromSelection) { - // Need to figure out which frame has a selection, then start from there - while (frame && frame->selectionController()->isNone()) { - frame = frame->tree()->traverseNext(); - } - if (!frame) { - // No selection, so start from the beginning. - frame = mainFrame; - } - // Now we have the frame with the selection. - WebCore::Frame* starterFrame = frame; - bool firstTimeThroughLoop = true; - if (forward) { - while (!(found = frame->findString(findString, true, false, false, true))) { - if (firstTimeThroughLoop) { - firstTimeThroughLoop = false; - // FIXME: Clearing the selection is necessary for the search to - // work properly. However, the invalidation does not remove - // the drawn rectangle from old frames. - frame->selectionController()->clear(); - } - frame = frame->tree()->traverseNextWithWrap(true); - if (frame == starterFrame) - break; - } - } else { - // Search backwards, searching the frames in reverse order as well. - while (!(found = frame->findString(findString, false, false, false, true))) { - if (firstTimeThroughLoop) { - firstTimeThroughLoop = false; - frame->selectionController()->clear(); - } - frame = frame->tree()->traversePreviousWithWrap(true); - if (frame == starterFrame) - break; - } - } - // In order to wrap to the beginning of the initial frame. - if (!found) { - found = frame->findString(findString, forward, false, false, true); - } - } else { - // Clear any old selections so find will work properly. - while (frame) { - frame->selectionController()->clear(); - frame->invalidateSelection(); - frame = frame->tree()->traverseNext(); - } - frame = mainFrame; - do { - found = frame->findString(findString, forward, false, false, false); - } while (!found && (frame = frame->tree()->traverseNext()) != NULL); - } - if (found) { - frame->view()->scrollRectIntoViewRecursively(frame->selectionController()->caretRect()); - return true; - } - return false; -} - -jstring WebViewCore::FindAddress(JNIEnv *env, jobject obj, jstring addr) -{ - if (NULL == addr) - return NULL; - int length = env->GetStringLength(addr); - if (0 == length) - return NULL; - const jchar* addrChars = env->GetStringChars(addr, NULL); - int start, end; - bool success = WebCore::CacheBuilder::FindAddress(addrChars, length, - &start, &end) == WebCore::CacheBuilder::FOUND_COMPLETE; - jstring ret = NULL; - if (success) { - ret = env->NewString((jchar*) addrChars + start, end - start); - env->DeleteLocalRef(ret); - } - env->ReleaseStringChars(addr, addrChars); - return ret; -} - -jint WebViewCore::FindAll(JNIEnv *env, jobject obj, jstring find) { - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeFindAll"); - if (NULL == find) - return 0; - int length = env->GetStringLength(find); - if (0 == length) - return 0; - const jchar* findChars = env->GetStringChars(find, NULL); - // Will this ever return NULL if find is not NULL and its length is not zero? - if (NULL == findChars) - return 0; - WebCore::String findString = WebCore::String((const UChar*) findChars, length); - env->ReleaseStringChars(find, findChars); - WebCore::Frame* frame = viewImpl->frame(); - int numFound = 0; - ClearMatches(env, obj); - while (frame) { - frame->selectionController()->clear(); - frame->invalidateSelection(); - if (frame->document()) - frame->document()->removeMarkers(); - frame->setMarkedTextMatchesAreHighlighted(true); - numFound += frame->markAllMatchesForText(findString, false, 0); - frame = frame->tree()->traverseNext(); - } - if (numFound > 0) - Find(env, obj, find, true, false); - return numFound; -} - -void WebViewCore::TouchUp(JNIEnv *env, jobject obj, jint touchGeneration, - jint buildGeneration, jint frame, jint node, jint x, jint y, jint size, - jboolean isClick, jboolean retry) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->touchUp(touchGeneration, buildGeneration, - (WebCore::Frame*) frame, (WebCore::Node*) node, x, y, size, isClick, retry); -} - -jstring WebViewCore::RetrieveHref(JNIEnv *env, jobject obj, jint frame, - jint node) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - WebCore::String result = viewImpl->retrieveHref((WebCore::Frame*) frame, - (WebCore::Node*) node); - if (!result.isEmpty()) - return WebCoreStringToJString(env, result); - return NULL; -} - -jstring WebViewCore::RetrieveImageRef(JNIEnv *env, jobject obj, jint x, jint y) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - WebCore::String result = viewImpl->retrieveImageRef(x, y); - if (!result.isEmpty()) - return WebCoreStringToJString(env, result); - return NULL; -} - -void WebViewCore::SetFinalFocus(JNIEnv *env, jobject obj, jint frame, jint node, - jint x, jint y, jboolean block) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->setFinalFocus((WebCore::Frame*) frame, (WebCore::Node*) node, x, - y, block); -} - -void WebViewCore::SetKitFocus(JNIEnv *env, jobject obj, jint moveGeneration, - jint buildGeneration, jint frame, jint node, jint x, jint y, - jboolean ignoreNullFocus) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->setKitFocus(moveGeneration, buildGeneration, - (WebCore::Frame*) frame, (WebCore::Node*) node, x, y, - ignoreNullFocus); -} - -void WebViewCore::UnblockFocus(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->unblockFocus(); -} - -void WebViewCore::UpdateFrameCache(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->updateFrameCache(); -} - -jint WebViewCore::GetContentMinPrefWidth(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - WebCore::Frame* frame = viewImpl->frame(); - if (frame) { - WebCore::Document* document = frame->document(); - if (document) { - WebCore::RenderObject* renderer = document->renderer(); - if (renderer && renderer->isRenderView()) { - return renderer->minPrefWidth(); - } - } - } - return 0; -} - -void WebViewCore::SetViewportSettingsFromNative(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - WebCore::Settings* s = viewImpl->frame()->page()->settings(); - if (s == NULL) - return; - - env->SetIntField(obj, gWebViewCoreFields.mViewportWidth, s->viewportWidth()); - env->SetIntField(obj, gWebViewCoreFields.mViewportHeight, s->viewportHeight()); - env->SetIntField(obj, gWebViewCoreFields.mViewportInitialScale, s->viewportInitialScale()); - env->SetIntField(obj, gWebViewCoreFields.mViewportMinimumScale, s->viewportMinimumScale()); - env->SetIntField(obj, gWebViewCoreFields.mViewportMaximumScale, s->viewportMaximumScale()); - env->SetBooleanField(obj, gWebViewCoreFields.mViewportUserScalable, s->viewportUserScalable()); -} - -void WebViewCore::SetSnapAnchor(JNIEnv *env, jobject obj, jint x, jint y) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->setSnapAnchor(x, y); -} - -void WebViewCore::SnapToAnchor(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->snapToAnchor(); -} - -void WebViewCore::SetBackgroundColor(JNIEnv *env, jobject obj, jint color) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->setBackgroundColor((SkColor) color); -} - -static void jrect_to_skirect(JNIEnv* env, jobject obj, SkIRect* result) -{ - int L, T, R, B; - GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B); - result->set(L, T, R, B); -} - -jstring WebViewCore::GetSelection(JNIEnv *env, jobject obj, jobject selRgn) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - SkRegion* selectionRegion = GraphicsJNI::getNativeRegion(env, selRgn); - WebCore::String result = viewImpl->getSelection(selectionRegion); - if (!result.isEmpty()) - return WebCoreStringToJString(env, result); - return NULL; -} - -void WebViewCore::Dump(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->dump(); -} - -void WebViewCore::RefreshPlugins(JNIEnv *env, - jobject obj, - jboolean reloadOpenPages) -{ - // Refresh the list of plugins, optionally reloading all open - // pages. - WebCore::refreshPlugins(reloadOpenPages); -} - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gJavaWebViewCoreMethods[] = { - { "nativeClearMatches", "()V", - (void*) WebViewCore::ClearMatches } , - { "nativeDraw", "(Landroid/graphics/Picture;)V", - (void*) WebViewCore::Draw }, - { "nativeKeyUp", "(II)Z", - (void*) WebViewCore::KeyUp }, - { "nativeSendListBoxChoices", "([ZI)V", - (void*) WebViewCore::SendListBoxChoices }, - { "nativeSendListBoxChoice", "(I)V", - (void*) WebViewCore::SendListBoxChoice }, - { "nativeSetSize", "(IIIF)V", - (void*) WebViewCore::SetSize }, - { "nativeSetVisibleRect", "(IIII)V", - (void*) WebViewCore::SetVisibleRect }, - { "nativeSetSelection", "(IIIIII)V", - (void*) WebViewCore::SetSelection } , - { "nativeDeleteSelection", "(IIIIII)V", - (void*) WebViewCore::DeleteSelection } , - { "nativeReplaceTextfieldText", "(IIIIIILjava/lang/String;II)V", - (void*) WebViewCore::ReplaceTextfieldText } , - { "passToJs", "(IIIIILjava/lang/String;IIZZZZ)V", - (void*) WebViewCore::PassToJs } , - { "nativeSaveDocumentState", "(IIII)V", - (void*) WebViewCore::SaveDocumentState }, - { "nativeFind", "(Ljava/lang/String;ZZ)Z", - (void*) WebViewCore::Find } , - { "nativeFindAddress", "(Ljava/lang/String;)Ljava/lang/String;", - (void*) WebViewCore::FindAddress }, - { "nativeFindAll", "(Ljava/lang/String;)I", - (void*) WebViewCore::FindAll } , - { "nativeTouchUp", "(IIIIIIIZZ)V", - (void*) WebViewCore::TouchUp }, - { "nativeRetrieveImageRef", "(II)Ljava/lang/String;", - (void*) WebViewCore::RetrieveImageRef }, - { "nativeRetrieveHref", "(II)Ljava/lang/String;", - (void*) WebViewCore::RetrieveHref }, - { "nativeSetFinalFocus", "(IIIIZ)V", - (void*) WebViewCore::SetFinalFocus }, - { "nativeSetKitFocus", "(IIIIIIZ)V", - (void*) WebViewCore::SetKitFocus }, - { "nativeUnblockFocus", "()V", - (void*) WebViewCore::UnblockFocus }, - { "nativeUpdateFrameCache", "()V", - (void*) WebViewCore::UpdateFrameCache }, - { "nativeGetContentMinPrefWidth", "()I", - (void*) WebViewCore::GetContentMinPrefWidth }, - { "setViewportSettingsFromNative", "()V", - (void*) WebViewCore::SetViewportSettingsFromNative }, - { "nativeSetSnapAnchor", "(II)V", - (void*) WebViewCore::SetSnapAnchor }, - { "nativeSnapToAnchor", "()V", - (void*) WebViewCore::SnapToAnchor }, - { "nativeSetBackgroundColor", "(I)V", - (void*) WebViewCore::SetBackgroundColor }, - { "nativeGetSelection", - "(Landroid/graphics/Region;)Ljava/lang/String;", - (void*) WebViewCore::GetSelection }, - { "nativeRefreshPlugins", "(Z)V", - (void*) WebViewCore::RefreshPlugins }, - { "nativeDump", "()V", - (void*) WebViewCore::Dump } -}; - -int register_webviewcore(JNIEnv* env) -{ - jclass widget = env->FindClass("android/webkit/WebViewCore"); - LOG_ASSERT(widget != NULL, - "Unable to find class android/webkit/WebViewCore"); - gWebViewCoreFields.mNativeClass = env->GetFieldID(widget, "mNativeClass", - "I"); - LOG_ASSERT(gWebViewCoreFields.mNativeClass != NULL, - "Unable to find android/webkit/WebViewCore.mNativeClass"); - gWebViewCoreFields.mViewportWidth = env->GetFieldID(widget, - "mViewportWidth", "I"); - LOG_ASSERT(gWebViewCoreFields.mViewportWidth != NULL, - "Unable to find android/webkit/WebViewCore.mViewportWidth"); - gWebViewCoreFields.mViewportHeight = env->GetFieldID(widget, - "mViewportHeight", "I"); - LOG_ASSERT(gWebViewCoreFields.mViewportHeight != NULL, - "Unable to find android/webkit/WebViewCore.mViewportHeight"); - gWebViewCoreFields.mViewportInitialScale = env->GetFieldID(widget, - "mViewportInitialScale", "I"); - LOG_ASSERT(gWebViewCoreFields.mViewportInitialScale != NULL, - "Unable to find android/webkit/WebViewCore.mViewportInitialScale"); - gWebViewCoreFields.mViewportMinimumScale = env->GetFieldID(widget, - "mViewportMinimumScale", "I"); - LOG_ASSERT(gWebViewCoreFields.mViewportMinimumScale != NULL, - "Unable to find android/webkit/WebViewCore.mViewportMinimumScale"); - gWebViewCoreFields.mViewportMaximumScale = env->GetFieldID(widget, - "mViewportMaximumScale", "I"); - LOG_ASSERT(gWebViewCoreFields.mViewportMaximumScale != NULL, - "Unable to find android/webkit/WebViewCore.mViewportMaximumScale"); - gWebViewCoreFields.mViewportUserScalable = env->GetFieldID(widget, - "mViewportUserScalable", "Z"); - LOG_ASSERT(gWebViewCoreFields.mViewportUserScalable != NULL, - "Unable to find android/webkit/WebViewCore.mViewportUserScalable"); - gWebViewCoreFields.mWebView = env->GetFieldID(widget, - "mWebView", "Landroid/webkit/WebView;"); - LOG_ASSERT(gWebViewCoreFields.mWebView != NULL, - "Unable to find android/webkit/WebViewCore.mWebView"); - - return jniRegisterNativeMethods(env, "android/webkit/WebViewCore", - gJavaWebViewCoreMethods, NELEM(gJavaWebViewCoreMethods)); -} - -} /* namespace android */ diff --git a/WebCore/platform/android/jni/WebViewCore.h b/WebCore/platform/android/jni/WebViewCore.h deleted file mode 100644 index 1cb51b2..0000000 --- a/WebCore/platform/android/jni/WebViewCore.h +++ /dev/null @@ -1,400 +0,0 @@ -/* - * - * Copyright 2006, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_WIDGET_HTMLWIDGET_H -#define ANDROID_WIDGET_HTMLWIDGET_H - -#include "WebCoreViewBridge.h" -#include "CacheBuilder.h" -#include "CachedHistory.h" -#include "FrameView.h" -#include "SkColor.h" -#include "SkScalar.h" -#include "SkRegion.h" -#include <ui/Rect.h> -#include <jni.h> - -namespace WebCore { - class AtomicString; - class Color; - class GraphicsContext; - class HTMLSelectElement; - class RenderPart; - class RenderText; - class FrameAndroid; - class Node; - class RenderTextControl; -} - -class SkPicture; - -namespace android { - - class CachedRoot; - - class ListBoxReply; - - class WebViewCore : public WebCoreViewBridge - { - public: - /** - * Initialize the ViewBridge with a JNI environment, a native HTMLWidget object - * and an associated frame to perform actions on. - */ - WebViewCore(JNIEnv* env, jobject javaView, WebCore::FrameView* view); - virtual ~WebViewCore(); - - /** - * Set the scroll offset. - * @param x The x position of the new scroll offset. - * @param y The y position of the new scroll offset. - */ -// void setScrollOffset(int x, int y); - - // Inherited from WebCoreViewBridge - virtual void draw(WebCore::GraphicsContext* ctx, - const WebCore::IntRect& rect, bool invalCache); - - /** - * Layout our Frame if needed and recursively layout all child frames. - */ - virtual void layout(); - - /** - * Scroll to an absolute position. - * @param x The x coordinate. - * @param y The y coordinate. - * @param animate If it is true, animate to the new scroll position - * - * This method calls Java to trigger a gradual scroll event. - */ - virtual void scrollTo(int x, int y, bool animate = false); - - /** - * Scroll to the point x,y relative to the current position. - * @param x The relative x position. - * @param y The relative y position. - */ - virtual void scrollBy(int x, int y); - - /** - * Mark the display list as invalid, and post an event (once) to - * rebuild the display list by calling webcore to draw the dom - */ - virtual void contentInvalidate(); - virtual void contentInvalidate(const WebCore::IntRect &rect); - - // invalidate the view/display, NOT the content/DOM - virtual void viewInvalidate() { sendViewInvalidate(); } - - /** - * Called by webcore when the focus was set after returning to prior page - * used to rebuild and display any changes in focus - */ - virtual void notifyFocusSet(); - /** - * Called by webcore when the progress indicator is done - * used to rebuild and display any changes in focus - */ - virtual void notifyProgressFinished(); - - /** - * On resize is called after a setSize event on WebCoreViewBridge. onResize - * then tells the frame to relayout the contents due to the size change - */ - virtual void onResize(); - - /** - * Notify the view that WebCore did its first layout. - */ - virtual void didFirstLayout(); - - /** - * Notify the view to restore the screen width, which in turn restores - * the scale. - */ - virtual void restoreScale(int); - - /* Set the view and frame */ - virtual void setView(WebCore::FrameView* view) { - if (mView) - mView->deref(); - mView = view; - if (mView) { - mView->ref(); - mFrame = (WebCore::FrameAndroid*)mView->frame(); - reset(false); - } else - mFrame = NULL; - } - - // new methods for this subclass - - void reset(bool fromConstructor); - - WebCore::FrameAndroid* frame() const { return mFrame; } - WebCore::String retrieveHref(WebCore::Frame* frame, WebCore::Node* node); - - /** - * Return the url of the image located at (x,y) in content coordinates, or - * null if there is no image at that point. - * - * @param x x content ordinate - * @param y y content ordinate - * @return WebCore::String url of the image located at (x,y), or null if there is - * no image there. - */ - WebCore::String retrieveImageRef(int x, int y); - - WebCore::String getSelection(SkRegion* ); - void recordPicture(SkPicture* picture, bool invalCache); - void setFrameCacheOutOfDate(); - void setFinalFocus(WebCore::Frame* frame, WebCore::Node* node, - int x, int y, bool block); - void setKitFocus(int moveGeneration, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus); - int getMaxXScroll() const { return mMaxXScroll; } - int getMaxYScroll() const { return mMaxYScroll; } - void setMaxXScroll(int maxx) { mMaxXScroll = maxx; } - void setMaxYScroll(int maxy) { mMaxYScroll = maxy; } - - int contentWidth() const { return mView->contentsWidth(); } - int contentHeight() const { return mView->contentsHeight(); } - - // the visible rect is in document coordinates, and describes the - // intersection of the document with the "window" in the UI. - void getVisibleRect(WebCore::IntRect* rect) const; - void setVisibleRect(const WebCore::IntRect& rect); - - WebCore::FrameView* getFrameView() { return mView; } - void listBoxRequest(WebCoreReply* reply, const uint16_t** labels, size_t count, const int enabled[], size_t enabledCount, - bool multiple, const int selected[], size_t selectedCountOrSelection); - - /** - * Handle keyDown events from Java. - * @param keyCode The key pressed. - * @return Whether keyCode was handled by this class. - */ - bool keyUp(KeyCode keyCode, int keyValue); - - /** - * Handle motionUp event from the UI thread (called touchUp in the - * WebCore thread). - */ - void touchUp(int touchGeneration, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - int size, bool isClick, bool retry); - - /** - * Return a new WebCoreViewBridge to interface with the passed in view. - */ - virtual WebCoreViewBridge* createBridgeForView(WebCore::FrameView* view); - - /** - * Sets the index of the label from a popup - */ - void popupReply(int index); - void popupReply(SkTDArray<int>array); - - virtual void jsAlert(const WebCore::String& url, const WebCore::String& text); - virtual bool jsConfirm(const WebCore::String& url, const WebCore::String& text); - virtual bool jsPrompt(const WebCore::String& url, const WebCore::String& message, const WebCore::String& defaultValue, WebCore::String& result); - virtual bool jsUnload(const WebCore::String& url, const WebCore::String& message); - - /** - * Delete text from start to end in the focused textfield. If there is no - * focus, or if start == end, silently fail, but set selection to that value. - * If start and end are out of order, swap them. - * Use the frame, node, x, and y to ensure that the correct node is focused. - * Return a frame. Convenience so replaceTextfieldText can use this function. - */ - WebCore::Frame* deleteSelection(WebCore::Frame* frame, WebCore::Node* node, int x, - int y,int start, int end); - - /** - * Set the selection of the currently focused textfield to (start, end). - * If start and end are out of order, swap them. - * Use the frame, node, x, and y to ensure that the correct node is focused. - * Return a frame. Convenience so deleteSelection can use this function. - */ - WebCore::Frame* setSelection(WebCore::Frame* frame, WebCore::Node* node, int x, - int y,int start, int end); - /** - * In the currenlty focused textfield, represented by frame, node, x, and y (which - * are used to ensure it has focus), replace the characters from oldStart to oldEnd - * (if oldStart == oldEnd, this will be an insert at that position) with replace, - * and set the selection to (start, end). - */ - void replaceTextfieldText(WebCore::Frame* frame, WebCore::Node* node, int x, int y, - int oldStart, int oldEnd, jstring replace, int start, int end); - void passToJs(WebCore::Frame* frame, WebCore::Node* node, int x, int y, int generation, - jstring currentText, int jKeyCode, int keyVal, bool down, bool cap, bool fn, bool sym); - - void saveDocumentState(WebCore::Frame* frame, WebCore::Node* node, int x, int y); - - // TODO: I don't like this hack but I need to access the java object in - // order to send it as a parameter to java - jobject getJavaObject(); - - // Return the parent WebView Java object associated with this - // WebViewCore. - jobject getWebViewJavaObject(); - - bool pinXToDocument(int* yPtr); - bool pinYToDocument(int* yPtr); - - WebCore::RenderLayer* getRenderLayer(); - - /** - * Tell the java side to update the focused textfield - * @param pointer Pointer to the node for the input field. - * @param changeToPassword If true, we are changing the textfield to - * a password field, and ignore the String - * @param text If changeToPassword is false, this is the new text that - * should go into the textfield. - */ - virtual void updateTextfield(WebCore::Node* pointer, - bool changeToPassword, const WebCore::String& text); - - virtual void removeFrameGeneration(WebCore::Frame* ); - virtual void updateFrameGeneration(WebCore::Frame* ); - - void setBackgroundColor(SkColor c); - void setSnapAnchor(int x, int y); - void snapToAnchor(); - void unblockFocus() { mBlockFocusChange = false; } - void updateFrameCache(); - void dump(); - - // jni methods - static void Destroy(JNIEnv*, jobject); - static void Dump(JNIEnv*, jobject); - static void RefreshPlugins(JNIEnv*, jobject, jboolean); - static void SetSize(JNIEnv*, jobject, jint, jint, jint, jfloat); - static void SetVisibleRect(JNIEnv*, jobject, jint, jint, jint, jint); - static jboolean KeyUp(JNIEnv*, jobject, jint, jint); - static void DeleteSelection(JNIEnv*, jobject, jint, jint, jint, jint, - jint, jint); - static void SetSelection(JNIEnv*, jobject, jint, jint, jint, jint, - jint, jint); - static void ReplaceTextfieldText(JNIEnv*, jobject, jint, jint, jint, - jint, jint, jint, jstring, jint, jint); - static void PassToJs(JNIEnv*, jobject, jint, jint, jint, jint, jint, - jstring, jint, jint, jboolean, jboolean, jboolean, jboolean); - static void SaveDocumentState(JNIEnv*, jobject, jint, jint, jint, jint); - static void Draw(JNIEnv*, jobject, jobject); - static void SendListBoxChoices(JNIEnv*, jobject, jbooleanArray, jint); - static void SendListBoxChoice(JNIEnv* env, jobject obj, jint choice); - static void ClearMatches(JNIEnv*, jobject); - static jboolean Find(JNIEnv*, jobject, jstring, jboolean, jboolean); - static jstring FindAddress(JNIEnv*, jobject, jstring); - static jint FindAll(JNIEnv*, jobject, jstring); - static void TouchUp(JNIEnv*, jobject, jint, jint, jint, jint, jint, - jint, jint, jboolean, jboolean); - static jstring RetrieveHref(JNIEnv*, jobject, jint, jint); - static jstring RetrieveImageRef(JNIEnv*, jobject, jint, jint); - static void SetFinalFocus(JNIEnv*, jobject, jint, jint, jint, jint, - jboolean); - static void SetKitFocus(JNIEnv*, jobject, jint, jint, jint, jint, jint, - jint, jboolean); - static void UnblockFocus(JNIEnv*, jobject); - static void UpdateFrameCache(JNIEnv*, jobject); - static jint GetContentMinPrefWidth(JNIEnv*, jobject); - static void SetViewportSettingsFromNative(JNIEnv*, jobject); - static void SetBackgroundColor(JNIEnv *env, jobject obj, jint color); - static void SetSnapAnchor(JNIEnv*, jobject, jint, jint); - static void SnapToAnchor(JNIEnv*, jobject); - static jstring GetSelection(JNIEnv*, jobject, jobject); - // end jni methods - - // these members are shared with webview.cpp - int retrieveFrameGeneration(WebCore::Frame* ); - static Mutex gFrameCacheMutex; - CachedRoot* mFrameCacheKit; // nav data being built by webcore - SkPicture* mNavPictureKit; - int mGeneration; // copy of the number bumped by WebViewNative - int mMoveGeneration; // copy of state in WebViewNative triggered by move - int mTouchGeneration; // copy of state in WebViewNative triggered by touch - int mLastGeneration; // last action using up to date cache - bool mUpdatedFrameCache; - bool mUseReplay; - static Mutex gRecomputeFocusMutex; - WTF::Vector<int> mRecomputeEvents; - // These two fields go together: we use the mutex to protect access to - // mButtons, so that we, and webview.cpp can look/modify the mButtons - // field safely from our respective threads - static Mutex gButtonMutex; - SkTDArray<Container*>* mButtons; - // end of shared members - private: - friend class ListBoxReply; - struct FrameGen { - const WebCore::Frame* mFrame; - int mGeneration; - }; - WTF::Vector<FrameGen> mFrameGenerations; - static Mutex gFrameGenerationMutex; - struct JavaGlue; - struct JavaGlue* mJavaGlue; - WebCore::FrameView* mView; - WebCore::FrameAndroid* mFrame; - WebCoreReply* mPopupReply; - WebCore::Node* mLastFocused; - WebCore::IntRect mLastFocusedBounds; - // Used in passToJS to avoid updating the UI text field until after the - // key event has been processed. - bool mBlockTextfieldUpdates; - // Passed in with key events to know when they were generated. Store it - // with the cache so that we can ignore stale text changes. - int mTextGeneration; - CachedRoot* mTemp; - SkPicture* mTempPict; - int mBuildGeneration; - int mMaxXScroll; - int mMaxYScroll; - WebCore::IntRect mVisibleRect; - WebCore::IntPoint mMousePos; - bool mFrameCacheOutOfDate; - bool mBlockFocusChange; - int mLastPassed; - int mLastVelocity; - CachedHistory mHistory; - WebCore::Node* mSnapAnchorNode; - WebCore::Frame* changedKitFocus(WebCore::Frame* frame, - WebCore::Node* node, int x, int y); - bool commonKitFocus(int generation, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus); - bool finalKitFocus(WebCore::Frame* frame, WebCore::Node* node, int x, int y); - void doMaxScroll(WebCore::CacheBuilder::Direction dir); - void sendMarkNodeInvalid(WebCore::Node* ); - void sendNotifyFocusSet(); - void sendNotifyProgressFinished(); - void sendRecomputeFocus(); - void sendViewInvalidate(); - bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr); - bool prepareFrameCache(); - void releaseFrameCache(bool newCache); -#if DEBUG_NAV_UI - uint32_t mNow; -#endif - }; - -} // namespace android - -#endif // ANDROID_WIDGET_HTMLWIDGET_H |