diff options
Diffstat (limited to 'Source/WebKit/android/jni/WebViewCore.cpp')
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.cpp | 376 |
1 files changed, 208 insertions, 168 deletions
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index f17e573..aa38222 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -30,6 +30,7 @@ #include "AccessibilityObject.h" #include "AndroidHitTestResult.h" +#include "ApplicationCacheStorage.h" #include "Attribute.h" #include "content/address_detector.h" #include "Chrome.h" @@ -62,7 +63,6 @@ #include "Geolocation.h" #include "GraphicsContext.h" #include "GraphicsJNI.h" -#include "GraphicsOperationCollection.h" #include "HTMLAnchorElement.h" #include "HTMLAreaElement.h" #include "HTMLElement.h" @@ -131,10 +131,10 @@ #include "WebCoreJni.h" #include "WebFrameView.h" #include "WindowsKeyboardCodes.h" -#include "android_graphics.h" #include "autofill/WebAutofill.h" #include "htmlediting.h" #include "markup.h" +#include "unicode/uloc.h" #include "visible_units.h" #include <JNIHelp.h> @@ -367,8 +367,6 @@ struct WebViewCore::JavaGlue { jmethodID m_showRect; jmethodID m_centerFitRect; jmethodID m_setScrollbarModes; - jmethodID m_setInstallableWebApp; - jmethodID m_enterFullscreenForVideoLayer; jmethodID m_exitFullscreenVideo; jmethodID m_setWebTextViewAutoFillable; jmethodID m_selectAt; @@ -401,7 +399,7 @@ struct WebViewCore::TextFieldInitDataGlue { jfieldID m_maxLength; jfieldID m_contentBounds; jfieldID m_nodeLayerId; - jfieldID m_contentRect; + jfieldID m_clientRect; }; /* @@ -423,7 +421,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m , m_mainFrame(mainframe) , m_popupReply(0) , m_blockTextfieldUpdates(false) - , m_focusBoundsChanged(false) , m_skipContentDraw(false) , m_textGeneration(0) , m_maxXScroll(320/4) @@ -436,7 +433,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m , m_textWrapWidth(320) , m_scale(1.0f) , m_groupForVisitedLinks(0) - , m_isPaused(false) , m_cacheMode(0) , m_fullscreenVideoMode(false) , m_matchCount(0) @@ -446,6 +442,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m , m_screenOnCounter(0) , m_currentNodeDomNavigationAxis(0) , m_deviceMotionAndOrientationManager(this) + , m_geolocationManager(this) #if ENABLE(TOUCH_EVENTS) , m_forwardingTouchEvents(false) #endif @@ -471,7 +468,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_updateViewport = GetJMethod(env, clazz, "updateViewport", "()V"); 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_updateTextfield = GetJMethod(env, clazz, "updateTextfield", "(ILjava/lang/String;I)V"); m_javaGlue->m_updateTextSelection = GetJMethod(env, clazz, "updateTextSelection", "(IIIII)V"); m_javaGlue->m_updateTextSizeAndScroll = GetJMethod(env, clazz, "updateTextSizeAndScroll", "(IIIII)V"); m_javaGlue->m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V"); @@ -479,7 +476,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_needTouchEvents = GetJMethod(env, clazz, "needTouchEvents", "(Z)V"); m_javaGlue->m_requestKeyboard = GetJMethod(env, clazz, "requestKeyboard", "(Z)V"); m_javaGlue->m_exceededDatabaseQuota = GetJMethod(env, clazz, "exceededDatabaseQuota", "(Ljava/lang/String;Ljava/lang/String;JJ)V"); - m_javaGlue->m_reachedMaxAppCacheSize = GetJMethod(env, clazz, "reachedMaxAppCacheSize", "(J)V"); + m_javaGlue->m_reachedMaxAppCacheSize = GetJMethod(env, clazz, "reachedMaxAppCacheSize", "(JJ)V"); m_javaGlue->m_populateVisitedLinks = GetJMethod(env, clazz, "populateVisitedLinks", "()V"); m_javaGlue->m_geolocationPermissionsShowPrompt = GetJMethod(env, clazz, "geolocationPermissionsShowPrompt", "(Ljava/lang/String;)V"); m_javaGlue->m_geolocationPermissionsHidePrompt = GetJMethod(env, clazz, "geolocationPermissionsHidePrompt", "()V"); @@ -499,9 +496,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_showRect = GetJMethod(env, clazz, "showRect", "(IIIIIIFFFF)V"); m_javaGlue->m_centerFitRect = GetJMethod(env, clazz, "centerFitRect", "(IIII)V"); m_javaGlue->m_setScrollbarModes = GetJMethod(env, clazz, "setScrollbarModes", "(II)V"); - m_javaGlue->m_setInstallableWebApp = GetJMethod(env, clazz, "setInstallableWebApp", "()V"); #if ENABLE(VIDEO) - m_javaGlue->m_enterFullscreenForVideoLayer = GetJMethod(env, clazz, "enterFullscreenForVideoLayer", "(ILjava/lang/String;)V"); m_javaGlue->m_exitFullscreenVideo = GetJMethod(env, clazz, "exitFullscreenVideo", "()V"); #endif m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V"); @@ -526,7 +521,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_textFieldInitDataGlue->m_maxLength = env->GetFieldID(tfidClazz, "mMaxLength", "I"); m_textFieldInitDataGlue->m_contentBounds = env->GetFieldID(tfidClazz, "mContentBounds", "Landroid/graphics/Rect;"); m_textFieldInitDataGlue->m_nodeLayerId = env->GetFieldID(tfidClazz, "mNodeLayerId", "I"); - m_textFieldInitDataGlue->m_contentRect = env->GetFieldID(tfidClazz, "mContentRect", "Landroid/graphics/Rect;"); + m_textFieldInitDataGlue->m_clientRect = env->GetFieldID(tfidClazz, "mClientRect", "Landroid/graphics/Rect;"); m_textFieldInitDataGlue->m_constructor = GetJMethod(env, tfidClazz, "<init>", "()V"); env->DeleteLocalRef(tfidClazz); @@ -728,13 +723,6 @@ void WebViewCore::clearContent() updateLocale(); } -bool WebViewCore::focusBoundsChanged() -{ - bool result = m_focusBoundsChanged; - m_focusBoundsChanged = false; - return result; -} - void WebViewCore::paintContents(WebCore::GraphicsContext* gc, WebCore::IntRect& dirty) { WebCore::FrameView* view = m_mainFrame->view(); @@ -1507,6 +1495,7 @@ bool WebViewCore::selectWordAroundPosition(Frame* frame, VisiblePosition pos) VisibleSelection selection(pos); selection.expandUsingGranularity(WordGranularity); SelectionController* selectionController = frame->selection(); + selection = VisibleSelection(selection.start(), selection.end()); bool wordSelected = false; if (selectionController->shouldChangeSelection(selection)) { @@ -1566,7 +1555,8 @@ void WebViewCore::layerToAbsoluteOffset(const LayerAndroid* layer, IntPoint& off void WebViewCore::setSelectionCaretInfo(SelectText* selectTextContainer, const WebCore::Position& pos, const IntPoint& frameOffset, - SelectText::HandleId handleId, int caretRectOffset, EAffinity affinity) + SelectText::HandleId handleId, SelectText::HandleType handleType, + int caretRectOffset, EAffinity affinity) { Node* node = pos.anchorNode(); LayerAndroid* layer = 0; @@ -1584,8 +1574,9 @@ void WebViewCore::setSelectionCaretInfo(SelectText* selectTextContainer, caretRect.setX(absoluteOffset.x() - offset.x() + caretRectOffset); caretRect.setY(absoluteOffset.y() - offset.y()); selectTextContainer->setCaretRect(handleId, caretRect); + selectTextContainer->setHandleType(handleId, handleType); selectTextContainer->setTextRect(handleId, - positionToTextRect(pos, affinity, offset)); + positionToTextRect(pos, affinity, offset, caretRect)); } bool WebViewCore::isLtr(const Position& position) @@ -1601,14 +1592,28 @@ bool WebViewCore::isLtr(const Position& position) return isLtr; } +static Node* findInputParent(Node* node) +{ + Node* testNode = node; + while (testNode) { + RenderObject* renderer = testNode->renderer(); + if (renderer + && (renderer->isTextArea() || renderer->isTextControl())) { + return testNode; + } + testNode = testNode->parentOrHostNode(); + } + return node; +} + SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) { bool isCaret = selection.isCaret(); + Position base = selection.base(); + Position extent = selection.extent(); if (selection.isNone() || (!selection.isContentEditable() && isCaret) - || !selection.start().anchorNode() - || !selection.start().anchorNode()->renderer() - || !selection.end().anchorNode() - || !selection.end().anchorNode()->renderer()) + || !base.anchorNode() || !base.anchorNode()->renderer() + || !extent.anchorNode() || !extent.anchorNode()->renderer()) return 0; RefPtr<Range> range = selection.firstRange(); @@ -1624,20 +1629,39 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) IntPoint frameOffset = convertGlobalContentToFrameContent(IntPoint()); SelectText* selectTextContainer = new SelectText(); if (isCaret) { - setSelectionCaretInfo(selectTextContainer, selection.start(), frameOffset, - SelectText::LeftHandle, 0, selection.affinity()); - setSelectionCaretInfo(selectTextContainer, selection.start(), frameOffset, - SelectText::RightHandle, 0, selection.affinity()); + setSelectionCaretInfo(selectTextContainer, base, frameOffset, + SelectText::BaseHandle, SelectText::CenterHandle, 0, + selection.affinity()); + setSelectionCaretInfo(selectTextContainer, base, frameOffset, + SelectText::ExtentHandle, SelectText::CenterHandle, 0, + selection.affinity()); } else { - bool ltr = isLtr(selection.start()); - Position left = ltr ? selection.start() : selection.end(); - Position right = ltr ? selection.end() : selection.start(); - int leftOffset = isLtr(left) ? 0 : -1; - int rightOffset = isLtr(right) ? 0 : -1; - setSelectionCaretInfo(selectTextContainer, left, frameOffset, - SelectText::LeftHandle, leftOffset, selection.affinity()); - setSelectionCaretInfo(selectTextContainer, right, frameOffset, - SelectText::RightHandle, rightOffset, selection.affinity()); + bool isBaseLtr = isLtr(base); + bool isBaseStart = comparePositions(base, extent) <= 0; + int baseOffset = isBaseLtr ? 0 : -1; + SelectText::HandleType baseHandleType = (isBaseLtr == isBaseStart) + ? SelectText::LeftHandle : SelectText::RightHandle; + EAffinity affinity = selection.affinity(); + setSelectionCaretInfo(selectTextContainer, base, frameOffset, + SelectText::BaseHandle, baseHandleType, baseOffset, affinity); + bool isExtentLtr = isLtr(extent); + int extentOffset = isExtentLtr ? 0 : -1; + SelectText::HandleType extentHandleType = (isExtentLtr == isBaseStart) + ? SelectText::RightHandle : SelectText::LeftHandle; + setSelectionCaretInfo(selectTextContainer, extent, frameOffset, + SelectText::ExtentHandle, extentHandleType, extentOffset, affinity); + IntRect clipRect; + if (selection.isContentEditable()) { + Node* editable = findInputParent(base.anchorNode()); + RenderObject* render = editable->renderer(); + if (render && render->isBox() && !render->isBody()) { + RenderBox* renderBox = toRenderBox(render); + clipRect = renderBox->clientBoxRect(); + FloatPoint pos = renderBox->localToAbsolute(clipRect.location()); + clipRect.setX(pos.x()); + clipRect.setY(pos.y()); + } + } Node* stopNode = range->pastLastNode(); for (Node* node = range->firstNode(); node != stopNode; node = node->traverseNextNode()) { @@ -1651,7 +1675,8 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) int layerId = platformLayerIdFromNode(node, &layer); Vector<IntRect> rects; renderText->absoluteRectsForRange(rects, startOffset, endOffset, true); - selectTextContainer->addHighlightRegion(layer, rects, frameOffset); + selectTextContainer->addHighlightRegion(layer, rects, frameOffset, + clipRect); } } selectTextContainer->setText(range->text()); @@ -1659,9 +1684,9 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) } IntRect WebViewCore::positionToTextRect(const Position& position, - EAffinity affinity, const WebCore::IntPoint& offset) + EAffinity affinity, const WebCore::IntPoint& offset, const IntRect& caretRect) { - IntRect textRect; + IntRect textRect = caretRect; InlineBox* inlineBox; int offsetIndex; position.getInlineBoxAndOffset(affinity, inlineBox, offsetIndex); @@ -1697,25 +1722,25 @@ IntPoint WebViewCore::convertGlobalContentToFrameContent(const IntPoint& point, return IntPoint(point.x() + frameOffset.x(), point.y() + frameOffset.y()); } -Position WebViewCore::trimSelectionPosition(const Position &start, const Position& stop) +VisiblePosition WebViewCore::trimSelectionPosition(const VisiblePosition &start, + const VisiblePosition& stop) { int direction = comparePositions(start, stop); if (direction == 0) return start; bool forward = direction < 0; - EAffinity affinity = forward ? DOWNSTREAM : UPSTREAM; bool move; - Position pos = start; + VisiblePosition pos = start; bool movedTooFar = false; do { move = true; - Node* node = pos.anchorNode(); + Node* node = pos.deepEquivalent().anchorNode(); if (node && node->isTextNode() && node->renderer()) { RenderText *textRenderer = toRenderText(node->renderer()); move = !textRenderer->textLength(); } if (move) { - Position nextPos = forward ? pos.next() : pos.previous(); + VisiblePosition nextPos = forward ? pos.next() : pos.previous(); movedTooFar = nextPos.isNull() || pos == nextPos || ((comparePositions(nextPos, stop) < 0) != forward); pos = nextPos; @@ -1726,47 +1751,65 @@ Position WebViewCore::trimSelectionPosition(const Position &start, const Positio return pos; } -void WebViewCore::selectText(int startX, int startY, int endX, int endY) +void WebViewCore::selectText(SelectText::HandleId handleId, int x, int y) { SelectionController* sc = focusedFrame()->selection(); - IntPoint startPoint = convertGlobalContentToFrameContent(IntPoint(startX, startY)); - VisiblePosition startPosition(visiblePositionForContentPoint(startPoint)); - IntPoint endPoint = convertGlobalContentToFrameContent(IntPoint(endX, endY)); - VisiblePosition endPosition(visiblePositionForContentPoint(endPoint)); + VisibleSelection selection = sc->selection(); + Position base = selection.base(); + Position extent = selection.extent(); + IntPoint dragPoint = convertGlobalContentToFrameContent(IntPoint(x, y)); + VisiblePosition dragPosition(visiblePositionForContentPoint(dragPoint)); - if (startPosition.isNull() || endPosition.isNull()) + if (base.isNull() || extent.isNull() || dragPosition.isNull()) return; + bool draggingBase = (handleId == SelectText::BaseHandle); + if (draggingBase) + base = dragPosition.deepEquivalent(); + else + extent = dragPosition.deepEquivalent(); - // Ensure startPosition is before endPosition - if (comparePositions(startPosition, endPosition) > 0) - swap(startPosition, endPosition); + bool baseIsStart = (comparePositions(base, extent) <= 0); + Position& start = baseIsStart ? base : extent; + Position& end = baseIsStart ? extent : base; + VisiblePosition startPosition(start, selection.affinity()); + VisiblePosition endPosition(end, selection.affinity()); + bool draggingStart = (baseIsStart == draggingBase); - if (sc->isContentEditable()) { - startPosition = sc->selection().visibleStart().honorEditableBoundaryAtOrAfter(startPosition); - endPosition = sc->selection().visibleEnd().honorEditableBoundaryAtOrBefore(endPosition); - if (startPosition.isNull() || endPosition.isNull()) { + if (draggingStart) { + if (selection.isRange()) { + startPosition = trimSelectionPosition(startPosition, endPosition); + if ((startPosition != endPosition) && isEndOfBlock(startPosition)) { + // Ensure startPosition is not at end of block + VisiblePosition nextStartPosition(startPosition.next()); + if (nextStartPosition.isNotNull()) + startPosition = nextStartPosition; + } + } + startPosition = endPosition.honorEditableBoundaryAtOrAfter(startPosition); + if (startPosition.isNull()) return; + start = startPosition.deepEquivalent(); + if (selection.isCaret()) + end = start; + } else { + if (selection.isRange()) { + endPosition = trimSelectionPosition(endPosition, startPosition); + if ((start != end) && isStartOfBlock(endPosition)) { + // Ensure endPosition is not at start of block + VisiblePosition prevEndPosition(endPosition.previous()); + if (!prevEndPosition.isNull()) + endPosition = prevEndPosition; + } } + endPosition = startPosition.honorEditableBoundaryAtOrAfter(endPosition); + if (endPosition.isNull()) + return; + end = endPosition.deepEquivalent(); + if (selection.isCaret()) + start = end; } - // Ensure startPosition is not at end of block - if (startPosition != endPosition && isEndOfBlock(startPosition)) { - VisiblePosition nextStartPosition(startPosition.next()); - if (!nextStartPosition.isNull()) - startPosition = nextStartPosition; - } - // Ensure endPosition is not at start of block - if (startPosition != endPosition && isStartOfBlock(endPosition)) { - VisiblePosition prevEndPosition(endPosition.previous()); - if (!prevEndPosition.isNull()) - endPosition = prevEndPosition; - } - - Position start = startPosition.deepEquivalent(); - Position end = endPosition.deepEquivalent(); - start = trimSelectionPosition(start, end); - end = trimSelectionPosition(end, start); - VisibleSelection selection(start, end); + selection = VisibleSelection(base, extent); // Only allow changes between caret positions or to text selection. bool selectChangeAllowed = (!selection.isCaret() || sc->isCaret()); if (selectChangeAllowed && sc->shouldChangeSelection(selection)) @@ -2944,33 +2987,31 @@ void WebViewCore::passToJs(int generation, const WTF::String& current, WTF::String test = getInputText(focus); if (test != current) { // If the text changed during the key event, update the UI text field. - updateTextfield(focus, false, test); + updateTextfield(focus, test); } // Now that the selection has settled down, send it. updateTextSelection(); } -WebCore::IntRect WebViewCore::scrollFocusedTextInput(float xPercent, int y) +void WebViewCore::scrollFocusedTextInput(float xPercent, int y) { WebCore::Node* focus = currentFocus(); if (!focus) { clearTextEntry(); - return WebCore::IntRect(); + return; } WebCore::RenderTextControl* renderText = toRenderTextControl(focus); if (!renderText) { clearTextEntry(); - return WebCore::IntRect(); + return; } - int x = (int) (xPercent * (renderText->scrollWidth() - - renderText->clientWidth())); + int x = (int)round(xPercent * (renderText->scrollWidth() - + renderText->contentWidth())); renderText->setScrollLeft(x); renderText->setScrollTop(y); focus->document()->frame()->selection()->recomputeCaretRect(); - LayerAndroid* layer = 0; - platformLayerIdFromNode(focus, &layer); - return absoluteContentRect(focus, layer); + updateTextSelection(); } void WebViewCore::setFocusControllerActive(bool active) @@ -3364,10 +3405,10 @@ bool WebViewCore::isAutoCompleteEnabled(Node* node) return isEnabled; } -WebCore::IntRect WebViewCore::absoluteContentRect(WebCore::Node* node, +WebCore::IntRect WebViewCore::absoluteClientRect(WebCore::Node* node, LayerAndroid* layer) { - IntRect contentRect; + IntRect clientRect; if (node) { RenderObject* render = node->renderer(); if (render && render->isBox() && !render->isBody()) { @@ -3376,11 +3417,15 @@ WebCore::IntRect WebViewCore::absoluteContentRect(WebCore::Node* node, WebViewCore::layerToAbsoluteOffset(layer, offset); RenderBox* renderBox = toRenderBox(render); - contentRect = renderBox->absoluteContentBox(); - contentRect.move(-offset.x(), -offset.y()); + clientRect = renderBox->clientBoxRect(); + IntRect contentBox = renderBox->contentBoxRect(); + clientRect.setX(contentBox.x()); + clientRect.setWidth(contentBox.width()); + FloatPoint absPos = renderBox->localToAbsolute(FloatPoint()); + clientRect.move(absPos.x() - offset.x(), absPos.y() - offset.y()); } } - return contentRect; + return clientRect; } jobject WebViewCore::createTextFieldInitData(Node* node) @@ -3417,7 +3462,7 @@ jobject WebViewCore::createTextFieldInitData(Node* node) env->SetIntField(initData, classDef->m_maxLength, getMaxLength(node)); LayerAndroid* layer = 0; int layerId = platformLayerIdFromNode(node, &layer); - IntRect bounds = absoluteContentRect(node, layer); + IntRect bounds = absoluteClientRect(node, layer); ScopedLocalRef<jobject> jbounds(env, intRectToRect(env, bounds)); env->SetObjectField(initData, classDef->m_contentBounds, jbounds.get()); env->SetIntField(initData, classDef->m_nodeLayerId, layerId); @@ -3429,7 +3474,7 @@ jobject WebViewCore::createTextFieldInitData(Node* node) contentRect.move(-rtc->scrollLeft(), -rtc->scrollTop()); } ScopedLocalRef<jobject> jcontentRect(env, intRectToRect(env, contentRect)); - env->SetObjectField(initData, classDef->m_contentRect, jcontentRect.get()); + env->SetObjectField(initData, classDef->m_clientRect, jcontentRect.get()); return initData; } @@ -3611,6 +3656,19 @@ bool WebViewCore::exceededDatabaseQuota(const WTF::String& url, const WTF::Strin #endif } +/* + * TODO Note that this logic still needs to be cleaned up. Normally the + * information provided in this callback is used to resize the appcache. + * so we need to provide the current database size. However, webkit provides no + * way to reach this information. It can be calculated by fetching all the + * origins and their usage, however this is too expensize (requires one inner + * join operation for each origin). Rather, we simply return the maximum cache size, + * which should be equivalent to the current cache size. This is generally safe. + * However, setting the maximum database size to less than the current database size + * may cause a problem. In this case, ApplicationCacheStorage ("the owner of database") + * uses the updated value, while database internally ignores it and uses the current size + * as quota. This means the value we returned here won't reflect the actual database size. + */ bool WebViewCore::reachedMaxAppCacheSize(const unsigned long long spaceNeeded) { #if ENABLE(OFFLINE_WEB_APPLICATIONS) @@ -3618,7 +3676,7 @@ bool WebViewCore::reachedMaxAppCacheSize(const unsigned long long spaceNeeded) AutoJObject javaObject = m_javaGlue->object(env); if (!javaObject.get()) return false; - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_reachedMaxAppCacheSize, spaceNeeded); + env->CallVoidMethod(javaObject.get(), m_javaGlue->m_reachedMaxAppCacheSize, spaceNeeded, WebCore::cacheStorage().maximumSize()); checkException(env); return true; #endif @@ -3848,8 +3906,7 @@ void WebViewCore::updateTextSizeAndScroll(WebCore::Node* node) checkException(env); } -void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword, - const WTF::String& text) +void WebViewCore::updateTextfield(WebCore::Node* ptr, const WTF::String& text) { JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject javaObject = m_javaGlue->object(env); @@ -3857,15 +3914,9 @@ void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword, return; if (m_blockTextfieldUpdates) return; - if (changeToPassword) { - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_updateTextfield, - (int) ptr, true, 0, m_textGeneration); - checkException(env); - return; - } jstring string = wtfStringToJstring(env, text); env->CallVoidMethod(javaObject.get(), m_javaGlue->m_updateTextfield, - (int) ptr, false, string, m_textGeneration); + (int) ptr, string, m_textGeneration); env->DeleteLocalRef(string); checkException(env); } @@ -4059,27 +4110,11 @@ void WebViewCore::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode checkException(env); } -void WebViewCore::notifyWebAppCanBeInstalled() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue->object(env); - if (!javaObject.get()) - return; - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_setInstallableWebApp); - checkException(env); -} - #if ENABLE(VIDEO) -void WebViewCore::enterFullscreenForVideoLayer(int layerId, const WTF::String& url) +void WebViewCore::enterFullscreenForVideoLayer() { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue->object(env); - if (!javaObject.get()) - return; - jstring jUrlStr = wtfStringToJstring(env, url); - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_enterFullscreenForVideoLayer, layerId, jUrlStr); + // Just need to update the video mode, to avoid multiple exit full screen. m_fullscreenVideoMode = true; - checkException(env); } void WebViewCore::exitFullscreenVideo() @@ -4373,6 +4408,44 @@ void WebViewCore::getLocale(String& language, String& region) region = String(propRegn, 2); } +// generate bcp47 identifier for the supplied language/region +static void toLanguageTag(char* output, size_t outSize, const String& language, + const String& region) { + if (output == NULL || outSize <= 0) + return; + String locale = language; + locale.append('_'); + locale.append(region); + char canonicalChars[ULOC_FULLNAME_CAPACITY]; + UErrorCode uErr = U_ZERO_ERROR; + uloc_canonicalize(locale.ascii().data(), canonicalChars, + ULOC_FULLNAME_CAPACITY, &uErr); + if (U_SUCCESS(uErr)) { + char likelyChars[ULOC_FULLNAME_CAPACITY]; + uErr = U_ZERO_ERROR; + uloc_addLikelySubtags(canonicalChars, likelyChars, + ULOC_FULLNAME_CAPACITY, &uErr); + if (U_SUCCESS(uErr)) { + uErr = U_ZERO_ERROR; + uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr); + if (U_SUCCESS(uErr)) { + return; + } else { + ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars, + u_errorName(uErr)); + } + } else { + ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s", canonicalChars, + u_errorName(uErr)); + } + } else { + ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale.ascii().data(), + u_errorName(uErr)); + } + // unable to build a proper language identifier + output[0] = '\0'; +} + void WebViewCore::updateLocale() { static String prevLang; @@ -4387,6 +4460,9 @@ void WebViewCore::updateLocale() prevRegn = region; GlyphPageTreeNode::resetRoots(); fontCache()->invalidate(); + char langTag[ULOC_FULLNAME_CAPACITY]; + toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, language, region); + FontPlatformData::setDefaultLanguage(langTag); } } @@ -4505,12 +4581,10 @@ static void PassToJs(JNIEnv* env, jobject obj, jint nativeClass, } static void ScrollFocusedTextInput(JNIEnv* env, jobject obj, jint nativeClass, - jfloat xPercent, jint y, jobject contentBounds) + jfloat xPercent, jint y) { WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); - IntRect bounds = viewImpl->scrollFocusedTextInput(xPercent, y); - if (contentBounds) - GraphicsJNI::irect_to_jrect(bounds, env, contentBounds); + viewImpl->scrollFocusedTextInput(xPercent, y); } static void SetFocusControllerActive(JNIEnv* env, jobject obj, jint nativeClass, @@ -4765,10 +4839,7 @@ static void GeolocationPermissionsProvide(JNIEnv* env, jobject obj, jint nativeClass, jstring origin, jboolean allow, jboolean remember) { WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); - Frame* frame = viewImpl->mainFrame(); - - ChromeClientAndroid* chromeClient = static_cast<ChromeClientAndroid*>(frame->page()->chrome()->client()); - chromeClient->provideGeolocationPermissions(jstringToWtfString(env, origin), allow, remember); + viewImpl->geolocationManager()->provideRealClientPermissionState(jstringToWtfString(env, origin), allow, remember); } static void RegisterURLSchemeAsLocal(JNIEnv* env, jobject obj, jint nativeClass, @@ -4777,20 +4848,6 @@ static void RegisterURLSchemeAsLocal(JNIEnv* env, jobject obj, jint nativeClass, WebCore::SchemeRegistry::registerURLSchemeAsLocal(jstringToWtfString(env, scheme)); } -static bool FocusBoundsChanged(JNIEnv* env, jobject obj, jint nativeClass) -{ - return reinterpret_cast<WebViewCore*>(nativeClass)->focusBoundsChanged(); -} - -static void SetIsPaused(JNIEnv* env, jobject obj, jint nativeClass, - jboolean isPaused) -{ - // tell the webcore thread to stop thinking while we do other work - // (selection and scrolling). This has nothing to do with the lifecycle - // pause and resume. - reinterpret_cast<WebViewCore*>(nativeClass)->setIsPaused(isPaused); -} - static void Pause(JNIEnv* env, jobject obj, jint nativeClass) { // This is called for the foreground tab when the browser is put to the @@ -4798,50 +4855,36 @@ static void Pause(JNIEnv* env, jobject obj, jint nativeClass) // browser). The browser can only be killed by the system when it is in the // background, so saving the Geolocation permission state now ensures that // is maintained when the browser is killed. - WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); - ChromeClient* chromeClient = viewImpl->mainFrame()->page()->chrome()->client(); - ChromeClientAndroid* chromeClientAndroid = static_cast<ChromeClientAndroid*>(chromeClient); - chromeClientAndroid->storeGeolocationPermissions(); + GeolocationPermissions::maybeStorePermanentPermissions(); + WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); Frame* mainFrame = viewImpl->mainFrame(); - for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) { - Geolocation* geolocation = frame->domWindow()->navigator()->optionalGeolocation(); - if (geolocation) - geolocation->suspend(); - } if (mainFrame) mainFrame->settings()->setMinDOMTimerInterval(BACKGROUND_TIMER_INTERVAL); viewImpl->deviceMotionAndOrientationManager()->maybeSuspendClients(); + viewImpl->geolocationManager()->suspendRealClient(); ANPEvent event; SkANP::InitEvent(&event, kLifecycle_ANPEventType); event.data.lifecycle.action = kPause_ANPLifecycleAction; viewImpl->sendPluginEvent(event); - - viewImpl->setIsPaused(true); } static void Resume(JNIEnv* env, jobject obj, jint nativeClass) { WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); Frame* mainFrame = viewImpl->mainFrame(); - for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) { - Geolocation* geolocation = frame->domWindow()->navigator()->optionalGeolocation(); - if (geolocation) - geolocation->resume(); - } if (mainFrame) mainFrame->settings()->setMinDOMTimerInterval(FOREGROUND_TIMER_INTERVAL); viewImpl->deviceMotionAndOrientationManager()->maybeResumeClients(); + viewImpl->geolocationManager()->resumeRealClient(); ANPEvent event; SkANP::InitEvent(&event, kLifecycle_ANPEventType); event.data.lifecycle.action = kResume_ANPLifecycleAction; viewImpl->sendPluginEvent(event); - - viewImpl->setIsPaused(false); } static void FreeMemory(JNIEnv* env, jobject obj, jint nativeClass) @@ -4959,10 +5002,10 @@ static jobject GetText(JNIEnv* env, jobject obj, jint nativeClass, } static void SelectText(JNIEnv* env, jobject obj, jint nativeClass, - jint startX, jint startY, jint endX, jint endY) + jint handleId, jint x, jint y) { WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); - viewImpl->selectText(startX, startY, endX, endY); + viewImpl->selectText(static_cast<SelectText::HandleId>(handleId), x, y); } static void ClearSelection(JNIEnv* env, jobject obj, jint nativeClass) @@ -5006,8 +5049,6 @@ static int FindNext(JNIEnv* env, jobject obj, jint nativeClass, static JNINativeMethod gJavaWebViewCoreMethods[] = { { "nativeClearContent", "(I)V", (void*) ClearContent }, - { "nativeFocusBoundsChanged", "(I)Z", - (void*) FocusBoundsChanged } , { "nativeKey", "(IIIIZZZZ)Z", (void*) Key }, { "nativeContentInvalidateAll", "(I)V", @@ -5034,7 +5075,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) MoveMouse }, { "passToJs", "(IILjava/lang/String;IIZZZZ)V", (void*) PassToJs }, - { "nativeScrollFocusedTextInput", "(IFILandroid/graphics/Rect;)V", + { "nativeScrollFocusedTextInput", "(IFI)V", (void*) ScrollFocusedTextInput }, { "nativeSetFocusControllerActive", "(IZ)V", (void*) SetFocusControllerActive }, @@ -5072,7 +5113,6 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) SetNewStorageLimit }, { "nativeGeolocationPermissionsProvide", "(ILjava/lang/String;ZZ)V", (void*) GeolocationPermissionsProvide }, - { "nativeSetIsPaused", "(IZ)V", (void*) SetIsPaused }, { "nativePause", "(I)V", (void*) Pause }, { "nativeResume", "(I)V", (void*) Resume }, { "nativeFreeMemory", "(I)V", (void*) FreeMemory }, @@ -5100,7 +5140,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) InsertText }, { "nativeGetText", "(IIIII)Ljava/lang/String;", (void*) GetText }, - { "nativeSelectText", "(IIIII)V", + { "nativeSelectText", "(IIII)V", (void*) SelectText }, { "nativeClearTextSelection", "(I)V", (void*) ClearSelection }, |