diff options
Diffstat (limited to 'WebKit/android/jni')
-rwxr-xr-x | WebKit/android/jni/MockGeolocation.cpp | 96 | ||||
-rw-r--r-- | WebKit/android/jni/WebCoreFrameBridge.cpp | 3 | ||||
-rw-r--r-- | WebKit/android/jni/WebCoreJniOnLoad.cpp | 4 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 79 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.h | 13 |
5 files changed, 182 insertions, 13 deletions
diff --git a/WebKit/android/jni/MockGeolocation.cpp b/WebKit/android/jni/MockGeolocation.cpp new file mode 100755 index 0000000..2f6ca60 --- /dev/null +++ b/WebKit/android/jni/MockGeolocation.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2009, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// The functions in this file are used to configure the mock GeolocationService +// for the LayoutTests. + +#include "config.h" + +#include <JNIHelp.h> +#include "Coordinates.h" +#include "GeolocationService.h" +#include "Geoposition.h" +#include "JavaSharedClient.h" +#include "jni_utility.h" +#include "PositionError.h" +#include "WebCoreJni.h" +#include <wtf/CurrentTime.h> + +using namespace WebCore; + +namespace android { + +static const char* javaMockGeolocationClass = "android/webkit/MockGeolocation"; + +static void setPosition(JNIEnv* env, jobject, double latitude, double longitude, double accuracy) +{ + RefPtr<Coordinates> coordinates = Coordinates::create(latitude, + longitude, + false, 0.0, // altitude, + accuracy, + false, 0.0, // altitudeAccuracy, + false, 0.0, // heading + false, 0.0); // speed + RefPtr<Geoposition> position = Geoposition::create(coordinates.release(), WTF::currentTime()); + GeolocationService::setMockPosition(position.release()); +} + +static void setError(JNIEnv* env, jobject, int code, jstring message) +{ + PositionError::ErrorCode codeEnum; + switch (code) { + case PositionError::UNKNOWN_ERROR: + codeEnum = PositionError::UNKNOWN_ERROR; + break; + case PositionError::PERMISSION_DENIED: + codeEnum = PositionError::PERMISSION_DENIED; + break; + case PositionError::POSITION_UNAVAILABLE: + codeEnum = PositionError::POSITION_UNAVAILABLE; + break; + case PositionError::TIMEOUT: + codeEnum = PositionError::TIMEOUT; + break; + default: + ASSERT(false); + } + String messageString = to_string(env, message); + RefPtr<PositionError> error = PositionError::create(codeEnum, messageString); + GeolocationService::setMockError(error.release()); +} + +static JNINativeMethod gMockGeolocationMethods[] = { + { "nativeSetPosition", "(DDD)V", (void*) setPosition }, + { "nativeSetError", "(ILjava/lang/String;)V", (void*) setError } +}; + +int register_mock_geolocation(JNIEnv* env) +{ + jclass mockGeolocation = env->FindClass(javaMockGeolocationClass); + LOG_ASSERT(mockGeolocation, "Unable to find class"); + return jniRegisterNativeMethods(env, javaMockGeolocationClass, gMockGeolocationMethods, NELEM(gMockGeolocationMethods)); +} + +} diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp index d042c92..17b908d 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.cpp +++ b/WebKit/android/jni/WebCoreFrameBridge.cpp @@ -1137,6 +1137,9 @@ static void ClearCache(JNIEnv *env, jobject obj) #if USE(JSC) // force JavaScript to GC when clear cache WebCore::gcController().garbageCollectSoon(); +#elif USE(V8) + WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); + pFrame->script()->collectGarbage(); #endif // USE(JSC) } diff --git a/WebKit/android/jni/WebCoreJniOnLoad.cpp b/WebKit/android/jni/WebCoreJniOnLoad.cpp index 3a29f43..25afc61 100644 --- a/WebKit/android/jni/WebCoreJniOnLoad.cpp +++ b/WebKit/android/jni/WebCoreJniOnLoad.cpp @@ -45,6 +45,7 @@ extern int register_webcorejni(JNIEnv*); extern int register_webstorage(JNIEnv*); #endif extern int register_geolocation_permissions(JNIEnv*); +extern int register_mock_geolocation(JNIEnv*); } @@ -66,7 +67,8 @@ static RegistrationMethod gWebCoreRegMethods[] = { { "WebStorage", android::register_webstorage }, #endif { "WebView", android::register_webview }, - { "GeolocationPermissions", android::register_geolocation_permissions } + { "GeolocationPermissions", android::register_geolocation_permissions }, + { "MockGeolocation", android::register_mock_geolocation } }; EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index 8e56fcc..3ede30a 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -171,6 +171,7 @@ struct WebViewCore::JavaGlue { jmethodID m_sendNotifyProgressFinished; jmethodID m_sendViewInvalidate; jmethodID m_updateTextfield; + jmethodID m_updateTextSelection; jmethodID m_clearTextEntry; jmethodID m_restoreScale; jmethodID m_restoreScreenWidthScale; @@ -244,6 +245,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_sendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V"); m_javaGlue->m_sendViewInvalidate = GetJMethod(env, clazz, "sendViewInvalidate", "(IIII)V"); m_javaGlue->m_updateTextfield = GetJMethod(env, clazz, "updateTextfield", "(IZLjava/lang/String;I)V"); + m_javaGlue->m_updateTextSelection = GetJMethod(env, clazz, "updateTextSelection", "(IIII)V"); m_javaGlue->m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V"); m_javaGlue->m_restoreScale = GetJMethod(env, clazz, "restoreScale", "(I)V"); m_javaGlue->m_restoreScreenWidthScale = GetJMethod(env, clazz, "restoreScreenWidthScale", "(I)V"); @@ -438,7 +440,7 @@ void WebViewCore::recordPictureSet(PictureSet* content) // If the frame doesn't have an owner then it is the top frame and the // view size is the frame size. WebCore::RenderPart* owner = frame->ownerRenderer(); - if (owner) { + if (owner && owner->style()->visibility() == VISIBLE) { int x = owner->x(); int y = owner->y(); @@ -1086,7 +1088,7 @@ void WebViewCore::updateCacheOnNodeChange() return; if (CacheBuilder::validNode(m_mainFrame, frame, node)) { RenderObject* renderer = node->renderer(); - if (renderer) { + if (renderer && renderer->style()->visibility() != HIDDEN) { IntRect absBox = renderer->absoluteBoundingBoxRect(); int globalX, globalY; CacheBuilder::GetGlobalOffset(frame, &globalX, &globalY); @@ -1499,7 +1501,13 @@ void WebViewCore::setSelection(int start, int end) start = end; end = temp; } + // Tell our EditorClient that this change was generated from the UI, so it + // does not need to echo it to the UI. + EditorClientAndroid* client = static_cast<EditorClientAndroid*>( + m_mainFrame->editor()->client()); + client->setUiGeneratedSelectionChange(true); rtc->setSelectionRange(start, end); + client->setUiGeneratedSelectionChange(false); focus->document()->frame()->revealSelection(); setFocusControllerActive(true); } @@ -1524,8 +1532,14 @@ void WebViewCore::replaceTextfieldText(int oldStart, if (!focus) return; setSelection(oldStart, oldEnd); + // Prevent our editor client from passing a message to change the + // selection. + EditorClientAndroid* client = static_cast<EditorClientAndroid*>( + m_mainFrame->editor()->client()); + client->setUiGeneratedSelectionChange(true); WebCore::TypingCommand::insertText(focus->document(), replace, false); + client->setUiGeneratedSelectionChange(false); setSelection(start, end); m_textGeneration = textGeneration; } @@ -1547,7 +1561,13 @@ void WebViewCore::passToJs(int generation, const WebCore::String& current, } // Block text field updates during a key press. m_blockTextfieldUpdates = true; + // Also prevent our editor client from passing a message to change the + // selection. + EditorClientAndroid* client = static_cast<EditorClientAndroid*>( + m_mainFrame->editor()->client()); + client->setUiGeneratedSelectionChange(true); key(event); + client->setUiGeneratedSelectionChange(false); m_blockTextfieldUpdates = false; m_textGeneration = generation; setFocusControllerActive(true); @@ -1783,8 +1803,14 @@ void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node) { " node=%p", m_mousePos.x(), m_mousePos.y(), m_scrollOffsetX, m_scrollOffsetY, pt.x(), pt.y(), node); } - if (node) + if (node) { + EditorClientAndroid* client + = static_cast<EditorClientAndroid*>( + m_mainFrame->editor()->client()); + client->setShouldChangeSelectedRange(false); handleMouseClick(frame, node); + client->setShouldChangeSelectedRange(true); + } } bool WebViewCore::handleTouchEvent(int action, int x, int y) @@ -1816,7 +1842,7 @@ bool WebViewCore::handleTouchEvent(int action, int x, int y) } void WebViewCore::touchUp(int touchGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, int size) + WebCore::Frame* frame, WebCore::Node* node, int x, int y) { if (m_touchGeneration > touchGeneration) { DBG_NAV_LOGD("m_touchGeneration=%d > touchGeneration=%d" @@ -1828,12 +1854,30 @@ void WebViewCore::touchUp(int touchGeneration, if (frame && CacheBuilder::validNode(m_mainFrame, frame, 0)) { frame->loader()->resetMultipleFormSubmissionProtection(); } - EditorClientAndroid* client = static_cast<EditorClientAndroid*>(m_mainFrame->editor()->client()); - client->setFromClick(true); + // If the click is on an unselected textfield/area we do not want to allow + // the click to change the selection, because we will set it ourselves + // elsewhere - beginning for textareas, end for textfields + bool needToIgnoreChangesToSelectedRange = true; + WebCore::Node* focusNode = currentFocus(); + if (focusNode) { + WebCore::RenderObject* renderer = focusNode->renderer(); + if (renderer && (renderer->isTextField() || renderer->isTextArea())) { + // Now check to see if the click is inside the focused textfield + if (focusNode->getRect().contains(x, y)) + needToIgnoreChangesToSelectedRange = false; + } + } + EditorClientAndroid* client = 0; + if (needToIgnoreChangesToSelectedRange) { + client = static_cast<EditorClientAndroid*>( + m_mainFrame->editor()->client()); + client->setShouldChangeSelectedRange(false); + } 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); + if (needToIgnoreChangesToSelectedRange) + client->setShouldChangeSelectedRange(true); } // Common code for both clicking with the trackball and touchUp @@ -2056,6 +2100,21 @@ WebViewCore::getWebViewJavaObject() return env->GetObjectField(m_javaGlue->object(env).get(), gWebViewCoreFields.m_webView); } +void WebViewCore::updateTextSelection() { + WebCore::Node* focusNode = currentFocus(); + if (!focusNode) + return; + RenderObject* renderer = focusNode->renderer(); + if (!renderer || (!renderer->isTextArea() && !renderer->isTextField())) + return; + RenderTextControl* rtc = static_cast<RenderTextControl*>(renderer); + JNIEnv* env = JSC::Bindings::getJNIEnv(); + env->CallVoidMethod(m_javaGlue->object(env).get(), + m_javaGlue->m_updateTextSelection, reinterpret_cast<int>(focusNode), + rtc->selectionStart(), rtc->selectionEnd(), m_textGeneration); + checkException(env); +} + void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword, const WebCore::String& text) { @@ -2369,7 +2428,7 @@ static jboolean HandleTouchEvent(JNIEnv *env, jobject obj, jint action, jint x, } static void TouchUp(JNIEnv *env, jobject obj, jint touchGeneration, - jint frame, jint node, jint x, jint y, jint size) + jint frame, jint node, jint x, jint y) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); @@ -2377,7 +2436,7 @@ static void TouchUp(JNIEnv *env, jobject obj, jint touchGeneration, WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); viewImpl->touchUp(touchGeneration, - (WebCore::Frame*) frame, (WebCore::Node*) node, x, y, size); + (WebCore::Frame*) frame, (WebCore::Node*) node, x, y); } static jstring RetrieveHref(JNIEnv *env, jobject obj, jint frame, @@ -2702,7 +2761,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) FindAddress }, { "nativeHandleTouchEvent", "(III)Z", (void*) HandleTouchEvent }, - { "nativeTouchUp", "(IIIIII)V", + { "nativeTouchUp", "(IIIII)V", (void*) TouchUp }, { "nativeRetrieveHref", "(II)Ljava/lang/String;", (void*) RetrieveHref }, diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index 22e00e2..1408cb7 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -173,6 +173,15 @@ namespace android { */ void updateTextfield(WebCore::Node* pointer, bool changeToPassword, const WebCore::String& text); + + /** + * Tell the java side to update the current selection in the focused + * textfield to the WebTextView. This function finds the currently + * focused textinput, and passes its selection to java. + * If there is no focus, or it is not a text input, this does nothing. + */ + void updateTextSelection(); + void clearTextEntry(); // JavaScript support void jsAlert(const WebCore::String& url, const WebCore::String& text); @@ -260,8 +269,8 @@ namespace android { * Handle motionUp event from the UI thread (called touchUp in the * WebCore thread). */ - void touchUp(int touchGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, int size); + void touchUp(int touchGeneration, WebCore::Frame* frame, + WebCore::Node* node, int x, int y); /** * Sets the index of the label from a popup |