diff options
Diffstat (limited to 'Source/WebKit/android/nav/WebView.cpp')
-rw-r--r-- | Source/WebKit/android/nav/WebView.cpp | 2718 |
1 files changed, 571 insertions, 2147 deletions
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 7cb41d9..a67b5fd 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -30,17 +30,16 @@ #include "AndroidAnimation.h" #include "AndroidLog.h" #include "BaseLayerAndroid.h" -#include "CachedFrame.h" -#include "CachedNode.h" -#include "CachedRoot.h" +#include "BaseRenderer.h" #include "DrawExtra.h" -#include "FindCanvas.h" #include "Frame.h" +#include "GLWebViewState.h" #include "GraphicsJNI.h" #include "HTMLInputElement.h" #include "IntPoint.h" #include "IntRect.h" #include "LayerAndroid.h" +#include "LayerContent.h" #include "Node.h" #include "utils/Functor.h" #include "private/hwui/DrawGlInfo.h" @@ -53,10 +52,8 @@ #include "SkPicture.h" #include "SkRect.h" #include "SkTime.h" -#ifdef ANDROID_INSTRUMENT -#include "TimeCounter.h" -#endif #include "TilesManager.h" +#include "TransferQueue.h" #include "WebCoreJni.h" #include "WebRequestContext.h" #include "WebViewCore.h" @@ -71,7 +68,7 @@ #include <JNIUtility.h> #include <JNIHelp.h> #include <jni.h> -#include <ui/KeycodeLabels.h> +#include <androidfw/KeycodeLabels.h> #include <wtf/text/AtomicString.h> #include <wtf/text/CString.h> @@ -95,7 +92,7 @@ static jfieldID gWebViewField; 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); + ALOG_ASSERT(m, "Could not find method %s", name); return m; } @@ -110,105 +107,81 @@ enum FrameCachePermission { AllowNewer }; +#define DRAW_EXTRAS_SIZE 2 enum DrawExtras { // keep this in sync with WebView.java DrawExtrasNone = 0, - DrawExtrasFind = 1, - DrawExtrasSelection = 2, - DrawExtrasCursorRing = 3 + DrawExtrasSelection = 1, + DrawExtrasCursorRing = 2 }; struct JavaGlue { jweak m_obj; - jmethodID m_overrideLoading; jmethodID m_scrollBy; - jmethodID m_sendMoveFocus; - jmethodID m_sendMoveMouse; - jmethodID m_sendMoveMouseIfLatest; - jmethodID m_sendMotionUp; - jmethodID m_domChangedFocus; jmethodID m_getScaledMaxXScroll; jmethodID m_getScaledMaxYScroll; - jmethodID m_getVisibleRect; - jmethodID m_rebuildWebTextView; + jmethodID m_updateRectsForGL; jmethodID m_viewInvalidate; jmethodID m_viewInvalidateRect; jmethodID m_postInvalidateDelayed; jmethodID m_pageSwapCallback; - jmethodID m_inFullScreenMode; jfieldID m_rectLeft; jfieldID m_rectTop; jmethodID m_rectWidth; jmethodID m_rectHeight; - jfieldID m_rectFLeft; - jfieldID m_rectFTop; - jmethodID m_rectFWidth; - jmethodID m_rectFHeight; - jmethodID m_getTextHandleScale; + jfieldID m_quadFP1; + jfieldID m_quadFP2; + jfieldID m_quadFP3; + jfieldID m_quadFP4; AutoJObject object(JNIEnv* env) { return getRealObject(env, m_obj); } } m_javaGlue; WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir, - bool isHighEndGfx) : - m_ring((WebViewCore*) viewImpl) - , m_isHighEndGfx(isHighEndGfx) + bool isHighEndGfx) + : m_isHighEndGfx(isHighEndGfx) { - jclass clazz = env->FindClass("android/webkit/WebView"); - // m_javaGlue = new JavaGlue; + memset(m_extras, 0, DRAW_EXTRAS_SIZE * sizeof(DrawExtra*)); + jclass clazz = env->FindClass("android/webkit/WebViewClassic"); m_javaGlue.m_obj = env->NewWeakGlobalRef(javaWebView); m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)Z"); - m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V"); - m_javaGlue.m_sendMoveFocus = GetJMethod(env, clazz, "sendMoveFocus", "(II)V"); - m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V"); - m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "(ZZ)V"); - m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIII)V"); - m_javaGlue.m_domChangedFocus = GetJMethod(env, clazz, "domChangedFocus", "()V"); m_javaGlue.m_getScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I"); m_javaGlue.m_getScaledMaxYScroll = GetJMethod(env, clazz, "getScaledMaxYScroll", "()I"); - m_javaGlue.m_getVisibleRect = GetJMethod(env, clazz, "sendOurVisibleRect", "()Landroid/graphics/Rect;"); - m_javaGlue.m_rebuildWebTextView = GetJMethod(env, clazz, "rebuildWebTextView", "()V"); + m_javaGlue.m_updateRectsForGL = GetJMethod(env, clazz, "updateRectsForGL", "()V"); m_javaGlue.m_viewInvalidate = GetJMethod(env, clazz, "viewInvalidate", "()V"); m_javaGlue.m_viewInvalidateRect = GetJMethod(env, clazz, "viewInvalidate", "(IIII)V"); m_javaGlue.m_postInvalidateDelayed = GetJMethod(env, clazz, "viewInvalidateDelayed", "(JIIII)V"); m_javaGlue.m_pageSwapCallback = GetJMethod(env, clazz, "pageSwapCallback", "(Z)V"); - m_javaGlue.m_inFullScreenMode = GetJMethod(env, clazz, "inFullScreenMode", "()Z"); - m_javaGlue.m_getTextHandleScale = GetJMethod(env, clazz, "getTextHandleScale", "()F"); env->DeleteLocalRef(clazz); jclass rectClass = env->FindClass("android/graphics/Rect"); - LOG_ASSERT(rectClass, "Could not find Rect class"); + ALOG_ASSERT(rectClass, "Could not find Rect class"); m_javaGlue.m_rectLeft = env->GetFieldID(rectClass, "left", "I"); m_javaGlue.m_rectTop = env->GetFieldID(rectClass, "top", "I"); m_javaGlue.m_rectWidth = GetJMethod(env, rectClass, "width", "()I"); m_javaGlue.m_rectHeight = GetJMethod(env, rectClass, "height", "()I"); env->DeleteLocalRef(rectClass); - jclass rectClassF = env->FindClass("android/graphics/RectF"); - LOG_ASSERT(rectClassF, "Could not find RectF class"); - m_javaGlue.m_rectFLeft = env->GetFieldID(rectClassF, "left", "F"); - m_javaGlue.m_rectFTop = env->GetFieldID(rectClassF, "top", "F"); - m_javaGlue.m_rectFWidth = GetJMethod(env, rectClassF, "width", "()F"); - m_javaGlue.m_rectFHeight = GetJMethod(env, rectClassF, "height", "()F"); - env->DeleteLocalRef(rectClassF); + jclass quadFClass = env->FindClass("android/webkit/QuadF"); + ALOG_ASSERT(quadFClass, "Could not find QuadF class"); + m_javaGlue.m_quadFP1 = env->GetFieldID(quadFClass, "p1", "Landroid/graphics/PointF;"); + m_javaGlue.m_quadFP2 = env->GetFieldID(quadFClass, "p2", "Landroid/graphics/PointF;"); + m_javaGlue.m_quadFP3 = env->GetFieldID(quadFClass, "p3", "Landroid/graphics/PointF;"); + m_javaGlue.m_quadFP4 = env->GetFieldID(quadFClass, "p4", "Landroid/graphics/PointF;"); + env->DeleteLocalRef(quadFClass); env->SetIntField(javaWebView, gWebViewField, (jint)this); m_viewImpl = (WebViewCore*) viewImpl; - m_frameCacheUI = 0; - m_navPictureUI = 0; m_generation = 0; m_heightCanMeasure = false; m_lastDx = 0; m_lastDxTime = 0; - m_ringAnimationEnd = 0; m_baseLayer = 0; m_glDrawFunctor = 0; m_isDrawingPaused = false; - m_buttonSkin = drawableDir.isEmpty() ? 0 : new RenderSkinButton(drawableDir); #if USE(ACCELERATED_COMPOSITING) m_glWebViewState = 0; - m_pageSwapCallbackRegistered = false; #endif } @@ -226,11 +199,17 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir, // deallocated base layer. stopGL(); #endif - delete m_frameCacheUI; - delete m_navPictureUI; SkSafeUnref(m_baseLayer); delete m_glDrawFunctor; - delete m_buttonSkin; + for (int i = 0; i < DRAW_EXTRAS_SIZE; i++) + delete m_extras[i]; +} + +DrawExtra* getDrawExtra(DrawExtras extras) +{ + if (extras == DrawExtrasNone) + return 0; + return m_extras[extras - 1]; } void stopGL() @@ -245,126 +224,6 @@ WebViewCore* getWebViewCore() const { return m_viewImpl; } -float getTextHandleScale() -{ - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue.object(env); - if (!javaObject.get()) - return 0; - float result = env->CallFloatMethod(javaObject.get(), m_javaGlue.m_getTextHandleScale); - checkException(env); - return result; -} - -void updateSelectionHandles() -{ - if (!m_baseLayer) - return; - // Adjust for device density & scale - m_selectText.updateHandleScale(getTextHandleScale()); -} - -// removes the cursor altogether (e.g., when going to a new page) -void clearCursor() -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return; - DBG_NAV_LOG(""); - m_viewImpl->m_hasCursorBounds = false; - root->clearCursor(); - viewInvalidate(); -} - -// leaves the cursor where it is, but suppresses drawing it -void hideCursor() -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return; - DBG_NAV_LOG(""); - hideCursor(root); - viewInvalidate(); -} - -void hideCursor(CachedRoot* root) -{ - DBG_NAV_LOG("inner"); - m_viewImpl->m_hasCursorBounds = false; - root->hideCursor(); -} - -#if DUMP_NAV_CACHE -void debugDump() -{ - CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) - root->mDebug.print(); -} -#endif - -void scrollToCurrentMatch() -{ - if (!m_findOnPage.currentMatchIsInLayer()) { - scrollRectOnScreen(m_findOnPage.currentMatchBounds()); - return; - } - - SkRect matchBounds = m_findOnPage.currentMatchBounds(); - LayerAndroid* rootLayer = getFrameCache(DontAllowNewer)->rootLayer(); - Layer* layerContainingMatch = rootLayer->findById(m_findOnPage.currentMatchLayerId()); - ASSERT(layerContainingMatch); - - // If the match is in a fixed position layer, there's nothing to do. - if (layerContainingMatch->shouldInheritFromRootTransform()) - return; - - // If the match is in a scrollable layer or a descendant of such a layer, - // there may be a range of of scroll configurations that will make the - // current match visible. Our approach is the simplest possible. Starting at - // the layer in which the match is found, we move up the layer tree, - // scrolling any scrollable layers as little as possible to make sure that - // the current match is in view. This approach has the disadvantage that we - // may end up scrolling a larger number of elements than is necessary, which - // may be visually jarring. However, minimising the number of layers - // scrolled would complicate the code significantly. - - bool didScrollLayer = false; - for (Layer* layer = layerContainingMatch; layer; layer = layer->getParent()) { - ASSERT(layer->getParent() || layer == rootLayer); - - if (layer->contentIsScrollable()) { - // Convert the match location to layer's local space and scroll it. - // Repeatedly calling Layer::localToAncestor() is inefficient as - // each call repeats part of the calculation. It would be more - // efficient to maintain the transform here and update it on each - // iteration, but that would mean duplicating logic from - // Layer::localToAncestor() and would complicate things. - SkMatrix transform; - layerContainingMatch->localToAncestor(layer, &transform); - SkRect transformedMatchBounds; - transform.mapRect(&transformedMatchBounds, matchBounds); - SkIRect roundedTransformedMatchBounds; - transformedMatchBounds.roundOut(&roundedTransformedMatchBounds); - // Only ScrollableLayerAndroid returns true for contentIsScrollable(). - didScrollLayer |= static_cast<ScrollableLayerAndroid*>(layer)->scrollRectIntoView(roundedTransformedMatchBounds); - } - } - // Invalidate, as the call below to scroll the main page may be a no-op. - if (didScrollLayer) - viewInvalidate(); - - // Convert matchBounds to the global space so we can scroll the main page. - SkMatrix transform; - layerContainingMatch->localToGlobal(&transform); - SkRect transformedMatchBounds; - transform.mapRect(&transformedMatchBounds, matchBounds); - SkIRect roundedTransformedMatchBounds; - transformedMatchBounds.roundOut(&roundedTransformedMatchBounds); - scrollRectOnScreen(roundedTransformedMatchBounds); -} - void scrollRectOnScreen(const IntRect& rect) { if (rect.isEmpty()) @@ -372,147 +231,59 @@ void scrollRectOnScreen(const IntRect& rect) int dx = 0; int left = rect.x(); int right = rect.maxX(); - if (left < m_visibleRect.fLeft) - dx = left - m_visibleRect.fLeft; + if (left < m_visibleContentRect.fLeft) + dx = left - m_visibleContentRect.fLeft; // Only scroll right if the entire width can fit on screen. - else if (right > m_visibleRect.fRight - && right - left < m_visibleRect.width()) - dx = right - m_visibleRect.fRight; + else if (right > m_visibleContentRect.fRight + && right - left < m_visibleContentRect.width()) + dx = right - m_visibleContentRect.fRight; int dy = 0; int top = rect.y(); int bottom = rect.maxY(); - if (top < m_visibleRect.fTop) - dy = top - m_visibleRect.fTop; + if (top < m_visibleContentRect.fTop) + dy = top - m_visibleContentRect.fTop; // Only scroll down if the entire height can fit on screen - else if (bottom > m_visibleRect.fBottom - && bottom - top < m_visibleRect.height()) - dy = bottom - m_visibleRect.fBottom; + else if (bottom > m_visibleContentRect.fBottom + && bottom - top < m_visibleContentRect.height()) + dy = bottom - m_visibleContentRect.fBottom; if ((dx|dy) == 0 || !scrollBy(dx, dy)) return; viewInvalidate(); } -void resetCursorRing() +int drawGL(WebCore::IntRect& invScreenRect, WebCore::IntRect* invalRect, + WebCore::IntRect& screenRect, int titleBarHeight, + WebCore::IntRect& screenClip, float scale, int extras, bool shouldDraw) { - m_ringAnimationEnd = 0; - m_viewImpl->m_hasCursorBounds = false; -} - -bool drawCursorPreamble(CachedRoot* root) -{ - if (!root) return false; - const CachedFrame* frame; - const CachedNode* node = root->currentCursor(&frame); - if (!node) { - DBG_NAV_LOGV("%s", "!node"); - resetCursorRing(); - return false; - } - m_ring.setIsButton(node); - if (node->isHidden()) { - DBG_NAV_LOG("node->isHidden()"); - m_viewImpl->m_hasCursorBounds = false; - return false; - } #if USE(ACCELERATED_COMPOSITING) - if (node->isInLayer() && root->rootLayer()) { - LayerAndroid* layer = root->rootLayer(); - layer->updateFixedLayersPositions(m_visibleRect); - layer->updatePositions(); - } -#endif - setVisibleRect(root); - m_ring.m_root = root; - m_ring.m_frame = frame; - m_ring.m_node = node; - SkMSec time = SkTime::GetMSecs(); - m_ring.m_isPressed = time < m_ringAnimationEnd - && m_ringAnimationEnd != UINT_MAX; - return true; -} - -void drawCursorPostamble() -{ - if (m_ringAnimationEnd == UINT_MAX) - return; - SkMSec time = SkTime::GetMSecs(); - if (time < m_ringAnimationEnd) { - // views assume that inval bounds coordinates are non-negative - WebCore::IntRect invalBounds(0, 0, INT_MAX, INT_MAX); - invalBounds.intersect(m_ring.m_absBounds); - postInvalidateDelayed(m_ringAnimationEnd - time, invalBounds); - } else { - hideCursor(const_cast<CachedRoot*>(m_ring.m_root)); - } -} + if (!m_baseLayer) + return 0; -bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, - WebCore::IntRect& webViewRect, int titleBarHeight, - WebCore::IntRect& clip, float scale, int extras) -{ -#if USE(ACCELERATED_COMPOSITING) - if (!m_baseLayer || inFullScreenMode()) - return false; + if (m_viewImpl) + m_viewImpl->setPrerenderingEnabled(!m_isDrawingPaused); if (!m_glWebViewState) { + TilesManager::instance()->setHighEndGfx(m_isHighEndGfx); m_glWebViewState = new GLWebViewState(); - m_glWebViewState->setHighEndGfx(m_isHighEndGfx); - m_glWebViewState->glExtras()->setCursorRingExtra(&m_ring); - m_glWebViewState->glExtras()->setFindOnPageExtra(&m_findOnPage); - if (m_baseLayer->content()) { - SkRegion region; - SkIRect rect; - rect.set(0, 0, m_baseLayer->content()->width(), m_baseLayer->content()->height()); - region.setRect(rect); - m_glWebViewState->setBaseLayer(m_baseLayer, region, false, true); - } + m_glWebViewState->setBaseLayer(m_baseLayer, false, true); } - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - if (extras == DrawExtrasCursorRing) - resetCursorRing(); - } - DrawExtra* extra = 0; - switch (extras) { - case DrawExtrasFind: - extra = &m_findOnPage; - break; - case DrawExtrasSelection: - // This will involve a JNI call, but under normal circumstances we will - // not hit this anyway. Only if USE_JAVA_TEXT_SELECTION is disabled - // in WebView.java will we hit this (so really debug only) - updateSelectionHandles(); - extra = &m_selectText; - break; - case DrawExtrasCursorRing: - if (drawCursorPreamble(root) && m_ring.setup()) { - if (m_ring.m_isPressed || m_ringAnimationEnd == UINT_MAX) - extra = &m_ring; - drawCursorPostamble(); - } - break; - default: - ; - } + DrawExtra* extra = getDrawExtra((DrawExtras) extras); - unsigned int pic = m_glWebViewState->currentPictureCounter(); m_glWebViewState->glExtras()->setDrawExtra(extra); // Make sure we have valid coordinates. We might not have valid coords // if the zoom manager is still initializing. We will be redrawn // once the correct scale is set - if (!m_visibleRect.isFinite()) - return false; + if (!m_visibleContentRect.isFinite()) + return 0; bool treesSwapped = false; bool newTreeHasAnim = false; - bool ret = m_glWebViewState->drawGL(viewRect, m_visibleRect, invalRect, - webViewRect, titleBarHeight, clip, scale, - &treesSwapped, &newTreeHasAnim); - if (treesSwapped && (m_pageSwapCallbackRegistered || newTreeHasAnim)) { - m_pageSwapCallbackRegistered = false; - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); + int ret = m_glWebViewState->drawGL(invScreenRect, m_visibleContentRect, invalRect, + screenRect, titleBarHeight, screenClip, scale, + &treesSwapped, &newTreeHasAnim, shouldDraw); + if (treesSwapped) { + ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject javaObject = m_javaGlue.object(env); if (javaObject.get()) { @@ -520,237 +291,45 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, checkException(env); } } - if (ret || m_glWebViewState->currentPictureCounter() != pic) - return !m_isDrawingPaused; + return m_isDrawingPaused ? 0 : ret; #endif - return false; + return 0; } -PictureSet* draw(SkCanvas* canvas, SkColor bgColor, int extras, bool split) +void draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras) { - PictureSet* ret = 0; if (!m_baseLayer) { canvas->drawColor(bgColor); - return ret; + return; } // draw the content of the base layer first - PictureSet* content = m_baseLayer->content(); + LayerContent* content = m_baseLayer->content(); int sc = canvas->save(SkCanvas::kClip_SaveFlag); - canvas->clipRect(SkRect::MakeLTRB(0, 0, content->width(), - content->height()), SkRegion::kDifference_Op); - canvas->drawColor(bgColor); - canvas->restoreToCount(sc); - if (content->draw(canvas)) - ret = split ? new PictureSet(*content) : 0; - - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - if (extras == DrawExtrasCursorRing) - resetCursorRing(); - } - LayerAndroid mainPicture(m_navPictureUI); - DrawExtra* extra = 0; - switch (extras) { - case DrawExtrasFind: - extra = &m_findOnPage; - break; - case DrawExtrasSelection: - // This will involve a JNI call, but under normal circumstances we will - // not hit this anyway. Only if USE_JAVA_TEXT_SELECTION is disabled - // in WebView.java will we hit this (so really debug only) - updateSelectionHandles(); - extra = &m_selectText; - break; - case DrawExtrasCursorRing: - if (drawCursorPreamble(root) && m_ring.setup()) { - extra = &m_ring; - drawCursorPostamble(); - } - break; - default: - ; - } -#if USE(ACCELERATED_COMPOSITING) - LayerAndroid* compositeLayer = compositeRoot(); - if (compositeLayer) { - // call this to be sure we've adjusted for any scrolling or animations - // before we actually draw - compositeLayer->updateFixedLayersPositions(m_visibleRect); - compositeLayer->updatePositions(); - // We have to set the canvas' matrix on the base layer - // (to have fixed layers work as intended) - SkAutoCanvasRestore restore(canvas, true); - m_baseLayer->setMatrix(canvas->getTotalMatrix()); - canvas->resetMatrix(); - m_baseLayer->draw(canvas); - } -#endif - if (extra) { - IntRect dummy; // inval area, unused for now - extra->draw(canvas, &mainPicture, &dummy); - } - return ret; -} - - -bool cursorIsTextInput(FrameCachePermission allowNewer) -{ - CachedRoot* root = getFrameCache(allowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return false; - } - const CachedNode* cursor = root->currentCursor(); - if (!cursor) { - DBG_NAV_LOG("!cursor"); - return false; + if (content) { + canvas->clipRect(SkRect::MakeLTRB(0, 0, content->width(), content->height()), + SkRegion::kDifference_Op); } - DBG_NAV_LOGD("%s", cursor->isTextInput() ? "true" : "false"); - return cursor->isTextInput(); -} - -void cursorRingBounds(WebCore::IntRect* bounds) -{ - DBG_NAV_LOGD("%s", ""); - CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) { - const CachedFrame* cachedFrame; - const CachedNode* cachedNode = root->currentCursor(&cachedFrame); - if (cachedNode) { - *bounds = cachedNode->cursorRingBounds(cachedFrame); - DBG_NAV_LOGD("bounds={%d,%d,%d,%d}", bounds->x(), bounds->y(), - bounds->width(), bounds->height()); - return; - } - } - *bounds = WebCore::IntRect(0, 0, 0, 0); -} + Color c = m_baseLayer->getBackgroundColor(); + canvas->drawColor(SkColorSetARGBInline(c.alpha(), c.red(), c.green(), c.blue())); + canvas->restoreToCount(sc); -void fixCursor() -{ - m_viewImpl->gCursorBoundsMutex.lock(); - bool hasCursorBounds = m_viewImpl->m_hasCursorBounds; - IntRect bounds = m_viewImpl->m_cursorBounds; - m_viewImpl->gCursorBoundsMutex.unlock(); - if (!hasCursorBounds) - return; - int x, y; - const CachedFrame* frame; - const CachedNode* node = m_frameCacheUI->findAt(bounds, &frame, &x, &y, true); - if (!node) - return; - // require that node have approximately the same bounds (+/- 4) and the same - // center (+/- 2) - IntPoint oldCenter = IntPoint(bounds.x() + (bounds.width() >> 1), - bounds.y() + (bounds.height() >> 1)); - IntRect newBounds = node->bounds(frame); - IntPoint newCenter = IntPoint(newBounds.x() + (newBounds.width() >> 1), - newBounds.y() + (newBounds.height() >> 1)); - DBG_NAV_LOGD("oldCenter=(%d,%d) newCenter=(%d,%d)" - " bounds=(%d,%d,w=%d,h=%d) newBounds=(%d,%d,w=%d,h=%d)", - oldCenter.x(), oldCenter.y(), newCenter.x(), newCenter.y(), - bounds.x(), bounds.y(), bounds.width(), bounds.height(), - newBounds.x(), newBounds.y(), newBounds.width(), newBounds.height()); - if (abs(oldCenter.x() - newCenter.x()) > 2) - return; - if (abs(oldCenter.y() - newCenter.y()) > 2) - return; - if (abs(bounds.x() - newBounds.x()) > 4) - return; - if (abs(bounds.y() - newBounds.y()) > 4) - return; - if (abs(bounds.maxX() - newBounds.maxX()) > 4) - return; - if (abs(bounds.maxY() - newBounds.maxY()) > 4) - return; - DBG_NAV_LOGD("node=%p frame=%p x=%d y=%d bounds=(%d,%d,w=%d,h=%d)", - node, frame, x, y, bounds.x(), bounds.y(), bounds.width(), - bounds.height()); - m_frameCacheUI->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); -} + // call this to be sure we've adjusted for any scrolling or animations + // before we actually draw + m_baseLayer->updatePositionsRecursive(m_visibleContentRect); + m_baseLayer->updatePositions(); -CachedRoot* getFrameCache(FrameCachePermission allowNewer) -{ - if (!m_viewImpl->m_updatedFrameCache) { - DBG_NAV_LOGV("%s", "!m_viewImpl->m_updatedFrameCache"); - return m_frameCacheUI; - } - if (allowNewer == DontAllowNewer && m_viewImpl->m_lastGeneration < m_generation) { - DBG_NAV_LOGD("allowNewer==DontAllowNewer m_viewImpl->m_lastGeneration=%d" - " < m_generation=%d", m_viewImpl->m_lastGeneration, m_generation); - return m_frameCacheUI; - } - DBG_NAV_LOGD("%s", "m_viewImpl->m_updatedFrameCache == true"); - const CachedFrame* oldCursorFrame; - const CachedNode* oldCursorNode = m_frameCacheUI ? - m_frameCacheUI->currentCursor(&oldCursorFrame) : 0; -#if USE(ACCELERATED_COMPOSITING) - int layerId = -1; - if (oldCursorNode && oldCursorNode->isInLayer()) { - const LayerAndroid* cursorLayer = oldCursorFrame->layer(oldCursorNode) - ->layer(m_frameCacheUI->rootLayer()); - if (cursorLayer) - layerId = cursorLayer->uniqueId(); - } -#endif - // get id from old layer and use to find new layer - bool oldFocusIsTextInput = false; - void* oldFocusNodePointer = 0; - if (m_frameCacheUI) { - const CachedNode* oldFocus = m_frameCacheUI->currentFocus(); - if (oldFocus) { - oldFocusIsTextInput = oldFocus->isTextInput(); - oldFocusNodePointer = oldFocus->nodePointer(); - } - } - m_viewImpl->gFrameCacheMutex.lock(); - delete m_frameCacheUI; - SkSafeUnref(m_navPictureUI); - m_viewImpl->m_updatedFrameCache = false; - m_frameCacheUI = m_viewImpl->m_frameCacheKit; - m_navPictureUI = m_viewImpl->m_navPictureKit; - m_viewImpl->m_frameCacheKit = 0; - m_viewImpl->m_navPictureKit = 0; - m_viewImpl->gFrameCacheMutex.unlock(); - if (m_frameCacheUI) - m_frameCacheUI->setRootLayer(compositeRoot()); -#if USE(ACCELERATED_COMPOSITING) - if (layerId >= 0) { - LayerAndroid* layer = const_cast<LayerAndroid*>( - m_frameCacheUI->rootLayer()); - if (layer) { - layer->updateFixedLayersPositions(m_visibleRect); - layer->updatePositions(); - } - } -#endif - fixCursor(); - if (oldFocusIsTextInput) { - const CachedNode* newFocus = m_frameCacheUI->currentFocus(); - if (newFocus && oldFocusNodePointer != newFocus->nodePointer() - && newFocus->isTextInput() - && newFocus != m_frameCacheUI->currentCursor()) { - // The focus has changed. We may need to update things. - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue.object(env); - if (javaObject.get()) { - env->CallVoidMethod(javaObject.get(), m_javaGlue.m_domChangedFocus); - checkException(env); - } - } - } - if (oldCursorNode && (!m_frameCacheUI || !m_frameCacheUI->currentCursor())) - viewInvalidate(); // redraw in case cursor ring is still visible - return m_frameCacheUI; + // We have to set the canvas' matrix on the base layer + // (to have fixed layers work as intended) + SkAutoCanvasRestore restore(canvas, true); + m_baseLayer->setMatrix(canvas->getTotalMatrix()); + canvas->resetMatrix(); + m_baseLayer->draw(canvas, getDrawExtra(extras)); } int getScaledMaxXScroll() { - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); + ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject javaObject = m_javaGlue.object(env); if (!javaObject.get()) @@ -762,7 +341,7 @@ int getScaledMaxXScroll() int getScaledMaxYScroll() { - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); + ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject javaObject = m_javaGlue.object(env); if (!javaObject.get()) @@ -772,294 +351,37 @@ int getScaledMaxYScroll() return result; } -IntRect getVisibleRect() +// Call through JNI to ask Java side to update the rectangles for GL functor. +// This is called at every draw when it is not in process mode, so we should +// keep this route as efficient as possible. Currently, its average cost on Xoom +// is about 0.1ms - 0.2ms. +// Alternatively, this can be achieved by adding more listener on Java side, but +// that will be more likely causing jank when triggering GC. +void updateRectsForGL() { - IntRect rect; - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject javaObject = m_javaGlue.object(env); if (!javaObject.get()) - return rect; - jobject jRect = env->CallObjectMethod(javaObject.get(), m_javaGlue.m_getVisibleRect); - checkException(env); - rect.setX(env->GetIntField(jRect, m_javaGlue.m_rectLeft)); - checkException(env); - rect.setY(env->GetIntField(jRect, m_javaGlue.m_rectTop)); - checkException(env); - rect.setWidth(env->CallIntMethod(jRect, m_javaGlue.m_rectWidth)); - checkException(env); - rect.setHeight(env->CallIntMethod(jRect, m_javaGlue.m_rectHeight)); - checkException(env); - env->DeleteLocalRef(jRect); - checkException(env); - return rect; -} - -static CachedFrame::Direction KeyToDirection(int32_t keyCode) -{ - switch (keyCode) { - case AKEYCODE_DPAD_RIGHT: - DBG_NAV_LOGD("keyCode=%s", "right"); - return CachedFrame::RIGHT; - case AKEYCODE_DPAD_LEFT: - DBG_NAV_LOGD("keyCode=%s", "left"); - return CachedFrame::LEFT; - case AKEYCODE_DPAD_DOWN: - DBG_NAV_LOGD("keyCode=%s", "down"); - return CachedFrame::DOWN; - case AKEYCODE_DPAD_UP: - DBG_NAV_LOGD("keyCode=%s", "up"); - return CachedFrame::UP; - default: - DBG_NAV_LOGD("bad key %d sent", keyCode); - return CachedFrame::UNINITIALIZED; - } -} - -WTF::String imageURI(int x, int y) -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - return root ? root->imageURI(x, y) : WTF::String(); -} - -bool cursorWantsKeyEvents() -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) { - const CachedNode* focus = root->currentCursor(); - if (focus) - return focus->wantsKeyEvents(); - } - return false; -} - - -/* returns true if the key had no effect (neither scrolled nor changed cursor) */ -bool moveCursor(int keyCode, int count, bool ignoreScroll) -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return true; - } - - m_viewImpl->m_moveGeneration++; - CachedFrame::Direction direction = KeyToDirection(keyCode); - const CachedFrame* cachedFrame, * oldFrame = 0; - const CachedNode* cursor = root->currentCursor(&oldFrame); - WebCore::IntPoint cursorLocation = root->cursorLocation(); - DBG_NAV_LOGD("old cursor %d (nativeNode=%p) cursorLocation={%d, %d}", - cursor ? cursor->index() : 0, - cursor ? cursor->nodePointer() : 0, cursorLocation.x(), cursorLocation.y()); - WebCore::IntRect visibleRect = setVisibleRect(root); - int xMax = getScaledMaxXScroll(); - int yMax = getScaledMaxYScroll(); - root->setMaxScroll(xMax, yMax); - const CachedNode* cachedNode = 0; - int dx = 0; - int dy = 0; - int counter = count; - while (--counter >= 0) { - WebCore::IntPoint scroll = WebCore::IntPoint(0, 0); - cachedNode = root->moveCursor(direction, &cachedFrame, &scroll); - dx += scroll.x(); - dy += scroll.y(); - } - DBG_NAV_LOGD("new cursor %d (nativeNode=%p) cursorLocation={%d, %d}" - "bounds={%d,%d,w=%d,h=%d}", cachedNode ? cachedNode->index() : 0, - cachedNode ? cachedNode->nodePointer() : 0, - root->cursorLocation().x(), root->cursorLocation().y(), - cachedNode ? cachedNode->bounds(cachedFrame).x() : 0, - cachedNode ? cachedNode->bounds(cachedFrame).y() : 0, - cachedNode ? cachedNode->bounds(cachedFrame).width() : 0, - cachedNode ? cachedNode->bounds(cachedFrame).height() : 0); - // If !m_heightCanMeasure (such as in the browser), we want to scroll no - // matter what - if (!ignoreScroll && (!m_heightCanMeasure || - !cachedNode || - (cursor && cursor->nodePointer() == cachedNode->nodePointer()))) - { - if (count == 1 && dx != 0 && dy == 0 && -m_lastDx == dx && - SkTime::GetMSecs() - m_lastDxTime < 1000) - root->checkForJiggle(&dx); - DBG_NAV_LOGD("scrollBy %d,%d", dx, dy); - if ((dx | dy)) - this->scrollBy(dx, dy); - m_lastDx = dx; - m_lastDxTime = SkTime::GetMSecs(); - } - bool result = false; - if (cachedNode) { - showCursorUntimed(); - m_viewImpl->updateCursorBounds(root, cachedFrame, cachedNode); - root->setCursor(const_cast<CachedFrame*>(cachedFrame), - const_cast<CachedNode*>(cachedNode)); - const CachedNode* focus = root->currentFocus(); - bool clearTextEntry = cachedNode != focus && focus - && cachedNode->nodePointer() != focus->nodePointer() && focus->isTextInput(); - // Stop painting the caret if the old focus was a text input and so is the new cursor. - bool stopPaintingCaret = clearTextEntry && cachedNode->wantsKeyEvents(); - sendMoveMouseIfLatest(clearTextEntry, stopPaintingCaret); - } else { - int docHeight = root->documentHeight(); - int docWidth = root->documentWidth(); - if (visibleRect.maxY() + dy > docHeight) - dy = docHeight - visibleRect.maxY(); - else if (visibleRect.y() + dy < 0) - dy = -visibleRect.y(); - if (visibleRect.maxX() + dx > docWidth) - dx = docWidth - visibleRect.maxX(); - else if (visibleRect.x() < 0) - dx = -visibleRect.x(); - result = direction == CachedFrame::LEFT ? dx >= 0 : - direction == CachedFrame::RIGHT ? dx <= 0 : - direction == CachedFrame::UP ? dy >= 0 : dy <= 0; - } - return result; -} - -void notifyProgressFinished() -{ - DBG_NAV_LOGD("cursorIsTextInput=%d", cursorIsTextInput(DontAllowNewer)); - rebuildWebTextView(); -#if DEBUG_NAV_UI - if (m_frameCacheUI) { - const CachedNode* focus = m_frameCacheUI->currentFocus(); - DBG_NAV_LOGD("focus %d (nativeNode=%p)", - focus ? focus->index() : 0, - focus ? focus->nodePointer() : 0); - } -#endif -} - -const CachedNode* findAt(CachedRoot* root, const WebCore::IntRect& rect, - const CachedFrame** framePtr, int* rxPtr, int* ryPtr) -{ - *rxPtr = 0; - *ryPtr = 0; - *framePtr = 0; - if (!root) - return 0; - setVisibleRect(root); - return root->findAt(rect, framePtr, rxPtr, ryPtr, true); -} - -IntRect setVisibleRect(CachedRoot* root) -{ - IntRect visibleRect = getVisibleRect(); - DBG_NAV_LOGD("getVisibleRect %d,%d,%d,%d", - visibleRect.x(), visibleRect.y(), visibleRect.width(), visibleRect.height()); - root->setVisibleRect(visibleRect); - return visibleRect; -} - -void selectBestAt(const WebCore::IntRect& rect) -{ - const CachedFrame* frame; - int rx, ry; - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) return; - const CachedNode* node = findAt(root, rect, &frame, &rx, &ry); - if (!node) { - DBG_NAV_LOGD("no nodes found root=%p", root); - root->rootHistory()->setMouseBounds(rect); - m_viewImpl->m_hasCursorBounds = false; - root->setCursor(0, 0); - viewInvalidate(); - } else { - DBG_NAV_LOGD("CachedNode:%p (%d)", node, node->index()); - WebCore::IntRect bounds = node->bounds(frame); - root->rootHistory()->setMouseBounds(bounds); - m_viewImpl->updateCursorBounds(root, frame, node); - showCursorTimed(); - root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); - } - sendMoveMouseIfLatest(false, false); -} - -const CachedNode* m_cacheHitNode; -const CachedFrame* m_cacheHitFrame; - -bool pointInNavCache(int x, int y, int slop) -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return false; - IntRect rect = IntRect(x - slop, y - slop, slop * 2, slop * 2); - int rx, ry; - return (m_cacheHitNode = findAt(root, rect, &m_cacheHitFrame, &rx, &ry)); -} - -bool motionUp(int x, int y, int slop) -{ - bool pageScrolled = false; - IntRect rect = IntRect(x - slop, y - slop, slop * 2, slop * 2); - int rx, ry; - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return 0; - const CachedFrame* frame = 0; - const CachedNode* result = findAt(root, rect, &frame, &rx, &ry); - CachedHistory* history = root->rootHistory(); - if (!result) { - DBG_NAV_LOGD("no nodes found root=%p", root); - history->setNavBounds(rect); - m_viewImpl->m_hasCursorBounds = false; - root->hideCursor(); - int dx = root->checkForCenter(x, y); - if (dx) { - scrollBy(dx, 0); - pageScrolled = true; - } - sendMotionUp(frame ? (WebCore::Frame*) frame->framePointer() : 0, - 0, x, y); - viewInvalidate(); - return pageScrolled; - } - DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result, - result->index(), x, y, rx, ry); - WebCore::IntRect navBounds = WebCore::IntRect(rx, ry, 1, 1); - history->setNavBounds(navBounds); - history->setMouseBounds(navBounds); - m_viewImpl->updateCursorBounds(root, frame, result); - root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(result)); - if (result->isSyntheticLink()) - overrideUrlLoading(result->getExport()); - else { - sendMotionUp( - (WebCore::Frame*) frame->framePointer(), - (WebCore::Node*) result->nodePointer(), rx, ry); - } - if (result->isTextInput() || result->isSelect() - || result->isContentEditable()) { - showCursorUntimed(); - } else - showCursorTimed(); - return pageScrolled; + env->CallVoidMethod(javaObject.get(), m_javaGlue.m_updateRectsForGL); + checkException(env); } #if USE(ACCELERATED_COMPOSITING) static const ScrollableLayerAndroid* findScrollableLayer( const LayerAndroid* parent, int x, int y, SkIRect* foundBounds) { - SkRect bounds; - parent->bounds(&bounds); + IntRect bounds = enclosingIntRect(parent->fullContentAreaMapped()); + // Check the parent bounds first; this will clip to within a masking layer's // bounds. if (parent->masksToBounds() && !bounds.contains(x, y)) return 0; - // Move the hit test local to parent. - x -= bounds.fLeft; - y -= bounds.fTop; + int count = parent->countChildren(); while (count--) { const LayerAndroid* child = parent->getChild(count); - const ScrollableLayerAndroid* result = findScrollableLayer(child, x, y, - foundBounds); + const ScrollableLayerAndroid* result = findScrollableLayer(child, x, y, foundBounds); if (result) { - foundBounds->offset(bounds.fLeft, bounds.fTop); if (parent->masksToBounds()) { if (bounds.width() < foundBounds->width()) foundBounds->fRight = foundBounds->fLeft + bounds.width(); @@ -1070,7 +392,7 @@ static const ScrollableLayerAndroid* findScrollableLayer( } } if (parent->contentIsScrollable()) { - foundBounds->set(0, 0, bounds.width(), bounds.height()); + foundBounds->set(bounds.x(), bounds.y(), bounds.width(), bounds.height()); return static_cast<const ScrollableLayerAndroid*>(parent); } return 0; @@ -1080,11 +402,9 @@ static const ScrollableLayerAndroid* findScrollableLayer( int scrollableLayer(int x, int y, SkIRect* layerRect, SkIRect* bounds) { #if USE(ACCELERATED_COMPOSITING) - const LayerAndroid* layerRoot = compositeRoot(); - if (!layerRoot) + if (!m_baseLayer) return 0; - const ScrollableLayerAndroid* result = findScrollableLayer(layerRoot, x, y, - bounds); + const ScrollableLayerAndroid* result = findScrollableLayer(m_baseLayer, x, y, bounds); if (result) { result->getScrollRect(layerRect); return result->uniqueId(); @@ -1099,52 +419,6 @@ void scrollLayer(int layerId, int x, int y) m_glWebViewState->scrollLayer(layerId, x, y); } -int getBlockLeftEdge(int x, int y, float scale) -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (root) - return root->getBlockLeftEdge(x, y, scale); - return -1; -} - -void overrideUrlLoading(const WTF::String& url) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue.object(env); - if (!javaObject.get()) - return; - jstring jName = wtfStringToJstring(env, url); - env->CallVoidMethod(javaObject.get(), m_javaGlue.m_overrideLoading, jName); - env->DeleteLocalRef(jName); -} - -void setFindIsUp(bool up) -{ - DBG_NAV_LOGD("up=%d", up); - m_viewImpl->m_findIsUp = up; -} - -void setFindIsEmpty() -{ - DBG_NAV_LOG(""); - m_findOnPage.clearCurrentLocation(); -} - -void showCursorTimed() -{ - DBG_NAV_LOG(""); - m_ringAnimationEnd = SkTime::GetMSecs() + PRESSED_STATE_DURATION; - viewInvalidate(); -} - -void showCursorUntimed() -{ - DBG_NAV_LOG(""); - m_ring.m_isPressed = false; - m_ringAnimationEnd = UINT_MAX; - viewInvalidate(); -} - void setHeightCanMeasure(bool measure) { m_heightCanMeasure = measure; @@ -1152,170 +426,16 @@ void setHeightCanMeasure(bool measure) String getSelection() { - return m_selectText.getSelection(); -} - -void moveSelection(int x, int y) -{ - m_selectText.moveSelection(getVisibleRect(), x, y); -} - -IntPoint selectableText() -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) - return IntPoint(0, 0); - return m_selectText.selectableText(root); -} - -void selectAll() -{ - m_selectText.selectAll(); -} - -int selectionX() -{ - return m_selectText.selectionX(); -} - -int selectionY() -{ - return m_selectText.selectionY(); -} - -void resetSelection() -{ - m_selectText.reset(); -} - -bool startSelection(int x, int y) -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) - return false; - updateSelectionHandles(); - return m_selectText.startSelection(root, getVisibleRect(), x, y); -} - -bool wordSelection(int x, int y) -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) - return false; - updateSelectionHandles(); - return m_selectText.wordSelection(root, getVisibleRect(), x, y); -} - -bool extendSelection(int x, int y) -{ - m_selectText.extendSelection(getVisibleRect(), x, y); - return true; -} - -bool hitSelection(int x, int y) -{ - updateSelectionHandles(); - return m_selectText.hitSelection(x, y); -} - -void setExtendSelection() -{ - m_selectText.setExtendSelection(true); -} - -void setSelectionPointer(bool set, float scale, int x, int y) -{ - m_selectText.setDrawPointer(set); - if (!set) - return; - m_selectText.m_inverseScale = scale; - m_selectText.m_selectX = x; - m_selectText.m_selectY = y; -} - -void sendMoveFocus(WebCore::Frame* framePtr, WebCore::Node* nodePtr) -{ - DBG_NAV_LOGD("framePtr=%p nodePtr=%p", framePtr, nodePtr); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue.object(env); - if (!javaObject.get()) - return; - env->CallVoidMethod(javaObject.get(), m_javaGlue.m_sendMoveFocus, (jint) framePtr, (jint) nodePtr); - checkException(env); -} - -void sendMoveMouse(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y) -{ - DBG_NAV_LOGD("framePtr=%p nodePtr=%p x=%d y=%d", framePtr, nodePtr, x, y); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue.object(env); - if (!javaObject.get()) - return; - env->CallVoidMethod(javaObject.get(), m_javaGlue.m_sendMoveMouse, reinterpret_cast<jint>(framePtr), reinterpret_cast<jint>(nodePtr), x, y); - checkException(env); -} - -void sendMoveMouseIfLatest(bool clearTextEntry, bool stopPaintingCaret) -{ - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue.object(env); - if (!javaObject.get()) - return; - env->CallVoidMethod(javaObject.get(), m_javaGlue.m_sendMoveMouseIfLatest, clearTextEntry, stopPaintingCaret); - checkException(env); -} - -void sendMotionUp(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y) -{ - DBG_NAV_LOGD("m_generation=%d framePtr=%p nodePtr=%p x=%d y=%d", m_generation, framePtr, nodePtr, x, y); - LOG_ASSERT(m_javaGlue.m_obj, "A WebView was not associated with this WebViewNative!"); - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue.object(env); - if (!javaObject.get()) - return; - m_viewImpl->m_touchGeneration = ++m_generation; - env->CallVoidMethod(javaObject.get(), m_javaGlue.m_sendMotionUp, m_generation, (jint) framePtr, (jint) nodePtr, x, y); - checkException(env); -} - -void findNext(bool forward) -{ - m_findOnPage.findNext(forward); - scrollToCurrentMatch(); - viewInvalidate(); -} - -// With this call, WebView takes ownership of matches, and is responsible for -// deleting it. -void setMatches(WTF::Vector<MatchInfo>* matches, jboolean sameAsLastSearch) -{ - // If this search is the same as the last one, check against the old - // location to determine whether to scroll. If the same word is found - // in the same place, then do not scroll. - IntRect oldLocation; - bool checkAgainstOldLocation = false; - if (sameAsLastSearch && m_findOnPage.isCurrentLocationValid()) { - oldLocation = m_findOnPage.currentMatchBounds(); - checkAgainstOldLocation = true; - } - - m_findOnPage.setMatches(matches); - - if (!checkAgainstOldLocation || oldLocation != m_findOnPage.currentMatchBounds()) - scrollToCurrentMatch(); - viewInvalidate(); -} - -int currentMatchIndex() -{ - return m_findOnPage.currentMatchIndex(); + SelectText* select = static_cast<SelectText*>( + getDrawExtra(WebView::DrawExtrasSelection)); + if (select) + return select->getText(); + return String(); } bool scrollBy(int dx, int dy) { - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); + ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject javaObject = m_javaGlue.object(env); @@ -1334,44 +454,6 @@ void setIsScrolling(bool isScrolling) #endif } -bool hasCursorNode() -{ - CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return false; - } - const CachedNode* cursorNode = root->currentCursor(); - DBG_NAV_LOGD("cursorNode=%d (nodePointer=%p)", - cursorNode ? cursorNode->index() : -1, - cursorNode ? cursorNode->nodePointer() : 0); - return cursorNode; -} - -bool hasFocusNode() -{ - CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return false; - } - const CachedNode* focusNode = root->currentFocus(); - DBG_NAV_LOGD("focusNode=%d (nodePointer=%p)", - focusNode ? focusNode->index() : -1, - focusNode ? focusNode->nodePointer() : 0); - return focusNode; -} - -void rebuildWebTextView() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue.object(env); - if (!javaObject.get()) - return; - env->CallVoidMethod(javaObject.get(), m_javaGlue.m_rebuildWebTextView); - checkException(env); -} - void viewInvalidate() { JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -1403,112 +485,64 @@ void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds) checkException(env); } -bool inFullScreenMode() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue.object(env); - if (!javaObject.get()) - return false; - jboolean result = env->CallBooleanMethod(javaObject.get(), m_javaGlue.m_inFullScreenMode); - checkException(env); - return result; -} - -int moveGeneration() -{ - return m_viewImpl->m_moveGeneration; -} - -LayerAndroid* compositeRoot() const -{ - LOG_ASSERT(!m_baseLayer || m_baseLayer->countChildren() == 1, - "base layer can't have more than one child %s", __FUNCTION__); - if (m_baseLayer && m_baseLayer->countChildren() == 1) - return static_cast<LayerAndroid*>(m_baseLayer->getChild(0)); - else - return 0; -} - #if ENABLE(ANDROID_OVERFLOW_SCROLL) -static void copyScrollPositionRecursive(const LayerAndroid* from, - LayerAndroid* root) +static void copyScrollPosition(const LayerAndroid* fromRoot, + LayerAndroid* toRoot, int layerId) { - if (!from || !root) + if (!fromRoot || !toRoot) return; - for (int i = 0; i < from->countChildren(); i++) { - const LayerAndroid* l = from->getChild(i); - if (l->contentIsScrollable()) { - const SkPoint& pos = l->getPosition(); - LayerAndroid* match = root->findById(l->uniqueId()); - if (match && match->contentIsScrollable()) - match->setPosition(pos.fX, pos.fY); - } - copyScrollPositionRecursive(l, root); - } + const LayerAndroid* from = fromRoot->findById(layerId); + LayerAndroid* to = toRoot->findById(layerId); + if (!from || !to || !from->contentIsScrollable() || !to->contentIsScrollable()) + return; + // TODO: Support this for iframes. + if (to->isIFrameContent() || from->isIFrameContent()) + return; + to->setScrollOffset(from->getScrollOffset()); } #endif -void registerPageSwapCallback() -{ - m_pageSwapCallbackRegistered = true; -} +BaseLayerAndroid* getBaseLayer() const { return m_baseLayer; } -void setBaseLayer(BaseLayerAndroid* layer, SkRegion& inval, bool showVisualIndicator, - bool isPictureAfterFirstLayout, bool registerPageSwapCallback) +bool setBaseLayer(BaseLayerAndroid* newBaseLayer, bool showVisualIndicator, + bool isPictureAfterFirstLayout, int scrollingLayer) { + bool queueFull = false; #if USE(ACCELERATED_COMPOSITING) if (m_glWebViewState) - m_glWebViewState->setBaseLayer(layer, inval, showVisualIndicator, - isPictureAfterFirstLayout); - m_pageSwapCallbackRegistered |= registerPageSwapCallback; + queueFull = m_glWebViewState->setBaseLayer(newBaseLayer, showVisualIndicator, + isPictureAfterFirstLayout); #endif #if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (layer) { - // TODO: the below tree copies are only necessary in software rendering - LayerAndroid* newCompositeRoot = static_cast<LayerAndroid*>(layer->getChild(0)); - copyScrollPositionRecursive(compositeRoot(), newCompositeRoot); - } + copyScrollPosition(m_baseLayer, newBaseLayer, scrollingLayer); #endif SkSafeUnref(m_baseLayer); - m_baseLayer = layer; - CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) - return; - root->resetLayers(); - root->setRootLayer(compositeRoot()); -} - -void getTextSelectionRegion(SkRegion *region) -{ - m_selectText.getSelectionRegion(getVisibleRect(), region, compositeRoot()); -} - -void getTextSelectionHandles(int* handles) -{ - m_selectText.getSelectionHandles(handles, compositeRoot()); -} + m_baseLayer = newBaseLayer; -void replaceBaseContent(PictureSet* set) -{ - if (!m_baseLayer) - return; - m_baseLayer->setContent(*set); - delete set; + return queueFull; } void copyBaseContentToPicture(SkPicture* picture) { - if (!m_baseLayer) + if (!m_baseLayer || !m_baseLayer->content()) return; - PictureSet* content = m_baseLayer->content(); - m_baseLayer->drawCanvas(picture->beginRecording(content->width(), content->height(), - SkPicture::kUsePathBoundsForClip_RecordingFlag)); + LayerContent* content = m_baseLayer->content(); + SkCanvas* canvas = picture->beginRecording(content->width(), content->height(), + SkPicture::kUsePathBoundsForClip_RecordingFlag); + + // clear the BaseLayerAndroid's previous matrix (set at each draw) + SkMatrix baseMatrix; + baseMatrix.reset(); + m_baseLayer->setMatrix(baseMatrix); + + m_baseLayer->draw(canvas, 0); + picture->endRecording(); } bool hasContent() { - if (!m_baseLayer) + if (!m_baseLayer || !m_baseLayer->content()) return false; return !m_baseLayer->content()->isEmpty(); } @@ -1522,37 +556,197 @@ Functor* getFunctor() { return m_glDrawFunctor; } -BaseLayerAndroid* getBaseLayer() { - return m_baseLayer; +void setVisibleContentRect(SkRect& visibleContentRect) { + m_visibleContentRect = visibleContentRect; +} + +void setDrawExtra(DrawExtra *extra, DrawExtras type) +{ + if (type == DrawExtrasNone) + return; + DrawExtra* old = m_extras[type - 1]; + m_extras[type - 1] = extra; + if (old != extra) { + delete old; + } +} + +void setTextSelection(SelectText *selection) { + setDrawExtra(selection, DrawExtrasSelection); } -void setVisibleRect(SkRect& visibleRect) { - m_visibleRect = visibleRect; +const TransformationMatrix* getLayerTransform(int layerId) { + if (layerId != -1 && m_baseLayer) { + LayerAndroid* layer = m_baseLayer->findById(layerId); + // We need to make sure the drawTransform is up to date as this is + // called before a draw() or drawGL() + if (layer) { + m_baseLayer->updatePositionsRecursive(m_visibleContentRect); + return layer->drawTransform(); + } + } + return 0; +} + +int getHandleLayerId(SelectText::HandleId handleId, SkIPoint& cursorPoint, + FloatQuad& textBounds) { + SelectText* selectText = static_cast<SelectText*>(getDrawExtra(DrawExtrasSelection)); + if (!selectText || !m_baseLayer) + return -1; + int layerId = selectText->caretLayerId(handleId); + IntRect cursorRect = selectText->caretRect(handleId); + IntRect textRect = selectText->textRect(handleId); + // Rects exclude the last pixel on right/bottom. We want only included pixels. + cursorPoint.set(cursorRect.x(), cursorRect.maxY() - 1); + textRect.setHeight(std::max(1, textRect.height() - 1)); + textRect.setWidth(std::max(1, textRect.width() - 1)); + textBounds = FloatQuad(textRect); + + const TransformationMatrix* transform = getLayerTransform(layerId); + if (transform) { + // We're overloading the concept of Rect to be just the two + // points (bottom-left and top-right. + cursorPoint = transform->mapPoint(cursorPoint); + textBounds = transform->mapQuad(textBounds); + } + return layerId; +} + +void mapLayerRect(int layerId, SkIRect& rect) { + const TransformationMatrix* transform = getLayerTransform(layerId); + if (transform) + rect = transform->mapRect(rect); +} + +void floatQuadToQuadF(JNIEnv* env, const FloatQuad& nativeTextQuad, + jobject textQuad) +{ + jobject p1 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP1); + jobject p2 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP2); + jobject p3 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP3); + jobject p4 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP4); + GraphicsJNI::point_to_jpointf(nativeTextQuad.p1(), env, p1); + GraphicsJNI::point_to_jpointf(nativeTextQuad.p2(), env, p2); + GraphicsJNI::point_to_jpointf(nativeTextQuad.p3(), env, p3); + GraphicsJNI::point_to_jpointf(nativeTextQuad.p4(), env, p4); + env->DeleteLocalRef(p1); + env->DeleteLocalRef(p2); + env->DeleteLocalRef(p3); + env->DeleteLocalRef(p4); +} + +// This is called when WebView switches rendering modes in a more permanent fashion +// such as when the layer type is set or the view is attached/detached from the window +int setHwAccelerated(bool hwAccelerated) { + if (!m_glWebViewState) + return 0; + LayerAndroid* root = m_baseLayer; + if (root) + return root->setHwAccelerated(hwAccelerated); + return 0; +} + +void setDrawingPaused(bool isPaused) +{ + m_isDrawingPaused = isPaused; + if (m_viewImpl) + m_viewImpl->setPrerenderingEnabled(!isPaused); +} + +// Finds the rectangles within world to the left, right, top, and bottom +// of rect and adds them to rects. If no intersection exists, false is returned. +static bool findMaskedRects(const FloatRect& world, + const FloatRect& rect, Vector<FloatRect>& rects) { + if (!world.intersects(rect)) + return false; // nothing to subtract + + // left rectangle + if (rect.x() > world.x()) + rects.append(FloatRect(world.x(), world.y(), + rect.x() - world.x(), world.height())); + // top rectangle + if (rect.y() > world.y()) + rects.append(FloatRect(world.x(), world.y(), + world.width(), rect.y() - world.y())); + // right rectangle + if (rect.maxX() < world.maxX()) + rects.append(FloatRect(rect.maxX(), world.y(), + world.maxX() - rect.maxX(), world.height())); + // bottom rectangle + if (rect.maxY() < world.maxY()) + rects.append(FloatRect(world.x(), rect.maxY(), + world.width(), world.maxY() - rect.maxY())); + return true; +} + +// Returns false if layerId is a fixed position layer, otherwise +// all fixed position layer rectangles are subtracted from those within +// rects. Rects will be modified to contain rectangles that don't include +// the fixed position layer rectangles. +static bool findMaskedRectsForLayer(LayerAndroid* layer, + Vector<FloatRect>& rects, int layerId) +{ + if (layer->isPositionFixed()) { + if (layerId == layer->uniqueId()) + return false; + FloatRect layerRect = layer->fullContentAreaMapped(); + for (int i = rects.size() - 1; i >= 0; i--) + if (findMaskedRects(rects[i], layerRect, rects)) + rects.remove(i); + } + + int childIndex = 0; + while (LayerAndroid* child = layer->getChild(childIndex++)) + if (!findMaskedRectsForLayer(child, rects, layerId)) + return false; + + return true; +} + +// Finds the largest rectangle not masked by any fixed layer. +void findMaxVisibleRect(int movingLayerId, SkIRect& visibleContentRect) +{ + if (!m_baseLayer) + return; + + FloatRect visibleContentFloatRect(visibleContentRect); + m_baseLayer->updatePositionsRecursive(visibleContentFloatRect); + Vector<FloatRect> rects; + rects.append(visibleContentFloatRect); + if (findMaskedRectsForLayer(m_baseLayer, rects, movingLayerId)) { + float maxSize = 0.0; + const FloatRect* largest = 0; + for (int i = 0; i < rects.size(); i++) { + const FloatRect& rect = rects[i]; + float size = rect.width() * rect.height(); + if (size > maxSize) { + maxSize = size; + largest = ▭ + } + } + if (largest) { + SkRect largeRect = *largest; + largeRect.round(&visibleContentRect); + } + } } - bool m_isDrawingPaused; private: // local state for WebView + bool m_isDrawingPaused; // private to getFrameCache(); other functions operate in a different thread - CachedRoot* m_frameCacheUI; // navigation data ready for use WebViewCore* m_viewImpl; int m_generation; // associate unique ID with sent kit focus to match with ui - SkPicture* m_navPictureUI; - SkMSec m_ringAnimationEnd; // Corresponds to the same-named boolean on the java side. bool m_heightCanMeasure; int m_lastDx; SkMSec m_lastDxTime; - SelectText m_selectText; - FindOnPage m_findOnPage; - CursorRing m_ring; + DrawExtra* m_extras[DRAW_EXTRAS_SIZE]; BaseLayerAndroid* m_baseLayer; Functor* m_glDrawFunctor; #if USE(ACCELERATED_COMPOSITING) GLWebViewState* m_glWebViewState; - bool m_pageSwapCallbackRegistered; #endif - RenderSkinButton* m_buttonSkin; - SkRect m_visibleRect; + SkRect m_visibleContentRect; bool m_isHighEndGfx; }; // end of WebView class @@ -1565,45 +759,54 @@ private: // local state for WebView class GLDrawFunctor : Functor { public: GLDrawFunctor(WebView* _wvInstance, - bool(WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*, - WebCore::IntRect&, int, WebCore::IntRect&, - jfloat, jint), - WebCore::IntRect _viewRect, float _scale, int _extras) { + int (WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*, + WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint, bool), + WebCore::IntRect _invScreenRect, float _scale, int _extras) { wvInstance = _wvInstance; funcPtr = _funcPtr; - viewRect = _viewRect; + invScreenRect = _invScreenRect; scale = _scale; extras = _extras; }; + status_t operator()(int messageId, void* data) { - if (viewRect.isEmpty()) { + TRACE_METHOD(); + bool shouldDraw = (messageId == uirenderer::DrawGlInfo::kModeDraw); + if (shouldDraw) + wvInstance->updateRectsForGL(); + + if (invScreenRect.isEmpty()) { // NOOP operation if viewport is empty return 0; } WebCore::IntRect inval; - int titlebarHeight = webViewRect.height() - viewRect.height(); + int titlebarHeight = screenRect.height() - invScreenRect.height(); uirenderer::DrawGlInfo* info = reinterpret_cast<uirenderer::DrawGlInfo*>(data); - WebCore::IntRect localViewRect = viewRect; - if (info->isLayer) - localViewRect.move(-1 * localViewRect.x(), -1 * localViewRect.y()); - - WebCore::IntRect clip(info->clipLeft, info->clipTop, - info->clipRight - info->clipLeft, - info->clipBottom - info->clipTop); - TilesManager::instance()->shader()->setWebViewMatrix(info->transform, info->isLayer); - - bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect, - titlebarHeight, clip, scale, extras); - if (retVal) { + WebCore::IntRect screenClip(info->clipLeft, info->clipTop, + info->clipRight - info->clipLeft, + info->clipBottom - info->clipTop); + + WebCore::IntRect localInvScreenRect = invScreenRect; + if (info->isLayer) { + // When webview is on a layer, we need to use the viewport relative + // to the FBO, rather than the screen(which will use invScreenRect). + localInvScreenRect.setX(screenClip.x()); + localInvScreenRect.setY(info->height - screenClip.y() - screenClip.height()); + } + // Send the necessary info to the shader. + TilesManager::instance()->shader()->setGLDrawInfo(info); + + int returnFlags = (*wvInstance.*funcPtr)(localInvScreenRect, &inval, screenRect, + titlebarHeight, screenClip, scale, extras, shouldDraw); + if ((returnFlags & uirenderer::DrawGlInfo::kStatusDraw) != 0) { IntRect finalInval; - if (inval.isEmpty()) { - finalInval = webViewRect; - retVal = true; - } else { - finalInval.setX(webViewRect.x() + inval.x()); - finalInval.setY(webViewRect.y() + titlebarHeight + inval.y()); + if (inval.isEmpty()) + finalInval = screenRect; + else { + finalInval.setX(screenRect.x() + inval.x()); + finalInval.setY(screenRect.y() + titlebarHeight + inval.y()); finalInval.setWidth(inval.width()); finalInval.setHeight(inval.height()); } @@ -1612,201 +815,45 @@ class GLDrawFunctor : Functor { info->dirtyRight = finalInval.maxX(); info->dirtyBottom = finalInval.maxY(); } - // return 1 if invalidation needed, 0 otherwise - return retVal ? 1 : 0; + // return 1 if invalidation needed, 2 to request non-drawing functor callback, 0 otherwise + ALOGV("returnFlags are %d, shouldDraw %d", returnFlags, shouldDraw); + return returnFlags; + } + void updateScreenRect(WebCore::IntRect& _screenRect) { + screenRect = _screenRect; } - void updateRect(WebCore::IntRect& _viewRect) { - viewRect = _viewRect; + void updateInvScreenRect(WebCore::IntRect& _invScreenRect) { + invScreenRect = _invScreenRect; } - void updateViewRect(WebCore::IntRect& _viewRect) { - webViewRect = _viewRect; + void updateScale(float _scale) { + scale = _scale; + } + void updateExtras(jint _extras) { + extras = _extras; } private: WebView* wvInstance; - bool (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, - WebCore::IntRect&, int, WebCore::IntRect&, float, int); - WebCore::IntRect viewRect; - WebCore::IntRect webViewRect; + int (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, + WebCore::IntRect&, int, WebCore::IntRect&, float, int, bool); + WebCore::IntRect invScreenRect; + WebCore::IntRect screenRect; jfloat scale; jint extras; }; -static jobject createJavaRect(JNIEnv* env, int x, int y, int right, int bottom) -{ - jclass rectClass = env->FindClass("android/graphics/Rect"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - jobject rect = env->NewObject(rectClass, init, x, y, right, bottom); - env->DeleteLocalRef(rectClass); - return rect; -} - /* * Native JNI methods */ -static int nativeCacheHitFramePointer(JNIEnv *env, jobject obj) -{ - return reinterpret_cast<int>(GET_NATIVE_VIEW(env, obj) - ->m_cacheHitFrame->framePointer()); -} - -static jobject nativeCacheHitNodeBounds(JNIEnv *env, jobject obj) -{ - WebCore::IntRect bounds = GET_NATIVE_VIEW(env, obj) - ->m_cacheHitNode->originalAbsoluteBounds(); - return createJavaRect(env, bounds.x(), bounds.y(), - bounds.maxX(), bounds.maxY()); -} - -static int nativeCacheHitNodePointer(JNIEnv *env, jobject obj) -{ - return reinterpret_cast<int>(GET_NATIVE_VIEW(env, obj) - ->m_cacheHitNode->nodePointer()); -} - -static bool nativeCacheHitIsPlugin(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->m_cacheHitNode->isPlugin(); -} - -static void nativeClearCursor(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->clearCursor(); -} static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl, jstring drawableDir, jboolean isHighEndGfx) { WTF::String dir = jstringToWtfString(env, drawableDir); - WebView* webview = new WebView(env, obj, viewImpl, dir, isHighEndGfx); + new WebView(env, obj, viewImpl, dir, isHighEndGfx); // NEED THIS OR SOMETHING LIKE IT! //Release(obj); } -static jint nativeCursorFramePointer(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedFrame* frame = 0; - (void) root->currentCursor(&frame); - return reinterpret_cast<int>(frame ? frame->framePointer() : 0); -} - -static const CachedNode* getCursorNode(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentCursor() : 0; -} - -static const CachedNode* getCursorNode(JNIEnv *env, jobject obj, - const CachedFrame** frame) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentCursor(frame) : 0; -} - -static const CachedNode* getFocusCandidate(JNIEnv *env, jobject obj, - const CachedFrame** frame) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedNode* cursor = root->currentCursor(frame); - if (cursor && cursor->wantsKeyEvents()) - return cursor; - return root->currentFocus(frame); -} - -static bool focusCandidateHasNextTextfield(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return false; - const CachedNode* cursor = root->currentCursor(); - if (!cursor || !cursor->isTextInput()) - cursor = root->currentFocus(); - if (!cursor || !cursor->isTextInput()) return false; - return root->nextTextField(cursor, 0); -} - -static const CachedNode* getFocusNode(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentFocus() : 0; -} - -static const CachedNode* getFocusNode(JNIEnv *env, jobject obj, - const CachedFrame** frame) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentFocus(frame) : 0; -} - -static const CachedInput* getInputCandidate(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedFrame* frame; - const CachedNode* cursor = root->currentCursor(&frame); - if (!cursor || !cursor->wantsKeyEvents()) - cursor = root->currentFocus(&frame); - return cursor ? frame->textInput(cursor) : 0; -} - -static jboolean nativePageShouldHandleShiftAndArrows(JNIEnv *env, jobject obj) -{ - const CachedNode* focus = getFocusNode(env, obj); - if (!focus) return false; - // Plugins handle shift and arrows whether or not they have focus. - if (focus->isPlugin()) return true; - const CachedNode* cursor = getCursorNode(env, obj); - // ContentEditable nodes should only receive shift and arrows if they have - // both the cursor and the focus. - return cursor && cursor->nodePointer() == focus->nodePointer() - && cursor->isContentEditable(); -} - -static jobject nativeCursorNodeBounds(JNIEnv *env, jobject obj) -{ - const CachedFrame* frame; - const CachedNode* node = getCursorNode(env, obj, &frame); - WebCore::IntRect bounds = node ? node->bounds(frame) - : WebCore::IntRect(0, 0, 0, 0); - return createJavaRect(env, bounds.x(), bounds.y(), - bounds.maxX(), bounds.maxY()); -} - -static jint nativeCursorNodePointer(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getCursorNode(env, obj); - return reinterpret_cast<int>(node ? node->nodePointer() : 0); -} - -static jobject nativeCursorPosition(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - const CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - WebCore::IntPoint pos = WebCore::IntPoint(0, 0); - if (root) - root->getSimulatedMousePosition(&pos); - jclass pointClass = env->FindClass("android/graphics/Point"); - jmethodID init = env->GetMethodID(pointClass, "<init>", "(II)V"); - jobject point = env->NewObject(pointClass, init, pos.x(), pos.y()); - env->DeleteLocalRef(pointClass); - return point; -} - static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj) { if (obj) { @@ -1825,88 +872,67 @@ static SkRect jrectf_to_rect(JNIEnv* env, jobject obj) return rect; } -static bool nativeCursorIntersects(JNIEnv *env, jobject obj, jobject visRect) -{ - const CachedFrame* frame; - const CachedNode* node = getCursorNode(env, obj, &frame); - return node ? node->bounds(frame).intersects( - jrect_to_webrect(env, visRect)) : false; -} - -static bool nativeCursorIsAnchor(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getCursorNode(env, obj); - return node ? node->isAnchor() : false; -} - -static bool nativeCursorIsTextInput(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getCursorNode(env, obj); - return node ? node->isTextInput() : false; -} - -static jobject nativeCursorText(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getCursorNode(env, obj); - if (!node) - return 0; - WTF::String value = node->getExport(); - return wtfStringToJstring(env, value); -} - -static void nativeDebugDump(JNIEnv *env, jobject obj) -{ -#if DUMP_NAV_CACHE - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->debugDump(); -#endif -} - -static jint nativeDraw(JNIEnv *env, jobject obj, jobject canv, +static void nativeDraw(JNIEnv *env, jobject obj, jobject canv, jobject visible, jint color, - jint extras, jboolean split) { + jint extras) { SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv); WebView* webView = GET_NATIVE_VIEW(env, obj); - SkRect visibleRect = jrectf_to_rect(env, visible); - webView->setVisibleRect(visibleRect); - PictureSet* pictureSet = webView->draw(canvas, color, extras, split); - return reinterpret_cast<jint>(pictureSet); -} + SkRect visibleContentRect = jrectf_to_rect(env, visible); + webView->setVisibleContentRect(visibleContentRect); + webView->draw(canvas, color, static_cast<WebView::DrawExtras>(extras)); +} + +static jint nativeCreateDrawGLFunction(JNIEnv *env, jobject obj, jint nativeView, + jobject jinvscreenrect, jobject jscreenrect, + jobject jvisiblecontentrect, + jfloat scale, jint extras) { + WebCore::IntRect invScreenRect = jrect_to_webrect(env, jinvscreenrect); + WebView *wvInstance = reinterpret_cast<WebView*>(nativeView); + SkRect visibleContentRect = jrectf_to_rect(env, jvisiblecontentrect); + wvInstance->setVisibleContentRect(visibleContentRect); + + GLDrawFunctor* functor = (GLDrawFunctor*) wvInstance->getFunctor(); + if (!functor) { + functor = new GLDrawFunctor(wvInstance, &android::WebView::drawGL, + invScreenRect, scale, extras); + wvInstance->setFunctor((Functor*) functor); + } else { + functor->updateInvScreenRect(invScreenRect); + functor->updateScale(scale); + functor->updateExtras(extras); + } -static jint nativeGetDrawGLFunction(JNIEnv *env, jobject obj, jint nativeView, - jobject jrect, jobject jviewrect, - jobject jvisiblerect, - jfloat scale, jint extras) { - WebCore::IntRect viewRect = jrect_to_webrect(env, jrect); - WebView *wvInstance = (WebView*) nativeView; - SkRect visibleRect = jrectf_to_rect(env, jvisiblerect); - wvInstance->setVisibleRect(visibleRect); + WebCore::IntRect rect = jrect_to_webrect(env, jscreenrect); + functor->updateScreenRect(rect); - GLDrawFunctor* functor = new GLDrawFunctor(wvInstance, - &android::WebView::drawGL, viewRect, scale, extras); - wvInstance->setFunctor((Functor*) functor); + return (jint)functor; +} - WebCore::IntRect webViewRect = jrect_to_webrect(env, jviewrect); - functor->updateViewRect(webViewRect); +static jint nativeGetDrawGLFunction(JNIEnv *env, jobject obj, jint nativeView) { + WebView *wvInstance = reinterpret_cast<WebView*>(nativeView); + if (!wvInstance) + return 0; - return (jint)functor; + return (jint) wvInstance->getFunctor(); } -static void nativeUpdateDrawGLFunction(JNIEnv *env, jobject obj, jobject jrect, - jobject jviewrect, jobject jvisiblerect) { - WebView *wvInstance = GET_NATIVE_VIEW(env, obj); +static void nativeUpdateDrawGLFunction(JNIEnv *env, jobject obj, jint nativeView, + jobject jinvscreenrect, jobject jscreenrect, + jobject jvisiblecontentrect, jfloat scale) { + WebView *wvInstance = reinterpret_cast<WebView*>(nativeView); if (wvInstance) { GLDrawFunctor* functor = (GLDrawFunctor*) wvInstance->getFunctor(); if (functor) { - WebCore::IntRect viewRect = jrect_to_webrect(env, jrect); - functor->updateRect(viewRect); + WebCore::IntRect invScreenRect = jrect_to_webrect(env, jinvscreenrect); + functor->updateInvScreenRect(invScreenRect); + + SkRect visibleContentRect = jrectf_to_rect(env, jvisiblecontentrect); + wvInstance->setVisibleContentRect(visibleContentRect); - SkRect visibleRect = jrectf_to_rect(env, jvisiblerect); - wvInstance->setVisibleRect(visibleRect); + WebCore::IntRect screenRect = jrect_to_webrect(env, jscreenrect); + functor->updateScreenRect(screenRect); - WebCore::IntRect webViewRect = jrect_to_webrect(env, jviewrect); - functor->updateViewRect(webViewRect); + functor->updateScale(scale); } } } @@ -1915,56 +941,29 @@ static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj, jint native { // only call in software rendering, initialize and evaluate animations #if USE(ACCELERATED_COMPOSITING) - LayerAndroid* root = ((WebView*)nativeView)->compositeRoot(); - if (root) { - root->initAnimations(); - return root->evaluateAnimations(); + BaseLayerAndroid* baseLayer = reinterpret_cast<WebView*>(nativeView)->getBaseLayer(); + if (baseLayer) { + baseLayer->initAnimations(); + return baseLayer->evaluateAnimations(); } #endif return false; } -static void nativeSetBaseLayer(JNIEnv *env, jobject obj, jint layer, jobject inval, - jboolean showVisualIndicator, - jboolean isPictureAfterFirstLayout, - jboolean registerPageSwapCallback) +static bool nativeSetBaseLayer(JNIEnv *env, jobject obj, jint nativeView, jint layer, + jboolean showVisualIndicator, + jboolean isPictureAfterFirstLayout, + jint scrollingLayer) { BaseLayerAndroid* layerImpl = reinterpret_cast<BaseLayerAndroid*>(layer); - SkRegion invalRegion; - if (inval) - invalRegion = *GraphicsJNI::getNativeRegion(env, inval); - GET_NATIVE_VIEW(env, obj)->setBaseLayer(layerImpl, invalRegion, showVisualIndicator, - isPictureAfterFirstLayout, - registerPageSwapCallback); -} - -static void nativeGetTextSelectionRegion(JNIEnv *env, jobject obj, jint view, - jobject region) -{ - if (!region) - return; - SkRegion* nregion = GraphicsJNI::getNativeRegion(env, region); - ((WebView*)view)->getTextSelectionRegion(nregion); -} - -static void nativeGetSelectionHandles(JNIEnv *env, jobject obj, jint view, - jintArray arr) -{ - int handles[4]; - ((WebView*)view)->getTextSelectionHandles(handles); - env->SetIntArrayRegion(arr, 0, 4, handles); - checkException(env); -} - -static BaseLayerAndroid* nativeGetBaseLayer(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->getBaseLayer(); + return reinterpret_cast<WebView*>(nativeView)->setBaseLayer(layerImpl, showVisualIndicator, + isPictureAfterFirstLayout, + scrollingLayer); } -static void nativeReplaceBaseContent(JNIEnv *env, jobject obj, jint content) +static BaseLayerAndroid* nativeGetBaseLayer(JNIEnv *env, jobject obj, jint nativeView) { - PictureSet* set = reinterpret_cast<PictureSet*>(content); - GET_NATIVE_VIEW(env, obj)->replaceBaseContent(set); + return reinterpret_cast<WebView*>(nativeView)->getBaseLayer(); } static void nativeCopyBaseContentToPicture(JNIEnv *env, jobject obj, jobject pict) @@ -1978,549 +977,40 @@ static bool nativeHasContent(JNIEnv *env, jobject obj) return GET_NATIVE_VIEW(env, obj)->hasContent(); } -static jobject nativeImageURI(JNIEnv *env, jobject obj, jint x, jint y) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WTF::String uri = view->imageURI(x, y); - return wtfStringToJstring(env, uri); -} - -static jint nativeFocusCandidateFramePointer(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedFrame* frame = 0; - const CachedNode* cursor = root->currentCursor(&frame); - if (!cursor || !cursor->wantsKeyEvents()) - (void) root->currentFocus(&frame); - return reinterpret_cast<int>(frame ? frame->framePointer() : 0); -} - -static bool nativeFocusCandidateIsPassword(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input && input->getType() == CachedInput::PASSWORD; -} - -static bool nativeFocusCandidateIsRtlText(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->isRtlText() : false; -} - -static bool nativeFocusCandidateIsTextInput(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusCandidate(env, obj, 0); - return node ? node->isTextInput() : false; -} - -static jint nativeFocusCandidateMaxLength(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->maxLength() : false; -} - -static jint nativeFocusCandidateIsAutoComplete(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->autoComplete() : false; -} - -static jobject nativeFocusCandidateName(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - if (!input) - return 0; - const WTF::String& name = input->name(); - return wtfStringToJstring(env, name); -} - -static jobject nativeFocusCandidateNodeBounds(JNIEnv *env, jobject obj) -{ - const CachedFrame* frame; - const CachedNode* node = getFocusCandidate(env, obj, &frame); - WebCore::IntRect bounds = node ? node->originalAbsoluteBounds() - : WebCore::IntRect(0, 0, 0, 0); - // Inset the rect by 1 unit, so that the focus candidate's border can still - // be seen behind it. - return createJavaRect(env, bounds.x(), bounds.y(), - bounds.maxX(), bounds.maxY()); -} - -static jobject nativeFocusCandidatePaddingRect(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - if (!input) - return 0; - // Note that the Java Rect is being used to pass four integers, rather than - // being used as an actual rectangle. - return createJavaRect(env, input->paddingLeft(), input->paddingTop(), - input->paddingRight(), input->paddingBottom()); -} - -static jint nativeFocusCandidatePointer(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusCandidate(env, obj, 0); - return reinterpret_cast<int>(node ? node->nodePointer() : 0); -} - -static jint nativeFocusCandidateIsSpellcheck(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->spellcheck() : false; -} - -static jobject nativeFocusCandidateText(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusCandidate(env, obj, 0); - if (!node) - return 0; - WTF::String value = node->getExport(); - return wtfStringToJstring(env, value); -} - -static int nativeFocusCandidateLineHeight(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->lineHeight() : 0; -} - -static jfloat nativeFocusCandidateTextSize(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->textSize() : 0.f; -} - -static int nativeFocusCandidateType(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - if (!input) - return CachedInput::NONE; - - if (input->isTextArea()) - return CachedInput::TEXT_AREA; - - return input->getType(); -} - -static int nativeFocusCandidateLayerId(JNIEnv *env, jobject obj) -{ - const CachedFrame* frame = 0; - const CachedNode* node = getFocusNode(env, obj, &frame); - if (!node || !frame) - return -1; - const CachedLayer* layer = frame->layer(node); - if (!layer) - return -1; - return layer->uniqueId(); -} - -static bool nativeFocusIsPlugin(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusNode(env, obj); - return node ? node->isPlugin() : false; -} - -static jobject nativeFocusNodeBounds(JNIEnv *env, jobject obj) -{ - const CachedFrame* frame; - const CachedNode* node = getFocusNode(env, obj, &frame); - WebCore::IntRect bounds = node ? node->bounds(frame) - : WebCore::IntRect(0, 0, 0, 0); - return createJavaRect(env, bounds.x(), bounds.y(), - bounds.maxX(), bounds.maxY()); -} - -static jint nativeFocusNodePointer(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusNode(env, obj); - return node ? reinterpret_cast<int>(node->nodePointer()) : 0; -} - -static bool nativeCursorWantsKeyEvents(JNIEnv* env, jobject jwebview) { - WebView* view = GET_NATIVE_VIEW(env, jwebview); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->cursorWantsKeyEvents(); -} - -static void nativeHideCursor(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->hideCursor(); -} - -static void nativeInstrumentReport(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounter::reportNow(); -#endif -} - -static void nativeSelectBestAt(JNIEnv *env, jobject obj, jobject jrect) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WebCore::IntRect rect = jrect_to_webrect(env, jrect); - view->selectBestAt(rect); -} - -static void nativeSelectAt(JNIEnv *env, jobject obj, jint x, jint y) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WebCore::IntRect rect = IntRect(x, y , 1, 1); - view->selectBestAt(rect); - if (view->hasCursorNode()) - view->showCursorUntimed(); -} - -static jobject nativeLayerBounds(JNIEnv* env, jobject obj, jint jlayer) -{ - SkRect r; -#if USE(ACCELERATED_COMPOSITING) - LayerAndroid* layer = (LayerAndroid*) jlayer; - r = layer->bounds(); -#else - r.setEmpty(); -#endif - SkIRect irect; - r.round(&irect); - jclass rectClass = env->FindClass("android/graphics/Rect"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - jobject rect = env->NewObject(rectClass, init, irect.fLeft, irect.fTop, - irect.fRight, irect.fBottom); - env->DeleteLocalRef(rectClass); - return rect; -} - -static jobject nativeSubtractLayers(JNIEnv* env, jobject obj, jobject jrect) -{ - SkIRect irect = jrect_to_webrect(env, jrect); -#if USE(ACCELERATED_COMPOSITING) - LayerAndroid* root = GET_NATIVE_VIEW(env, obj)->compositeRoot(); - if (root) { - SkRect rect; - rect.set(irect); - rect = root->subtractLayers(rect); - rect.round(&irect); - } -#endif - jclass rectClass = env->FindClass("android/graphics/Rect"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - jobject rect = env->NewObject(rectClass, init, irect.fLeft, irect.fTop, - irect.fRight, irect.fBottom); - env->DeleteLocalRef(rectClass); - return rect; -} - -static jint nativeTextGeneration(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->textGeneration() : 0; -} - -static bool nativePointInNavCache(JNIEnv *env, jobject obj, - int x, int y, int slop) -{ - return GET_NATIVE_VIEW(env, obj)->pointInNavCache(x, y, slop); -} - -static bool nativeMotionUp(JNIEnv *env, jobject obj, - int x, int y, int slop) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->motionUp(x, y, slop); -} - -static bool nativeHasCursorNode(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->hasCursorNode(); -} - -static bool nativeHasFocusNode(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->hasFocusNode(); -} - -static bool nativeMoveCursor(JNIEnv *env, jobject obj, - int key, int count, bool ignoreScroll) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - DBG_NAV_LOGD("env=%p obj=%p view=%p", env, obj, view); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->moveCursor(key, count, ignoreScroll); -} - -static void nativeSetFindIsUp(JNIEnv *env, jobject obj, jboolean isUp) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->setFindIsUp(isUp); -} - -static void nativeSetFindIsEmpty(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->setFindIsEmpty(); -} - -static void nativeShowCursorTimed(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->showCursorTimed(); -} - static void nativeSetHeightCanMeasure(JNIEnv *env, jobject obj, bool measure) { WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeSetHeightCanMeasure"); + ALOG_ASSERT(view, "view not set in nativeSetHeightCanMeasure"); view->setHeightCanMeasure(measure); } -static jobject nativeGetCursorRingBounds(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - jclass rectClass = env->FindClass("android/graphics/Rect"); - LOG_ASSERT(rectClass, "Could not find Rect class!"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - LOG_ASSERT(init, "Could not find constructor for Rect"); - WebCore::IntRect webRect; - view->cursorRingBounds(&webRect); - jobject rect = env->NewObject(rectClass, init, webRect.x(), - webRect.y(), webRect.maxX(), webRect.maxY()); - env->DeleteLocalRef(rectClass); - return rect; -} - -static int nativeFindAll(JNIEnv *env, jobject obj, jstring findLower, - jstring findUpper, jboolean sameAsLastSearch) -{ - // If one or the other is null, do not search. - if (!(findLower && findUpper)) - return 0; - // Obtain the characters for both the lower case string and the upper case - // string representing the same word. - const jchar* findLowerChars = env->GetStringChars(findLower, 0); - const jchar* findUpperChars = env->GetStringChars(findUpper, 0); - // If one or the other is null, do not search. - if (!(findLowerChars && findUpperChars)) { - if (findLowerChars) - env->ReleaseStringChars(findLower, findLowerChars); - if (findUpperChars) - env->ReleaseStringChars(findUpper, findUpperChars); - checkException(env); - return 0; - } - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeFindAll"); - CachedRoot* root = view->getFrameCache(WebView::AllowNewer); - if (!root) { - env->ReleaseStringChars(findLower, findLowerChars); - env->ReleaseStringChars(findUpper, findUpperChars); - checkException(env); - return 0; - } - int length = env->GetStringLength(findLower); - // If the lengths of the strings do not match, then they are not the same - // word, so do not search. - if (!length || env->GetStringLength(findUpper) != length) { - env->ReleaseStringChars(findLower, findLowerChars); - env->ReleaseStringChars(findUpper, findUpperChars); - checkException(env); - return 0; - } - int width = root->documentWidth(); - int height = root->documentHeight(); - // Create a FindCanvas, which allows us to fake draw into it so we can - // figure out where our search string is rendered (and how many times). - FindCanvas canvas(width, height, (const UChar*) findLowerChars, - (const UChar*) findUpperChars, length << 1); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); - canvas.setBitmapDevice(bitmap); - root->draw(canvas); - WTF::Vector<MatchInfo>* matches = canvas.detachMatches(); - // With setMatches, the WebView takes ownership of matches - view->setMatches(matches, sameAsLastSearch); - - env->ReleaseStringChars(findLower, findLowerChars); - env->ReleaseStringChars(findUpper, findUpperChars); - checkException(env); - return canvas.found(); -} - -static void nativeFindNext(JNIEnv *env, jobject obj, bool forward) +static void nativeDestroy(JNIEnv *env, jobject obj, jint ptr) { - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeFindNext"); - view->findNext(forward); -} - -static int nativeFindIndex(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeFindIndex"); - return view->currentMatchIndex(); -} - -static void nativeUpdateCachedTextfield(JNIEnv *env, jobject obj, jstring updatedText, jint generation) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeUpdateCachedTextfield"); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return; - const CachedNode* cachedFocusNode = root->currentFocus(); - if (!cachedFocusNode || !cachedFocusNode->isTextInput()) - return; - WTF::String webcoreString = jstringToWtfString(env, updatedText); - (const_cast<CachedNode*>(cachedFocusNode))->setExport(webcoreString); - root->setTextGeneration(generation); - checkException(env); -} - -static jint nativeGetBlockLeftEdge(JNIEnv *env, jobject obj, jint x, jint y, - jfloat scale) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - if (!view) - return -1; - return view->getBlockLeftEdge(x, y, scale); -} - -static void nativeDestroy(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOGD("nativeDestroy view: %p", view); - LOG_ASSERT(view, "view not set in nativeDestroy"); + WebView* view = reinterpret_cast<WebView*>(ptr); + ALOGD("nativeDestroy view: %p", view); + ALOG_ASSERT(view, "view not set in nativeDestroy"); delete view; } -static void nativeStopGL(JNIEnv *env, jobject obj) +static void nativeStopGL(JNIEnv *env, jobject obj, jint ptr) { - GET_NATIVE_VIEW(env, obj)->stopGL(); -} - -static bool nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return false; - const CachedNode* current = root->currentCursor(); - if (!current || !current->isTextInput()) - current = root->currentFocus(); - if (!current || !current->isTextInput()) - return false; - const CachedFrame* frame; - const CachedNode* next = root->nextTextField(current, &frame); - if (!next) - return false; - const WebCore::IntRect& bounds = next->bounds(frame); - root->rootHistory()->setMouseBounds(bounds); - view->getWebViewCore()->updateCursorBounds(root, frame, next); - view->showCursorUntimed(); - root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(next)); - view->sendMoveFocus(static_cast<WebCore::Frame*>(frame->framePointer()), - static_cast<WebCore::Node*>(next->nodePointer())); - if (!next->isInLayer()) - view->scrollRectOnScreen(bounds); - view->getWebViewCore()->m_moveGeneration++; - return true; -} - -static int nativeMoveGeneration(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - if (!view) - return 0; - return view->moveGeneration(); -} - -static void nativeMoveSelection(JNIEnv *env, jobject obj, int x, int y) -{ - GET_NATIVE_VIEW(env, obj)->moveSelection(x, y); -} - -static void nativeResetSelection(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->resetSelection(); -} - -static jobject nativeSelectableText(JNIEnv* env, jobject obj) -{ - IntPoint pos = GET_NATIVE_VIEW(env, obj)->selectableText(); - jclass pointClass = env->FindClass("android/graphics/Point"); - jmethodID init = env->GetMethodID(pointClass, "<init>", "(II)V"); - jobject point = env->NewObject(pointClass, init, pos.x(), pos.y()); - env->DeleteLocalRef(pointClass); - return point; -} - -static void nativeSelectAll(JNIEnv* env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->selectAll(); -} - -static void nativeSetExtendSelection(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->setExtendSelection(); -} - -static jboolean nativeStartSelection(JNIEnv *env, jobject obj, int x, int y) -{ - return GET_NATIVE_VIEW(env, obj)->startSelection(x, y); -} - -static jboolean nativeWordSelection(JNIEnv *env, jobject obj, int x, int y) -{ - return GET_NATIVE_VIEW(env, obj)->wordSelection(x, y); -} - -static void nativeExtendSelection(JNIEnv *env, jobject obj, int x, int y) -{ - GET_NATIVE_VIEW(env, obj)->extendSelection(x, y); + if (ptr) + reinterpret_cast<WebView*>(ptr)->stopGL(); } static jobject nativeGetSelection(JNIEnv *env, jobject obj) { WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); + ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); String selection = view->getSelection(); return wtfStringToJstring(env, selection); } -static jboolean nativeHitSelection(JNIEnv *env, jobject obj, int x, int y) -{ - return GET_NATIVE_VIEW(env, obj)->hitSelection(x, y); -} - -static jint nativeSelectionX(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->selectionX(); -} - -static jint nativeSelectionY(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->selectionY(); -} - -static void nativeSetSelectionPointer(JNIEnv *env, jobject obj, jint nativeView, - jboolean set, jfloat scale, jint x, jint y) -{ - ((WebView*)nativeView)->setSelectionPointer(set, scale, x, y); -} - -static void nativeRegisterPageSwapCallback(JNIEnv *env, jobject obj) +static void nativeDiscardAllTextures(JNIEnv *env, jobject obj) { - GET_NATIVE_VIEW(env, obj)->registerPageSwapCallback(); + //discard all textures for debugging/test purposes, but not gl backing memory + bool allTextures = true, deleteGLTextures = false; + TilesManager::instance()->discardTextures(allTextures, deleteGLTextures); } static void nativeTileProfilingStart(JNIEnv *env, jobject obj) @@ -2581,15 +1071,14 @@ static void dumpToFile(const char text[], void* file) { } #endif +// Return true to view invalidate WebView static bool nativeSetProperty(JNIEnv *env, jobject obj, jstring jkey, jstring jvalue) { WTF::String key = jstringToWtfString(env, jkey); WTF::String value = jstringToWtfString(env, jvalue); if (key == "inverted") { - if (value == "true") - TilesManager::instance()->setInvertedScreen(true); - else - TilesManager::instance()->setInvertedScreen(false); + bool shouldInvert = (value == "true"); + TilesManager::instance()->setInvertedScreen(shouldInvert); return true; } else if (key == "inverted_contrast") { @@ -2600,25 +1089,47 @@ static bool nativeSetProperty(JNIEnv *env, jobject obj, jstring jkey, jstring jv else if (key == "enable_cpu_upload_path") { TilesManager::instance()->transferQueue()->setTextureUploadType( value == "true" ? CpuUpload : GpuUpload); - return true; } else if (key == "use_minimal_memory") { TilesManager::instance()->setUseMinimalMemory(value == "true"); - return true; + } + else if (key == "use_double_buffering") { + TilesManager::instance()->setUseDoubleBuffering(value == "true"); + } + else if (key == "tree_updates") { + TilesManager::instance()->clearContentUpdates(); } return false; } -static jstring nativeGetProperty(JNIEnv *env, jobject obj, jstring key) +static jstring nativeGetProperty(JNIEnv *env, jobject obj, jstring jkey) { + WTF::String key = jstringToWtfString(env, jkey); + if (key == "tree_updates") { + int updates = TilesManager::instance()->getContentUpdates(); + WTF::String wtfUpdates = WTF::String::number(updates); + return wtfStringToJstring(env, wtfUpdates); + } return 0; } static void nativeOnTrimMemory(JNIEnv *env, jobject obj, jint level) { if (TilesManager::hardwareAccelerationEnabled()) { - bool freeAllTextures = (level > TRIM_MEMORY_UI_HIDDEN); - TilesManager::instance()->deallocateTextures(freeAllTextures); + // When we got TRIM_MEMORY_MODERATE or TRIM_MEMORY_COMPLETE, we should + // make sure the transfer queue is empty and then abandon the Surface + // Texture to avoid ANR b/c framework may destroy the EGL context. + // Refer to WindowManagerImpl.java for conditions we followed. + TilesManager* tilesManager = TilesManager::instance(); + if ((level >= TRIM_MEMORY_MODERATE + && !tilesManager->highEndGfx()) + || level >= TRIM_MEMORY_COMPLETE) { + ALOGD("OnTrimMemory with EGL Context %p", eglGetCurrentContext()); + tilesManager->cleanupGLResources(); + } + + bool freeAllTextures = (level > TRIM_MEMORY_UI_HIDDEN), glTextures = true; + tilesManager->discardTextures(freeAllTextures, glTextures); } } @@ -2626,7 +1137,7 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl) { #ifdef ANDROID_DUMP_DISPLAY_TREE WebView* view = GET_NATIVE_VIEW(env, jwebview); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); + ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); if (view && view->getWebViewCore()) { FILE* file = fopen(DISPLAY_TREE_LOG_FILE, "w"); @@ -2643,17 +1154,17 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl) SkDumpCanvas canvas(&dumper); // this will playback the picture into the canvas, which will // spew its contents to the dumper - view->draw(&canvas, 0, 0, false); + view->draw(&canvas, 0, WebView::DrawExtrasNone); // we're done with the file now fwrite("\n", 1, 1, file); fclose(file); } #if USE(ACCELERATED_COMPOSITING) - const LayerAndroid* rootLayer = view->compositeRoot(); - if (rootLayer) { + const LayerAndroid* baseLayer = view->getBaseLayer(); + if (baseLayer) { FILE* file = fopen(LAYERS_TREE_LOG_FILE,"w"); if (file) { - rootLayer->dumpLayers(file, 0); + baseLayer->dumpLayers(file, 0); fclose(file); } } @@ -2662,13 +1173,13 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl) #endif } -static int nativeScrollableLayer(JNIEnv* env, jobject jwebview, jint x, jint y, - jobject rect, jobject bounds) +static int nativeScrollableLayer(JNIEnv* env, jobject jwebview, jint nativeView, + jint x, jint y, jobject rect, jobject bounds) { - WebView* view = GET_NATIVE_VIEW(env, jwebview); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); + WebView* webview = reinterpret_cast<WebView*>(nativeView); + ALOG_ASSERT(webview, "webview not set in %s", __FUNCTION__); SkIRect nativeRect, nativeBounds; - int id = view->scrollableLayer(x, y, &nativeRect, &nativeBounds); + int id = webview->scrollableLayer(x, y, &nativeRect, &nativeBounds); if (rect) GraphicsJNI::irect_to_jrect(nativeRect, env, rect); if (bounds) @@ -2676,18 +1187,18 @@ static int nativeScrollableLayer(JNIEnv* env, jobject jwebview, jint x, jint y, return id; } -static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint x, - jint y) +static bool nativeScrollLayer(JNIEnv* env, jobject obj, + jint nativeView, jint layerId, jint x, jint y) { #if ENABLE(ANDROID_OVERFLOW_SCROLL) - WebView* view = GET_NATIVE_VIEW(env, obj); - view->scrollLayer(layerId, x, y); + WebView* webview = reinterpret_cast<WebView*>(nativeView); + webview->scrollLayer(layerId, x, y); //TODO: the below only needed for the SW rendering path - LayerAndroid* root = view->compositeRoot(); - if (!root) + LayerAndroid* baseLayer = webview->getBaseLayer(); + if (!baseLayer) return false; - LayerAndroid* layer = root->findById(layerId); + LayerAndroid* layer = baseLayer->findById(layerId); if (!layer || !layer->contentIsScrollable()) return false; return static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y); @@ -2697,9 +1208,10 @@ static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint x, static void nativeSetIsScrolling(JNIEnv* env, jobject jwebview, jboolean isScrolling) { + // TODO: Pass in the native pointer instead WebView* view = GET_NATIVE_VIEW(env, jwebview); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->setIsScrolling(isScrolling); + if (view) + view->setIsScrolling(isScrolling); } static void nativeUseHardwareAccelSkia(JNIEnv*, jobject, jboolean enabled) @@ -2707,9 +1219,9 @@ static void nativeUseHardwareAccelSkia(JNIEnv*, jobject, jboolean enabled) BaseRenderer::setCurrentRendererType(enabled ? BaseRenderer::Ganesh : BaseRenderer::Raster); } -static int nativeGetBackgroundColor(JNIEnv* env, jobject obj) +static int nativeGetBackgroundColor(JNIEnv* env, jobject obj, jint nativeView) { - WebView* view = GET_NATIVE_VIEW(env, obj); + WebView* view = reinterpret_cast<WebView*>(nativeView); BaseLayerAndroid* baseLayer = view->getBaseLayer(); if (baseLayer) { WebCore::Color color = baseLayer->getBackgroundColor(); @@ -2723,179 +1235,93 @@ static int nativeGetBackgroundColor(JNIEnv* env, jobject obj) static void nativeSetPauseDrawing(JNIEnv *env, jobject obj, jint nativeView, jboolean pause) { - ((WebView*)nativeView)->m_isDrawingPaused = pause; + reinterpret_cast<WebView*>(nativeView)->setDrawingPaused(pause); +} + +static void nativeSetTextSelection(JNIEnv *env, jobject obj, jint nativeView, + jint selectionPtr) +{ + SelectText* selection = reinterpret_cast<SelectText*>(selectionPtr); + reinterpret_cast<WebView*>(nativeView)->setTextSelection(selection); +} + +static jint nativeGetHandleLayerId(JNIEnv *env, jobject obj, jint nativeView, + jint handleIndex, jobject cursorPoint, + jobject textQuad) +{ + WebView* webview = reinterpret_cast<WebView*>(nativeView); + SkIPoint nativePoint; + FloatQuad nativeTextQuad; + int layerId = webview->getHandleLayerId((SelectText::HandleId) handleIndex, + nativePoint, nativeTextQuad); + if (cursorPoint) + GraphicsJNI::ipoint_to_jpoint(nativePoint, env, cursorPoint); + if (textQuad) + webview->floatQuadToQuadF(env, nativeTextQuad, textQuad); + return layerId; +} + +static void nativeMapLayerRect(JNIEnv *env, jobject obj, jint nativeView, + jint layerId, jobject rect) +{ + WebView* webview = reinterpret_cast<WebView*>(nativeView); + SkIRect nativeRect; + GraphicsJNI::jrect_to_irect(env, rect, &nativeRect); + webview->mapLayerRect(layerId, nativeRect); + GraphicsJNI::irect_to_jrect(nativeRect, env, rect); +} + +static jint nativeSetHwAccelerated(JNIEnv *env, jobject obj, jint nativeView, + jboolean hwAccelerated) +{ + WebView* webview = reinterpret_cast<WebView*>(nativeView); + return webview->setHwAccelerated(hwAccelerated); +} + +static void nativeFindMaxVisibleRect(JNIEnv *env, jobject obj, jint nativeView, + jint movingLayerId, jobject visibleContentRect) +{ + WebView* webview = reinterpret_cast<WebView*>(nativeView); + SkIRect nativeRect; + GraphicsJNI::jrect_to_irect(env, visibleContentRect, &nativeRect); + webview->findMaxVisibleRect(movingLayerId, nativeRect); + GraphicsJNI::irect_to_jrect(nativeRect, env, visibleContentRect); } /* * JNI registration */ static JNINativeMethod gJavaWebViewMethods[] = { - { "nativeCacheHitFramePointer", "()I", - (void*) nativeCacheHitFramePointer }, - { "nativeCacheHitIsPlugin", "()Z", - (void*) nativeCacheHitIsPlugin }, - { "nativeCacheHitNodeBounds", "()Landroid/graphics/Rect;", - (void*) nativeCacheHitNodeBounds }, - { "nativeCacheHitNodePointer", "()I", - (void*) nativeCacheHitNodePointer }, - { "nativeClearCursor", "()V", - (void*) nativeClearCursor }, { "nativeCreate", "(ILjava/lang/String;Z)V", (void*) nativeCreate }, - { "nativeCursorFramePointer", "()I", - (void*) nativeCursorFramePointer }, - { "nativePageShouldHandleShiftAndArrows", "()Z", - (void*) nativePageShouldHandleShiftAndArrows }, - { "nativeCursorNodeBounds", "()Landroid/graphics/Rect;", - (void*) nativeCursorNodeBounds }, - { "nativeCursorNodePointer", "()I", - (void*) nativeCursorNodePointer }, - { "nativeCursorIntersects", "(Landroid/graphics/Rect;)Z", - (void*) nativeCursorIntersects }, - { "nativeCursorIsAnchor", "()Z", - (void*) nativeCursorIsAnchor }, - { "nativeCursorIsTextInput", "()Z", - (void*) nativeCursorIsTextInput }, - { "nativeCursorPosition", "()Landroid/graphics/Point;", - (void*) nativeCursorPosition }, - { "nativeCursorText", "()Ljava/lang/String;", - (void*) nativeCursorText }, - { "nativeCursorWantsKeyEvents", "()Z", - (void*)nativeCursorWantsKeyEvents }, - { "nativeDebugDump", "()V", - (void*) nativeDebugDump }, - { "nativeDestroy", "()V", + { "nativeDestroy", "(I)V", (void*) nativeDestroy }, - { "nativeDraw", "(Landroid/graphics/Canvas;Landroid/graphics/RectF;IIZ)I", + { "nativeDraw", "(Landroid/graphics/Canvas;Landroid/graphics/RectF;II)V", (void*) nativeDraw }, - { "nativeGetDrawGLFunction", "(ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/RectF;FI)I", + { "nativeCreateDrawGLFunction", "(ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/RectF;FI)I", + (void*) nativeCreateDrawGLFunction }, + { "nativeGetDrawGLFunction", "(I)I", (void*) nativeGetDrawGLFunction }, - { "nativeUpdateDrawGLFunction", "(Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/RectF;)V", + { "nativeUpdateDrawGLFunction", "(ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/RectF;F)V", (void*) nativeUpdateDrawGLFunction }, { "nativeDumpDisplayTree", "(Ljava/lang/String;)V", (void*) nativeDumpDisplayTree }, { "nativeEvaluateLayersAnimations", "(I)Z", (void*) nativeEvaluateLayersAnimations }, - { "nativeExtendSelection", "(II)V", - (void*) nativeExtendSelection }, - { "nativeFindAll", "(Ljava/lang/String;Ljava/lang/String;Z)I", - (void*) nativeFindAll }, - { "nativeFindNext", "(Z)V", - (void*) nativeFindNext }, - { "nativeFindIndex", "()I", - (void*) nativeFindIndex}, - { "nativeFocusCandidateFramePointer", "()I", - (void*) nativeFocusCandidateFramePointer }, - { "nativeFocusCandidateHasNextTextfield", "()Z", - (void*) focusCandidateHasNextTextfield }, - { "nativeFocusCandidateIsPassword", "()Z", - (void*) nativeFocusCandidateIsPassword }, - { "nativeFocusCandidateIsRtlText", "()Z", - (void*) nativeFocusCandidateIsRtlText }, - { "nativeFocusCandidateIsTextInput", "()Z", - (void*) nativeFocusCandidateIsTextInput }, - { "nativeFocusCandidateLineHeight", "()I", - (void*) nativeFocusCandidateLineHeight }, - { "nativeFocusCandidateMaxLength", "()I", - (void*) nativeFocusCandidateMaxLength }, - { "nativeFocusCandidateIsAutoComplete", "()Z", - (void*) nativeFocusCandidateIsAutoComplete }, - { "nativeFocusCandidateIsSpellcheck", "()Z", - (void*) nativeFocusCandidateIsSpellcheck }, - { "nativeFocusCandidateName", "()Ljava/lang/String;", - (void*) nativeFocusCandidateName }, - { "nativeFocusCandidateNodeBounds", "()Landroid/graphics/Rect;", - (void*) nativeFocusCandidateNodeBounds }, - { "nativeFocusCandidatePaddingRect", "()Landroid/graphics/Rect;", - (void*) nativeFocusCandidatePaddingRect }, - { "nativeFocusCandidatePointer", "()I", - (void*) nativeFocusCandidatePointer }, - { "nativeFocusCandidateText", "()Ljava/lang/String;", - (void*) nativeFocusCandidateText }, - { "nativeFocusCandidateTextSize", "()F", - (void*) nativeFocusCandidateTextSize }, - { "nativeFocusCandidateType", "()I", - (void*) nativeFocusCandidateType }, - { "nativeFocusCandidateLayerId", "()I", - (void*) nativeFocusCandidateLayerId }, - { "nativeFocusIsPlugin", "()Z", - (void*) nativeFocusIsPlugin }, - { "nativeFocusNodeBounds", "()Landroid/graphics/Rect;", - (void*) nativeFocusNodeBounds }, - { "nativeFocusNodePointer", "()I", - (void*) nativeFocusNodePointer }, - { "nativeGetCursorRingBounds", "()Landroid/graphics/Rect;", - (void*) nativeGetCursorRingBounds }, { "nativeGetSelection", "()Ljava/lang/String;", (void*) nativeGetSelection }, - { "nativeHasCursorNode", "()Z", - (void*) nativeHasCursorNode }, - { "nativeHasFocusNode", "()Z", - (void*) nativeHasFocusNode }, - { "nativeHideCursor", "()V", - (void*) nativeHideCursor }, - { "nativeHitSelection", "(II)Z", - (void*) nativeHitSelection }, - { "nativeImageURI", "(II)Ljava/lang/String;", - (void*) nativeImageURI }, - { "nativeInstrumentReport", "()V", - (void*) nativeInstrumentReport }, - { "nativeLayerBounds", "(I)Landroid/graphics/Rect;", - (void*) nativeLayerBounds }, - { "nativeMotionUp", "(III)Z", - (void*) nativeMotionUp }, - { "nativeMoveCursor", "(IIZ)Z", - (void*) nativeMoveCursor }, - { "nativeMoveCursorToNextTextInput", "()Z", - (void*) nativeMoveCursorToNextTextInput }, - { "nativeMoveGeneration", "()I", - (void*) nativeMoveGeneration }, - { "nativeMoveSelection", "(II)V", - (void*) nativeMoveSelection }, - { "nativePointInNavCache", "(III)Z", - (void*) nativePointInNavCache }, - { "nativeResetSelection", "()V", - (void*) nativeResetSelection }, - { "nativeSelectableText", "()Landroid/graphics/Point;", - (void*) nativeSelectableText }, - { "nativeSelectAll", "()V", - (void*) nativeSelectAll }, - { "nativeSelectBestAt", "(Landroid/graphics/Rect;)V", - (void*) nativeSelectBestAt }, - { "nativeSelectAt", "(II)V", - (void*) nativeSelectAt }, - { "nativeSelectionX", "()I", - (void*) nativeSelectionX }, - { "nativeSelectionY", "()I", - (void*) nativeSelectionY }, - { "nativeSetExtendSelection", "()V", - (void*) nativeSetExtendSelection }, - { "nativeSetFindIsEmpty", "()V", - (void*) nativeSetFindIsEmpty }, - { "nativeSetFindIsUp", "(Z)V", - (void*) nativeSetFindIsUp }, { "nativeSetHeightCanMeasure", "(Z)V", (void*) nativeSetHeightCanMeasure }, - { "nativeSetBaseLayer", "(ILandroid/graphics/Region;ZZZ)V", + { "nativeSetBaseLayer", "(IIZZI)Z", (void*) nativeSetBaseLayer }, - { "nativeGetTextSelectionRegion", "(ILandroid/graphics/Region;)V", - (void*) nativeGetTextSelectionRegion }, - { "nativeGetSelectionHandles", "(I[I)V", - (void*) nativeGetSelectionHandles }, - { "nativeGetBaseLayer", "()I", + { "nativeGetBaseLayer", "(I)I", (void*) nativeGetBaseLayer }, - { "nativeReplaceBaseContent", "(I)V", - (void*) nativeReplaceBaseContent }, { "nativeCopyBaseContentToPicture", "(Landroid/graphics/Picture;)V", (void*) nativeCopyBaseContentToPicture }, { "nativeHasContent", "()Z", (void*) nativeHasContent }, - { "nativeSetSelectionPointer", "(IZFII)V", - (void*) nativeSetSelectionPointer }, - { "nativeShowCursorTimed", "()V", - (void*) nativeShowCursorTimed }, - { "nativeRegisterPageSwapCallback", "()V", - (void*) nativeRegisterPageSwapCallback }, + { "nativeDiscardAllTextures", "()V", + (void*) nativeDiscardAllTextures }, { "nativeTileProfilingStart", "()V", (void*) nativeTileProfilingStart }, { "nativeTileProfilingStop", "()F", @@ -2910,29 +1336,17 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeTileProfilingGetInt }, { "nativeTileProfilingGetFloat", "(IILjava/lang/String;)F", (void*) nativeTileProfilingGetFloat }, - { "nativeStartSelection", "(II)Z", - (void*) nativeStartSelection }, - { "nativeStopGL", "()V", + { "nativeStopGL", "(I)V", (void*) nativeStopGL }, - { "nativeSubtractLayers", "(Landroid/graphics/Rect;)Landroid/graphics/Rect;", - (void*) nativeSubtractLayers }, - { "nativeTextGeneration", "()I", - (void*) nativeTextGeneration }, - { "nativeUpdateCachedTextfield", "(Ljava/lang/String;I)V", - (void*) nativeUpdateCachedTextfield }, - { "nativeWordSelection", "(II)Z", - (void*) nativeWordSelection }, - { "nativeGetBlockLeftEdge", "(IIF)I", - (void*) nativeGetBlockLeftEdge }, - { "nativeScrollableLayer", "(IILandroid/graphics/Rect;Landroid/graphics/Rect;)I", + { "nativeScrollableLayer", "(IIILandroid/graphics/Rect;Landroid/graphics/Rect;)I", (void*) nativeScrollableLayer }, - { "nativeScrollLayer", "(III)Z", + { "nativeScrollLayer", "(IIII)Z", (void*) nativeScrollLayer }, { "nativeSetIsScrolling", "(Z)V", (void*) nativeSetIsScrolling }, { "nativeUseHardwareAccelSkia", "(Z)V", (void*) nativeUseHardwareAccelSkia }, - { "nativeGetBackgroundColor", "()I", + { "nativeGetBackgroundColor", "(I)I", (void*) nativeGetBackgroundColor }, { "nativeSetProperty", "(Ljava/lang/String;Ljava/lang/String;)Z", (void*) nativeSetProperty }, @@ -2942,17 +1356,27 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeOnTrimMemory }, { "nativeSetPauseDrawing", "(IZ)V", (void*) nativeSetPauseDrawing }, + { "nativeSetTextSelection", "(II)V", + (void*) nativeSetTextSelection }, + { "nativeGetHandleLayerId", "(IILandroid/graphics/Point;Landroid/webkit/QuadF;)I", + (void*) nativeGetHandleLayerId }, + { "nativeMapLayerRect", "(IILandroid/graphics/Rect;)V", + (void*) nativeMapLayerRect }, + { "nativeSetHwAccelerated", "(IZ)I", + (void*) nativeSetHwAccelerated }, + { "nativeFindMaxVisibleRect", "(IILandroid/graphics/Rect;)V", + (void*) nativeFindMaxVisibleRect }, }; int registerWebView(JNIEnv* env) { - jclass clazz = env->FindClass("android/webkit/WebView"); - LOG_ASSERT(clazz, "Unable to find class android/webkit/WebView"); + jclass clazz = env->FindClass("android/webkit/WebViewClassic"); + ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebViewClassic"); gWebViewField = env->GetFieldID(clazz, "mNativeClass", "I"); - LOG_ASSERT(gWebViewField, "Unable to find android/webkit/WebView.mNativeClass"); + ALOG_ASSERT(gWebViewField, "Unable to find android/webkit/WebViewClassic.mNativeClass"); env->DeleteLocalRef(clazz); - return jniRegisterNativeMethods(env, "android/webkit/WebView", gJavaWebViewMethods, NELEM(gJavaWebViewMethods)); + return jniRegisterNativeMethods(env, "android/webkit/WebViewClassic", gJavaWebViewMethods, NELEM(gJavaWebViewMethods)); } } // namespace android |