summaryrefslogtreecommitdiffstats
path: root/WebKit/android/jni
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android/jni')
-rwxr-xr-xWebKit/android/jni/MockGeolocation.cpp96
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp3
-rw-r--r--WebKit/android/jni/WebCoreJniOnLoad.cpp4
-rw-r--r--WebKit/android/jni/WebViewCore.cpp79
-rw-r--r--WebKit/android/jni/WebViewCore.h13
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