diff options
Diffstat (limited to 'Source/WebKit')
18 files changed, 451 insertions, 312 deletions
diff --git a/Source/WebKit/android/RenderSkinMediaButton.cpp b/Source/WebKit/android/RenderSkinMediaButton.cpp index febf575..b3aa57d 100644 --- a/Source/WebKit/android/RenderSkinMediaButton.cpp +++ b/Source/WebKit/android/RenderSkinMediaButton.cpp @@ -95,6 +95,9 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT Decode(); } + if (!canvas) + return; + // If we failed to decode, do nothing. This way the browser still works, // and webkit will still draw the label and layout space for us. if (gDecodingFailed) diff --git a/Source/WebKit/android/RenderSkinNinePatch.cpp b/Source/WebKit/android/RenderSkinNinePatch.cpp index ec748f7..9ef0b4a 100644 --- a/Source/WebKit/android/RenderSkinNinePatch.cpp +++ b/Source/WebKit/android/RenderSkinNinePatch.cpp @@ -73,7 +73,7 @@ bool RenderSkinNinePatch::decodeAsset(AssetManager* am, const char* filename, Ni } asset->close(); - if (!peeker.fPatchIsValid) { + if (!peeker.fPatch) { ALOGE("RenderSkinNinePatch::Patch data not valid"); return false; } diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp index 5e16152..c10f5b3 100644 --- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp +++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp @@ -95,7 +95,7 @@ void ChromeClientAndroid::scheduleCompositingLayerSync() m_needsLayerSync = true; WebViewCore* webViewCore = WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view()); if (webViewCore) - webViewCore->layersDraw(); + webViewCore->contentDraw(); } void ChromeClientAndroid::setNeedsOneShotDrawingSynchronization() @@ -238,11 +238,7 @@ void ChromeClientAndroid::addMessageToConsole(MessageSource, MessageType, Messag android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->addMessageToConsole(message, lineNumber, sourceID, msgLevel); } -void ChromeClientAndroid::formDidBlur(const WebCore::Node* node) -{ - android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->formDidBlur(node); -} - +void ChromeClientAndroid::formDidBlur(const WebCore::Node* node) { notImplemented(); } bool ChromeClientAndroid::canRunBeforeUnloadConfirmPanel() { return true; } bool ChromeClientAndroid::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) { String url = frame->document()->documentURI(); diff --git a/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp b/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp index 95ced96..52aeb23 100644 --- a/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp +++ b/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp @@ -264,7 +264,9 @@ public: if (!m_poster || (!m_poster->getPixels() && !m_poster->pixelRef())) return; - SkCanvas* canvas = ctxt->platformContext()->mCanvas; + SkCanvas* canvas = ctxt->platformContext()->getCanvas(); + if (!canvas) + return; // We paint with the following rules in mind: // - only downscale the poster, never upscale // - maintain the natural aspect ratio of the poster diff --git a/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp b/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp index 77e3c32..d846daf 100644 --- a/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp +++ b/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp @@ -30,6 +30,7 @@ #include "UrlInterceptResponse.h" #include "WebCoreJni.h" +#include <ScopedLocalRef.h> #include <utils/Log.h> namespace android { @@ -38,15 +39,14 @@ class JavaInputStreamWrapper { public: JavaInputStreamWrapper(JNIEnv* env, jobject inputStream) : m_inputStream(env->NewGlobalRef(inputStream)) - , m_buffer(0) { - LOG_ALWAYS_FATAL_IF(!inputStream); - jclass inputStreamClass = env->FindClass("java/io/InputStream"); - LOG_ALWAYS_FATAL_IF(!inputStreamClass); - m_read = env->GetMethodID(inputStreamClass, "read", "([B)I"); + , m_buffer(NULL) { + LOG_ALWAYS_FATAL_IF(!m_inputStream); + ScopedLocalRef<jclass> inputStreamClass(env, env->FindClass("java/io/InputStream")); + LOG_ALWAYS_FATAL_IF(!inputStreamClass.get()); + m_read = env->GetMethodID(inputStreamClass.get(), "read", "([B)I"); LOG_ALWAYS_FATAL_IF(!m_read); - m_close = env->GetMethodID(inputStreamClass, "close", "()V"); + m_close = env->GetMethodID(inputStreamClass.get(), "close", "()V"); LOG_ALWAYS_FATAL_IF(!m_close); - env->DeleteLocalRef(inputStreamClass); } ~JavaInputStreamWrapper() { @@ -63,10 +63,10 @@ public: JNIEnv* env = JSC::Bindings::getJNIEnv(); // Initialize our read buffer to the capacity of out. if (!m_buffer) { - m_buffer = env->NewByteArray(out->capacity()); - m_buffer = (jbyteArray) env->NewGlobalRef(m_buffer); + ScopedLocalRef<jbyteArray> buffer_local(env, env->NewByteArray(out->capacity())); + m_buffer = static_cast<jbyteArray>(env->NewGlobalRef(buffer_local.get())); } - int size = (int) env->CallIntMethod(m_inputStream, m_read, m_buffer); + int size = env->CallIntMethod(m_inputStream, m_read, m_buffer); if (checkException(env) || size < 0) return; // Copy from m_buffer to out. @@ -82,40 +82,32 @@ private: }; UrlInterceptResponse::UrlInterceptResponse(JNIEnv* env, jobject response) { - jclass javaResponse = env->FindClass("android/webkit/WebResourceResponse"); - LOG_ALWAYS_FATAL_IF(!javaResponse); - jfieldID mimeType = env->GetFieldID(javaResponse, "mMimeType", - "Ljava/lang/String;"); + ScopedLocalRef<jclass> javaResponse(env, env->FindClass("android/webkit/WebResourceResponse")); + LOG_ALWAYS_FATAL_IF(!javaResponse.get()); + jfieldID mimeType = env->GetFieldID(javaResponse.get(), "mMimeType", "Ljava/lang/String;"); LOG_ALWAYS_FATAL_IF(!mimeType); - jfieldID encoding = env->GetFieldID(javaResponse, "mEncoding", - "Ljava/lang/String;"); + jfieldID encoding = env->GetFieldID(javaResponse.get(), "mEncoding", "Ljava/lang/String;"); LOG_ALWAYS_FATAL_IF(!encoding); - jfieldID inputStream = env->GetFieldID(javaResponse, "mInputStream", - "Ljava/io/InputStream;"); + jfieldID inputStream = env->GetFieldID(javaResponse.get(), "mInputStream", "Ljava/io/InputStream;"); LOG_ALWAYS_FATAL_IF(!inputStream); - jobject stream = env->GetObjectField(response, inputStream); - if (stream) - m_inputStream.set(new JavaInputStreamWrapper(env, stream)); + ScopedLocalRef<jobject> stream(env, env->GetObjectField(response, inputStream)); + if (stream.get()) + m_inputStream.set(new JavaInputStreamWrapper(env, stream.get())); - jstring mimeStr = (jstring) env->GetObjectField(response, mimeType); - jstring encodingStr = (jstring) env->GetObjectField(response, encoding); + ScopedLocalRef<jstring> mimeStr(env, static_cast<jstring>(env->GetObjectField(response, mimeType))); + ScopedLocalRef<jstring> encodingStr(env, static_cast<jstring>(env->GetObjectField(response, encoding))); - if (mimeStr) { - const char* s = env->GetStringUTFChars(mimeStr, NULL); - m_mimeType.assign(s, env->GetStringUTFLength(mimeStr)); - env->ReleaseStringUTFChars(mimeStr, s); + if (mimeStr.get()) { + const char* s = env->GetStringUTFChars(mimeStr.get(), NULL); + m_mimeType.assign(s, env->GetStringUTFLength(mimeStr.get())); + env->ReleaseStringUTFChars(mimeStr.get(), s); } - if (encodingStr) { - const char* s = env->GetStringUTFChars(encodingStr, NULL); - m_encoding.assign(s, env->GetStringUTFLength(encodingStr)); - env->ReleaseStringUTFChars(encodingStr, s); + if (encodingStr.get()) { + const char* s = env->GetStringUTFChars(encodingStr.get(), NULL); + m_encoding.assign(s, env->GetStringUTFLength(encodingStr.get())); + env->ReleaseStringUTFChars(encodingStr.get(), s); } - - env->DeleteLocalRef(javaResponse); - env->DeleteLocalRef(stream); - env->DeleteLocalRef(mimeStr); - env->DeleteLocalRef(encodingStr); } UrlInterceptResponse::~UrlInterceptResponse() { diff --git a/Source/WebKit/android/jni/PictureSet.cpp b/Source/WebKit/android/jni/PictureSet.cpp index f3534eb..8beb0ef 100644 --- a/Source/WebKit/android/jni/PictureSet.cpp +++ b/Source/WebKit/android/jni/PictureSet.cpp @@ -38,6 +38,8 @@ #include "SkRegion.h" #include "SkStream.h" +#include "PlatformGraphicsContext.h" + #define MAX_DRAW_TIME 100 #define MIN_SPLITTABLE 400 #define MAX_ADDITIONAL_AREA 0.65 @@ -133,6 +135,9 @@ void PictureSet::add(const Pictures* temp) { Pictures pictureAndBounds = *temp; SkSafeRef(pictureAndBounds.mPicture); +#ifdef CONTEXT_RECORDING + SkSafeRef(pictureAndBounds.mGraphicsOperationCollection); +#endif pictureAndBounds.mWroteElapsed = false; mPictures.append(pictureAndBounds); } @@ -478,13 +483,20 @@ void PictureSet::add(const SkIRect& area, uint32_t elapsed, bool split, bool emp working->mArea.setEmpty(); SkSafeUnref(working->mPicture); working->mPicture = 0; +#ifdef CONTEXT_RECORDING + SkSafeUnref(working->mGraphicsOperationCollection); + working->mGraphicsOperationCollection = 0; +#endif } } // Now we can add the new Picture to the list, with the correct area // that need to be repainted - Pictures pictureAndBounds = {totalArea, 0, totalArea, - elapsed, split, false, false, empty}; + Pictures pictureAndBounds = {totalArea, 0, +#ifdef CONTEXT_RECORDING + 0, +#endif + totalArea, elapsed, split, false, false, empty}; #ifdef FAST_PICTURESET if (mPictures.size() == 0) @@ -525,6 +537,10 @@ void PictureSet::add(const SkIRect& area, uint32_t elapsed, bool split, bool emp working->mArea.setEmpty(); SkSafeUnref(working->mPicture); working->mPicture = 0; +#ifdef CONTEXT_RECORDING + SkSafeUnref(working->mGraphicsOperationCollection); + working->mGraphicsOperationCollection = 0; +#endif } } @@ -677,6 +693,9 @@ void PictureSet::clear() for (Pictures* working = mPictures.begin(); working != last; working++) { working->mArea.setEmpty(); SkSafeUnref(working->mPicture); +#ifdef CONTEXT_RECORDING + SkSafeUnref(working->mGraphicsOperationCollection); +#endif } mPictures.clear(); #endif // FAST_PICTURESET @@ -797,7 +816,14 @@ bool PictureSet::draw(SkCanvas* canvas) canvas->translate(pathBounds.fLeft, pathBounds.fTop); canvas->save(); uint32_t startTime = getThreadMsec(); + +#ifdef CONTEXT_RECORDING + WebCore::PlatformGraphicsContextSkia context(canvas); + working->mGraphicsOperationCollection->apply(&context); +#else canvas->drawPicture(*working->mPicture); +#endif + size_t elapsed = working->mElapsed = getThreadMsec() - startTime; working->mWroteElapsed = true; if (maxElapsed < elapsed && (pathBounds.width() >= MIN_SPLITTABLE || @@ -1060,6 +1086,14 @@ void PictureSet::setPicture(size_t i, SkPicture* p) mPictures[i].mEmpty = emptyPicture(p); } +#ifdef CONTEXT_RECORDING +void PictureSet::setGraphicsOperationCollection(size_t i, WebCore::GraphicsOperationCollection* p) +{ + SkSafeUnref(mPictures[i].mGraphicsOperationCollection); + mPictures[i].mGraphicsOperationCollection = p; +} +#endif + void PictureSet::split(PictureSet* out) const { dump(__FUNCTION__); diff --git a/Source/WebKit/android/jni/PictureSet.h b/Source/WebKit/android/jni/PictureSet.h index 1d9a14d..1e639da 100644 --- a/Source/WebKit/android/jni/PictureSet.h +++ b/Source/WebKit/android/jni/PictureSet.h @@ -45,7 +45,10 @@ #include <wtf/Vector.h> #include <wtf/HashMap.h> +#include "GraphicsOperationCollection.h" + // #define FAST_PICTURESET // use a hierarchy of pictures +// #define CONTEXT_RECORDING // use the new PlatformGraphicsContextRecording class SkCanvas; class SkPicture; @@ -100,6 +103,9 @@ namespace android { const SkIRect& bounds(size_t i) const { return mPictures[i].mArea; } void setPicture(size_t i, SkPicture* p); +#ifdef CONTEXT_RECORDING + void setGraphicsOperationCollection(size_t i, WebCore::GraphicsOperationCollection* p); +#endif void setDrawTimes(const PictureSet& ); size_t size() const { return mPictures.size(); } void split(PictureSet* result) const; @@ -119,9 +125,13 @@ namespace android { int mBucketCountX; int mBucketCountY; #else + struct Pictures { SkIRect mArea; SkPicture* mPicture; +#ifdef CONTEXT_RECORDING + WebCore::GraphicsOperationCollection* mGraphicsOperationCollection; +#endif SkIRect mUnsplit; uint32_t mElapsed; bool mSplit : 8; diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp index bfce349..3fdc3e6 100644 --- a/Source/WebKit/android/jni/ViewStateSerializer.cpp +++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp @@ -40,6 +40,7 @@ #include "PictureLayerContent.h" #include "PictureSet.h" #include "ScrollableLayerAndroid.h" +#include "SkFlattenable.h" #include "SkPicture.h" #include "TilesManager.h" diff --git a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp index d0f3830..7a2971a 100644 --- a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp +++ b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp @@ -316,7 +316,6 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* ALOG_ASSERT(mJavaFrame->mAutoLogin, "Could not find method autoLogin"); mUserAgent = WTF::String(); - mUserInitiatedAction = false; mBlockNetworkLoads = false; m_renderSkins = 0; } diff --git a/Source/WebKit/android/jni/WebCoreFrameBridge.h b/Source/WebKit/android/jni/WebCoreFrameBridge.h index 13f99af..30c1d83 100644 --- a/Source/WebKit/android/jni/WebCoreFrameBridge.h +++ b/Source/WebKit/android/jni/WebCoreFrameBridge.h @@ -128,13 +128,6 @@ class WebFrame : public WebCoreRefObject { // application. void autoLogin(const std::string& loginHeader); - /** - * When the user initiates a click, we set mUserInitiatedAction to true. - * If a load happens due to this click, then we ask the application if it wants - * to override the load. Otherwise, we attempt to load the resource internally. - */ - void setUserInitiatedAction(bool userInitiatedAction) { mUserInitiatedAction = userInitiatedAction; } - WebCore::Page* page() const { return mPage; } // Currently used only by the chrome net stack. A similar field is used by @@ -163,7 +156,6 @@ class WebFrame : public WebCoreRefObject { WebCore::Page* mPage; WTF::String mUserAgent; bool mBlockNetworkLoads; - bool mUserInitiatedAction; WebCore::RenderSkinAndroid* m_renderSkins; }; diff --git a/Source/WebKit/android/jni/WebCoreJni.cpp b/Source/WebKit/android/jni/WebCoreJni.cpp index 6dfc9f1..72ded59 100644 --- a/Source/WebKit/android/jni/WebCoreJni.cpp +++ b/Source/WebKit/android/jni/WebCoreJni.cpp @@ -118,8 +118,10 @@ jobject intRectToRect(JNIEnv* env, const WebCore::IntRect& rect) ALOG_ASSERT(rectClass, "Could not find android/graphics/Rect"); jmethodID rectInit = env->GetMethodID(rectClass, "<init>", "(IIII)V"); ALOG_ASSERT(rectInit, "Could not find init method on Rect"); - return env->NewObject(rectClass, rectInit, rect.x(), rect.y(), + jobject jrect = env->NewObject(rectClass, rectInit, rect.x(), rect.y(), rect.maxX(), rect.maxY()); + env->DeleteLocalRef(rectClass); + return jrect; } jobjectArray intRectVectorToRectArray(JNIEnv* env, Vector<WebCore::IntRect>& rects) diff --git a/Source/WebKit/android/jni/WebFrameView.cpp b/Source/WebKit/android/jni/WebFrameView.cpp index f30e5b7..10e31dc 100644 --- a/Source/WebKit/android/jni/WebFrameView.cpp +++ b/Source/WebKit/android/jni/WebFrameView.cpp @@ -61,7 +61,7 @@ void WebFrameView::draw(WebCore::GraphicsContext* gc, const WebCore::IntRect& re mFrameView->paintContents(gc, rect); else { // FIXME: I'm not entirely sure this ever happens or is needed - gc->setFillColor(Color::white, ColorSpaceDeviceRGB); + gc->setFillColor(WebCore::Color::white, WebCore::ColorSpaceDeviceRGB); gc->fillRect(rect); } } diff --git a/Source/WebKit/android/jni/WebSettings.cpp b/Source/WebKit/android/jni/WebSettings.cpp index 65ac360..cec44c1 100644 --- a/Source/WebKit/android/jni/WebSettings.cpp +++ b/Source/WebKit/android/jni/WebSettings.cpp @@ -118,6 +118,9 @@ struct FieldIds { mGeolocationEnabled = env->GetFieldID(clazz, "mGeolocationEnabled", "Z"); mGeolocationDatabasePath = env->GetFieldID(clazz, "mGeolocationDatabasePath", "Ljava/lang/String;"); mXSSAuditorEnabled = env->GetFieldID(clazz, "mXSSAuditorEnabled", "Z"); +#if ENABLE(LINK_PREFETCH) + mLinkPrefetchEnabled = env->GetFieldID(clazz, "mLinkPrefetchEnabled", "Z"); +#endif mJavaScriptCanOpenWindowsAutomatically = env->GetFieldID(clazz, "mJavaScriptCanOpenWindowsAutomatically", "Z"); mUseWideViewport = env->GetFieldID(clazz, "mUseWideViewport", "Z"); @@ -245,6 +248,9 @@ struct FieldIds { jfieldID mGeolocationEnabled; jfieldID mGeolocationDatabasePath; jfieldID mXSSAuditorEnabled; +#if ENABLE(LINK_PREFETCH) + jfieldID mLinkPrefetchEnabled; +#endif #if ENABLE(DATABASE) || ENABLE(DOM_STORAGE) jfieldID mDatabasePath; jfieldID mDatabasePathHasBeenSet; @@ -545,6 +551,11 @@ public: flag = env->GetBooleanField(obj, gFieldIds->mXSSAuditorEnabled); s->setXSSAuditorEnabled(flag); +#if ENABLE(LINK_PREFETCH) + flag = env->GetBooleanField(obj, gFieldIds->mLinkPrefetchEnabled); + s->setLinkPrefetchEnabled(flag); +#endif + size = env->GetIntField(obj, gFieldIds->mPageCacheCapacity); if (size > 0) { s->setUsesPageCache(true); diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index bb76c80..cdd484b 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -62,6 +62,7 @@ #include "Geolocation.h" #include "GraphicsContext.h" #include "GraphicsJNI.h" +#include "GraphicsOperationCollection.h" #include "HTMLAnchorElement.h" #include "HTMLAreaElement.h" #include "HTMLElement.h" @@ -107,6 +108,7 @@ #include "ResourceRequest.h" #include "RuntimeEnabledFeatures.h" #include "SchemeRegistry.h" +#include "ScopedLocalRef.h" #include "ScriptController.h" #include "SelectionController.h" #include "SelectText.h" @@ -322,7 +324,6 @@ struct WebViewCore::JavaGlue { jweak m_obj; jmethodID m_scrollTo; jmethodID m_contentDraw; - jmethodID m_layersDraw; jmethodID m_requestListBox; jmethodID m_openFileChooser; jmethodID m_requestSingleListBox; @@ -351,7 +352,6 @@ struct WebViewCore::JavaGlue { jmethodID m_getDeviceMotionService; jmethodID m_getDeviceOrientationService; jmethodID m_addMessageToConsole; - jmethodID m_formDidBlur; jmethodID m_focusNodeChanged; jmethodID m_getPluginClass; jmethodID m_showFullScreenPlugin; @@ -371,7 +371,6 @@ struct WebViewCore::JavaGlue { jmethodID m_setWebTextViewAutoFillable; jmethodID m_selectAt; jmethodID m_initEditField; - jmethodID m_updateMatchCount; jmethodID m_chromeCanTakeFocus; jmethodID m_chromeTakeFocus; AutoJObject object(JNIEnv* env) { @@ -398,7 +397,7 @@ struct WebViewCore::TextFieldInitDataGlue { jfieldID m_name; jfieldID m_label; jfieldID m_maxLength; - jfieldID m_nodeBounds; + jfieldID m_contentBounds; jfieldID m_nodeLayerId; jfieldID m_contentRect; }; @@ -421,7 +420,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m , m_textFieldInitDataGlue(new TextFieldInitDataGlue) , m_mainFrame(mainframe) , m_popupReply(0) - , m_blurringNodePointer(0) , m_blockTextfieldUpdates(false) , m_focusBoundsChanged(false) , m_skipContentDraw(false) @@ -458,7 +456,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_obj = env->NewWeakGlobalRef(javaWebViewCore); m_javaGlue->m_scrollTo = GetJMethod(env, clazz, "contentScrollTo", "(IIZZ)V"); m_javaGlue->m_contentDraw = GetJMethod(env, clazz, "contentDraw", "()V"); - m_javaGlue->m_layersDraw = GetJMethod(env, clazz, "layersDraw", "()V"); m_javaGlue->m_requestListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[I[I)V"); m_javaGlue->m_openFileChooser = GetJMethod(env, clazz, "openFileChooser", "(Ljava/lang/String;)Ljava/lang/String;"); m_javaGlue->m_requestSingleListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[II)V"); @@ -487,7 +484,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_getDeviceMotionService = GetJMethod(env, clazz, "getDeviceMotionService", "()Landroid/webkit/DeviceMotionService;"); m_javaGlue->m_getDeviceOrientationService = GetJMethod(env, clazz, "getDeviceOrientationService", "()Landroid/webkit/DeviceOrientationService;"); m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;I)V"); - m_javaGlue->m_formDidBlur = GetJMethod(env, clazz, "formDidBlur", "(I)V"); m_javaGlue->m_focusNodeChanged = GetJMethod(env, clazz, "focusNodeChanged", "(ILandroid/webkit/WebViewCore$WebKitHitTest;)V"); m_javaGlue->m_getPluginClass = GetJMethod(env, clazz, "getPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;"); m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/ViewManager$ChildView;II)V"); @@ -509,7 +505,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V"); m_javaGlue->m_selectAt = GetJMethod(env, clazz, "selectAt", "(II)V"); m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(IIILandroid/webkit/WebViewCore$TextFieldInitData;)V"); - m_javaGlue->m_updateMatchCount = GetJMethod(env, clazz, "updateMatchCount", "(IILjava/lang/String;)V"); m_javaGlue->m_chromeCanTakeFocus = GetJMethod(env, clazz, "chromeCanTakeFocus", "(I)Z"); m_javaGlue->m_chromeTakeFocus = GetJMethod(env, clazz, "chromeTakeFocus", "(I)V"); env->DeleteLocalRef(clazz); @@ -527,7 +522,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_textFieldInitDataGlue->m_name = env->GetFieldID(tfidClazz, "mName", "Ljava/lang/String;"); m_textFieldInitDataGlue->m_label = env->GetFieldID(tfidClazz, "mLabel", "Ljava/lang/String;"); m_textFieldInitDataGlue->m_maxLength = env->GetFieldID(tfidClazz, "mMaxLength", "I"); - m_textFieldInitDataGlue->m_nodeBounds = env->GetFieldID(tfidClazz, "mNodeBounds", "Landroid/graphics/Rect;"); + m_textFieldInitDataGlue->m_contentBounds = env->GetFieldID(tfidClazz, "mContentBounds", "Landroid/graphics/Rect;"); m_textFieldInitDataGlue->m_nodeLayerId = env->GetFieldID(tfidClazz, "mNodeLayerId", "I"); m_textFieldInitDataGlue->m_contentRect = env->GetFieldID(tfidClazz, "mContentRect", "Landroid/graphics/Rect;"); m_textFieldInitDataGlue->m_constructor = GetJMethod(env, tfidClazz, "<init>", "()V"); @@ -790,7 +785,7 @@ SkPicture* WebViewCore::rebuildPicture(const SkIRect& inval) SkAutoMemoryUsageProbe mup(__FUNCTION__); SkCanvas* recordingCanvas = arp.getRecordingCanvas(); - WebCore::PlatformGraphicsContext pgc(recordingCanvas); + WebCore::PlatformGraphicsContextSkia pgc(recordingCanvas); WebCore::GraphicsContext gc(&pgc); IntPoint origin = view->minimumScrollPosition(); WebCore::IntRect drawArea(inval.fLeft + origin.x(), inval.fTop + origin.y(), @@ -806,6 +801,27 @@ SkPicture* WebViewCore::rebuildPicture(const SkIRect& inval) return picture; } +#ifdef CONTEXT_RECORDING +GraphicsOperationCollection* WebViewCore::rebuildGraphicsOperationCollection(const SkIRect& inval) +{ + WebCore::FrameView* view = m_mainFrame->view(); + int width = view->contentsWidth(); + int height = view->contentsHeight(); + + IntPoint origin = view->minimumScrollPosition(); + WebCore::IntRect drawArea(inval.fLeft + origin.x(), inval.fTop + origin.y(), + inval.width(), inval.height()); + + AutoGraphicsOperationCollection autoPicture(drawArea); + view->platformWidget()->draw(autoPicture.context(), drawArea); + + m_rebuildInval.op(inval, SkRegion::kUnion_Op); + + SkSafeRef(autoPicture.picture()); + return autoPicture.picture(); +} +#endif + void WebViewCore::rebuildPictureSet(PictureSet* pictureSet) { #ifdef FAST_PICTURESET @@ -831,24 +847,16 @@ void WebViewCore::rebuildPictureSet(PictureSet* pictureSet) DBG_SET_LOGD("pictSet=%p [%d] {%d,%d,w=%d,h=%d}", pictureSet, index, inval.fLeft, inval.fTop, inval.width(), inval.height()); pictureSet->setPicture(index, rebuildPicture(inval)); +#ifdef CONTEXT_RECORDING + pictureSet->setGraphicsOperationCollection(index, + rebuildGraphicsOperationCollection(inval)); +#endif } pictureSet->validate(__FUNCTION__); #endif } -bool WebViewCore::updateLayers(LayerAndroid* layers) -{ - // We update the layers - ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client()); - GraphicsLayerAndroid* root = static_cast<GraphicsLayerAndroid*>(chromeC->layersSync()); - if (root) { - LayerAndroid* updatedLayer = root->contentLayer(); - return layers->updateWithTree(updatedLayer); - } - return true; -} - void WebViewCore::notifyAnimationStarted() { // We notify webkit that the animations have begun @@ -874,16 +882,25 @@ BaseLayerAndroid* WebViewCore::createBaseLayer(SkRegion* region) #if USE(ACCELERATED_COMPOSITING) // We set the background color + Color background = Color::white; if (m_mainFrame && m_mainFrame->document() && m_mainFrame->document()->body()) { + bool hasCSSBackground = false; + Document* document = m_mainFrame->document(); RefPtr<RenderStyle> style = document->styleForElementIgnoringPendingStylesheets(document->body()); if (style->hasBackground()) { - Color color = style->visitedDependentColor(CSSPropertyBackgroundColor); - if (color.isValid() && color.alpha() > 0) - base->setBackgroundColor(color); + background = style->visitedDependentColor(CSSPropertyBackgroundColor); + hasCSSBackground = true; + } + + WebCore::FrameView* view = m_mainFrame->view(); + if (view) { + Color viewBackground = view->baseBackgroundColor(); + background = hasCSSBackground ? viewBackground.blend(background) : viewBackground; } } + base->setBackgroundColor(background); // We update the layers ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client()); @@ -990,16 +1007,6 @@ void WebViewCore::contentDraw() checkException(env); } -void WebViewCore::layersDraw() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue->object(env); - if (!javaObject.get()) - return; - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_layersDraw); - checkException(env); -} - void WebViewCore::contentInvalidate(const WebCore::IntRect &r) { DBG_SET_LOGD("rect={%d,%d,w=%d,h=%d}", r.x(), r.y(), r.width(), r.height()); @@ -1619,7 +1626,7 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) RenderText* renderText = toRenderText(r); int caretOffset; InlineBox* inlineBox; - start.getInlineBoxAndOffset(DOWNSTREAM, inlineBox, caretOffset); + start.getInlineBoxAndOffset(selection.affinity(), inlineBox, caretOffset); startHandle = renderText->localCaretRect(inlineBox, caretOffset); FloatPoint absoluteOffset = renderText->localToAbsolute(startHandle.location()); startHandle.setX(absoluteOffset.x() - layerOffset.x()); @@ -1667,10 +1674,50 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) selectTextContainer->setCaretRect(SelectText::EndHandle, endHandle); selectTextContainer->setText(range->text()); + selectTextContainer->setTextRect(SelectText::StartHandle, + positionToTextRect(selection.start(), selection.affinity())); + selectTextContainer->setTextRect(SelectText::EndHandle, + positionToTextRect(selection.end(), selection.affinity())); return selectTextContainer; } +IntRect WebViewCore::positionToTextRect(const Position& position, EAffinity affinity) +{ + IntRect textRect; + InlineBox* inlineBox; + int offset; + position.getInlineBoxAndOffset(affinity, inlineBox, offset); + if (inlineBox && inlineBox->isInlineTextBox()) { + InlineTextBox* box = static_cast<InlineTextBox*>(inlineBox); + RootInlineBox* root = box->root(); + RenderText* renderText = box->textRenderer(); + int left = root->logicalLeft(); + int width = root->logicalWidth(); + int top = root->selectionTop(); + int height = root->selectionHeight(); + + Node* node = position.anchorNode(); + LayerAndroid* layer = 0; + int layerId = platformLayerIdFromNode(node, &layer); + IntPoint layerOffset; + layerToAbsoluteOffset(layer, layerOffset); + + if (!renderText->style()->isHorizontalWritingMode()) { + swap(left, top); + swap(width, height); + } + FloatPoint origin(left, top); + FloatPoint absoluteOrigin = renderText->localToAbsolute(origin); + + textRect.setX(absoluteOrigin.x() - layerOffset.x()); + textRect.setWidth(width); + textRect.setY(absoluteOrigin.y() - layerOffset.y()); + textRect.setHeight(height); + } + return textRect; +} + IntPoint WebViewCore::convertGlobalContentToFrameContent(const IntPoint& point, WebCore::Frame* frame) { if (!frame) frame = focusedFrame(); @@ -2890,17 +2937,17 @@ void WebViewCore::passToJs(int generation, const WTF::String& current, updateTextSelection(); } -void WebViewCore::scrollFocusedTextInput(float xPercent, int y) +WebCore::IntRect WebViewCore::scrollFocusedTextInput(float xPercent, int y) { WebCore::Node* focus = currentFocus(); if (!focus) { clearTextEntry(); - return; + return WebCore::IntRect(); } WebCore::RenderTextControl* renderText = toRenderTextControl(focus); if (!renderText) { clearTextEntry(); - return; + return WebCore::IntRect(); } int x = (int) (xPercent * (renderText->scrollWidth() - @@ -2908,6 +2955,9 @@ void WebViewCore::scrollFocusedTextInput(float xPercent, int y) renderText->setScrollLeft(x); renderText->setScrollTop(y); focus->document()->frame()->selection()->recomputeCaretRect(); + LayerAndroid* layer = 0; + platformLayerIdFromNode(focus, &layer); + return absoluteContentRect(focus, layer); } void WebViewCore::setFocusControllerActive(bool active) @@ -3215,6 +3265,23 @@ void WebViewCore::touchUp(int touchGeneration, handleMouseClick(frame, node, false); } +bool WebViewCore::performMouseClick() +{ + WebCore::PlatformMouseEvent mouseDown(m_mousePos, m_mousePos, WebCore::LeftButton, + WebCore::MouseEventPressed, 1, false, false, false, false, + WTF::currentTime()); + // ignore the return from as it will return true if the hit point can trigger selection change + m_mainFrame->eventHandler()->handleMousePressEvent(mouseDown); + WebCore::PlatformMouseEvent mouseUp(m_mousePos, m_mousePos, WebCore::LeftButton, + WebCore::MouseEventReleased, 1, false, false, false, false, + WTF::currentTime()); + bool handled = m_mainFrame->eventHandler()->handleMouseReleaseEvent(mouseUp); + + WebCore::Node* focusNode = currentFocus(); + initializeTextInput(focusNode, false); + return handled; +} + // Check for the "x-webkit-soft-keyboard" attribute. If it is there and // set to hidden, do not show the soft keyboard. Node passed as a parameter // must not be null. @@ -3242,15 +3309,12 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node // Need to special case area tags because an image map could have an area element in the middle // so when attempting to get the default, the point chosen would be follow the wrong link. if (nodePtr->hasTagName(WebCore::HTMLNames::areaTag)) { - webFrame->setUserInitiatedAction(true); nodePtr->dispatchSimulatedClick(0, true, true); - webFrame->setUserInitiatedAction(false); return true; } } if (!valid || !framePtr) framePtr = m_mainFrame; - webFrame->setUserInitiatedAction(true); WebCore::PlatformMouseEvent mouseDown(m_mousePos, m_mousePos, WebCore::LeftButton, WebCore::MouseEventPressed, 1, false, false, false, false, WTF::currentTime()); @@ -3260,7 +3324,6 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node WebCore::MouseEventReleased, 1, false, false, false, false, WTF::currentTime()); bool handled = framePtr->eventHandler()->handleMouseReleaseEvent(mouseUp); - webFrame->setUserInitiatedAction(false); WebCore::Node* focusNode = currentFocus(); initializeTextInput(focusNode, fake); @@ -3337,34 +3400,37 @@ bool WebViewCore::isAutoCompleteEnabled(Node* node) return isEnabled; } -WebCore::IntRect WebViewCore::boundingRect(WebCore::Node* node, +WebCore::IntRect WebViewCore::absoluteContentRect(WebCore::Node* node, LayerAndroid* layer) { - // Caret selection - IntRect boundingRect; + IntRect contentRect; if (node) { RenderObject* render = node->renderer(); - if (render && !render->isBody()) { + if (render && render->isBox() && !render->isBody()) { IntPoint offset = convertGlobalContentToFrameContent(IntPoint(), node->document()->frame()); WebViewCore::layerToAbsoluteOffset(layer, offset); - boundingRect = render->absoluteBoundingBoxRect(true); - boundingRect.move(-offset.x(), -offset.y()); + + RenderBox* renderBox = toRenderBox(render); + contentRect = renderBox->absoluteContentBox(); + contentRect.move(-offset.x(), -offset.y()); } } - return boundingRect; + return contentRect; } jobject WebViewCore::createTextFieldInitData(Node* node) { JNIEnv* env = JSC::Bindings::getJNIEnv(); TextFieldInitDataGlue* classDef = m_textFieldInitDataGlue; - jclass clazz = env->FindClass("android/webkit/WebViewCore$TextFieldInitData"); - jobject initData = env->NewObject(clazz, classDef->m_constructor); + ScopedLocalRef<jclass> clazz(env, + env->FindClass("android/webkit/WebViewCore$TextFieldInitData")); + jobject initData = env->NewObject(clazz.get(), classDef->m_constructor); env->SetIntField(initData, classDef->m_fieldPointer, reinterpret_cast<int>(node)); - env->SetObjectField(initData, classDef->m_text, + ScopedLocalRef<jstring> inputText(env, wtfStringToJstring(env, getInputText(node), true)); + env->SetObjectField(initData, classDef->m_text, inputText.get()); env->SetIntField(initData, classDef->m_type, getInputType(node)); env->SetBooleanField(initData, classDef->m_isSpellCheckEnabled, isSpellCheckEnabled(node)); @@ -3378,16 +3444,18 @@ jobject WebViewCore::createTextFieldInitData(Node* node) isTextInput(document->previousFocusableNode(node, tabEvent.get()))); env->SetBooleanField(initData, classDef->m_isAutoCompleteEnabled, isAutoCompleteEnabled(node)); - env->SetObjectField(initData, classDef->m_name, + ScopedLocalRef<jstring> fieldName(env, wtfStringToJstring(env, getFieldName(node), false)); - env->SetObjectField(initData, classDef->m_name, + env->SetObjectField(initData, classDef->m_name, fieldName.get()); + ScopedLocalRef<jstring> label(env, wtfStringToJstring(env, requestLabel(document->frame(), node), false)); + env->SetObjectField(initData, classDef->m_name, label.get()); env->SetIntField(initData, classDef->m_maxLength, getMaxLength(node)); LayerAndroid* layer = 0; int layerId = platformLayerIdFromNode(node, &layer); - IntRect bounds = boundingRect(node, layer); - env->SetObjectField(initData, classDef->m_nodeBounds, - intRectToRect(env, bounds)); + IntRect bounds = absoluteContentRect(node, layer); + ScopedLocalRef<jobject> jbounds(env, intRectToRect(env, bounds)); + env->SetObjectField(initData, classDef->m_contentBounds, jbounds.get()); env->SetIntField(initData, classDef->m_nodeLayerId, layerId); IntRect contentRect; RenderTextControl* rtc = toRenderTextControl(node); @@ -3396,8 +3464,8 @@ jobject WebViewCore::createTextFieldInitData(Node* node) contentRect.setHeight(rtc->scrollHeight()); contentRect.move(-rtc->scrollLeft(), -rtc->scrollTop()); } - env->SetObjectField(initData, classDef->m_contentRect, - intRectToRect(env, contentRect)); + ScopedLocalRef<jobject> jcontentRect(env, intRectToRect(env, contentRect)); + env->SetObjectField(initData, classDef->m_contentRect, jcontentRect.get()); return initData; } @@ -3412,9 +3480,9 @@ void WebViewCore::initEditField(Node* node) int end = 0; getSelectionOffsets(node, start, end); SelectText* selectText = createSelectText(focusedFrame()->selection()->selection()); + ScopedLocalRef<jobject> initData(env, createTextFieldInitData(node)); env->CallVoidMethod(javaObject.get(), m_javaGlue->m_initEditField, - start, end, reinterpret_cast<int>(selectText), - createTextFieldInitData(node)); + start, end, reinterpret_cast<int>(selectText), initData.get()); checkException(env); } @@ -3436,15 +3504,6 @@ void WebViewCore::popupReply(const int* array, int count) } } -void WebViewCore::formDidBlur(const WebCore::Node* node) -{ - // If the blur is on a text input, keep track of the node so we can - // hide the soft keyboard when the new focus is set, if it is not a - // text input. - if (isTextInput(node)) - m_blurringNodePointer = reinterpret_cast<int>(node); -} - // This is a slightly modified Node::nextNodeConsideringAtomicNodes() with the // extra constraint of limiting the search to inside a containing parent WebCore::Node* nextNodeWithinParent(WebCore::Node* parent, WebCore::Node* start) @@ -3468,6 +3527,7 @@ void WebViewCore::initializeTextInput(WebCore::Node* node, bool fake) { if (node) { if (isTextInput(node)) { + bool showKeyboard = true; initEditField(node); WebCore::RenderTextControl* rtc = toRenderTextControl(node); if (rtc && node->hasTagName(HTMLNames::inputTag)) { @@ -3484,10 +3544,11 @@ void WebViewCore::initializeTextInput(WebCore::Node* node, bool fake) autoFill->formFieldFocused(inputElement); } #endif - } else if (!fake) { - requestKeyboard(false); - } + } else + showKeyboard = false; } + if (!fake) + requestKeyboard(showKeyboard); } else if (!fake && !nodeIsPlugin(node)) { // not a text entry field, put away the keyboard. clearTextEntry(); @@ -3505,12 +3566,7 @@ void WebViewCore::focusNodeChanged(WebCore::Node* newFocus) if (!javaObject.get()) return; if (isTextInput(newFocus)) - initializeTextInput(newFocus); - else if (m_blurringNodePointer) { - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_formDidBlur, m_blurringNodePointer); - checkException(env); - m_blurringNodePointer = 0; - } + initializeTextInput(newFocus, true); HitTestResult focusHitResult; focusHitResult.setInnerNode(newFocus); focusHitResult.setInnerNonSharedNode(newFocus); @@ -4242,19 +4298,15 @@ int WebViewCore::findTextOnPage(const WTF::String &text) frame = frame->tree()->traverseNextWithWrap(false); } while (frame); m_activeMatchIndex = m_matchCount - 1; // prime first findNext - if (!m_matchCount) // send at least one update, even if no hits - updateMatchCount(); - else - findNextOnPage(true); return m_matchCount; } -void WebViewCore::findNextOnPage(bool forward) +int WebViewCore::findNextOnPage(bool forward) { if (!m_mainFrame) - return; + return -1; if (!m_matchCount) - return; + return -1; EditorClientAndroid* client = static_cast<EditorClientAndroid*>( m_mainFrame->editor()->client()); @@ -4301,24 +4353,12 @@ void WebViewCore::findNextOnPage(bool forward) m_mainFrame->selection()->revealSelection( ScrollAlignment::alignCenterIfNeeded, true); } - updateMatchCount(); } // Clear selection so it doesn't display. m_mainFrame->selection()->clear(); client->setUiGeneratedSelectionChange(false); -} - -void WebViewCore::updateMatchCount() const -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue->object(env); - if (!javaObject.get()) - return; - jstring javaText = wtfStringToJstring(env, m_searchText, true); - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_updateMatchCount, - m_activeMatchIndex, m_matchCount, javaText); - checkException(env); + return m_activeMatchIndex; } String WebViewCore::getText(int startX, int startY, int endX, int endY) @@ -4496,10 +4536,12 @@ static void PassToJs(JNIEnv* env, jobject obj, jint nativeClass, } static void ScrollFocusedTextInput(JNIEnv* env, jobject obj, jint nativeClass, - jfloat xPercent, jint y) + jfloat xPercent, jint y, jobject contentBounds) { WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); - viewImpl->scrollFocusedTextInput(xPercent, y); + IntRect bounds = viewImpl->scrollFocusedTextInput(xPercent, y); + if (contentBounds) + GraphicsJNI::irect_to_jrect(bounds, env, contentBounds); } static void SetFocusControllerActive(JNIEnv* env, jobject obj, jint nativeClass, @@ -4525,19 +4567,6 @@ void WebViewCore::addVisitedLink(const UChar* string, int length) m_groupForVisitedLinks->addVisitedLink(string, length); } -static bool UpdateLayers(JNIEnv* env, jobject obj, jint nativeClass, - jint jbaseLayer) -{ - WebViewCore* viewImpl = (WebViewCore*) nativeClass; - BaseLayerAndroid* baseLayer = (BaseLayerAndroid*) jbaseLayer; - if (baseLayer) { - LayerAndroid* root = static_cast<LayerAndroid*>(baseLayer->getChild(0)); - if (root) - return viewImpl->updateLayers(root); - } - return true; -} - static void NotifyAnimationStarted(JNIEnv* env, jobject obj, jint nativeClass) { WebViewCore* viewImpl = (WebViewCore*) nativeClass; @@ -4646,6 +4675,12 @@ static void TouchUp(JNIEnv* env, jobject obj, jint nativeClass, (WebCore::Frame*) frame, (WebCore::Node*) node, x, y); } +static bool MouseClick(JNIEnv* env, jobject obj, jint nativeClass) +{ + WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); + return viewImpl->performMouseClick(); +} + static jstring RetrieveHref(JNIEnv* env, jobject obj, jint nativeClass, jint x, jint y) { @@ -5010,11 +5045,11 @@ static int FindAll(JNIEnv* env, jobject obj, jint nativeClass, return viewImpl->findTextOnPage(wtfText); } -static void FindNext(JNIEnv* env, jobject obj, jint nativeClass, +static int FindNext(JNIEnv* env, jobject obj, jint nativeClass, jboolean forward) { WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); - viewImpl->findNextOnPage(forward); + return viewImpl->findNextOnPage(forward); } // ---------------------------------------------------------------------------- @@ -5055,7 +5090,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) MoveMouse }, { "passToJs", "(IILjava/lang/String;IIZZZZ)V", (void*) PassToJs }, - { "nativeScrollFocusedTextInput", "(IFI)V", + { "nativeScrollFocusedTextInput", "(IFILandroid/graphics/Rect;)V", (void*) ScrollFocusedTextInput }, { "nativeSetFocusControllerActive", "(IZ)V", (void*) SetFocusControllerActive }, @@ -5067,6 +5102,8 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) HandleTouchEvent }, { "nativeTouchUp", "(IIIIII)V", (void*) TouchUp }, + { "nativeMouseClick", "(I)Z", + (void*) MouseClick }, { "nativeRetrieveHref", "(III)Ljava/lang/String;", (void*) RetrieveHref }, { "nativeRetrieveAnchorText", "(III)Ljava/lang/String;", @@ -5075,8 +5112,6 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) RetrieveImageSource }, { "nativeGetContentMinPrefWidth", "(I)I", (void*) GetContentMinPrefWidth }, - { "nativeUpdateLayers", "(II)Z", - (void*) UpdateLayers }, { "nativeNotifyAnimationStarted", "(I)V", (void*) NotifyAnimationStarted }, { "nativeRecordContent", "(ILandroid/graphics/Region;Landroid/graphics/Point;)I", @@ -5137,7 +5172,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) nativeCertTrustChanged }, { "nativeFindAll", "(ILjava/lang/String;)I", (void*) FindAll }, - { "nativeFindNext", "(IZ)V", + { "nativeFindNext", "(IZ)I", (void*) FindNext }, }; diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index 479f549..00b4bda 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -53,6 +53,7 @@ namespace WebCore { class Color; + class GraphicsOperationCollection; class FrameView; class HTMLAnchorElement; class HTMLElement; @@ -85,9 +86,6 @@ class SkPicture; class SkIRect; namespace android { - // TODO: This file hasn't been good about namespace. Remove this temporary - // workaround to build - using namespace WebCore; enum Direction { DIRECTION_BACKWARD = 0, @@ -138,12 +136,6 @@ namespace android { // Followings are called from native WebCore to Java - /** - * Notification that a form was blurred. Pass a message to hide the - * keyboard if it was showing for that Node. - * @param Node The Node that blurred. - */ - void formDidBlur(const WebCore::Node*); void focusNodeChanged(WebCore::Node*); /** @@ -174,7 +166,7 @@ namespace android { void layersDraw(); #if USE(ACCELERATED_COMPOSITING) - GraphicsLayerAndroid* graphicsRootLayer() const; + WebCore::GraphicsLayerAndroid* graphicsRootLayer() const; #endif /** Invalidate the view/screen, NOT the content/DOM, but expressed in @@ -214,7 +206,7 @@ namespace android { * Tell the java side to update the focused textfield * @param pointer Pointer to the node for the input field. * @param changeToPassword If true, we are changing the textfield to - * a password field, and ignore the String + * a password field, and ignore the WTF::String * @param text If changeToPassword is false, this is the new text that * should go into the textfield. */ @@ -290,12 +282,13 @@ namespace android { jobject getDeviceMotionService(); jobject getDeviceOrientationService(); - void addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID, int msgLevel); + void addMessageToConsole(const WTF::String& message, unsigned int lineNumber, const WTF::String& sourceID, int msgLevel); /** * Tell the Java side of the scrollbar mode */ - void setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode); + void setScrollbarModes(WebCore::ScrollbarMode horizontalMode, + WebCore::ScrollbarMode verticalMode); // // Followings support calls from Java to native WebCore @@ -310,7 +303,7 @@ namespace android { // scroll the selection on screen (if necessary). void revealSelection(); - void moveMouse(int x, int y, HitTestResult* hoveredNode = 0); + void moveMouse(int x, int y, WebCore::HitTestResult* hoveredNode = 0); // set the scroll amount that webview.java is currently showing void setScrollOffset(bool sendScrollEvent, int dx, int dy); @@ -326,8 +319,8 @@ namespace android { * @return Whether keyCode was handled by this class. */ bool key(const WebCore::PlatformKeyboardEvent& event); - bool chromeCanTakeFocus(FocusDirection direction); - void chromeTakeFocus(FocusDirection direction); + bool chromeCanTakeFocus(WebCore::FocusDirection direction); + void chromeTakeFocus(WebCore::FocusDirection direction); /** * Handle (trackball) click event / dpad center press from Java. @@ -339,7 +332,9 @@ namespace android { /** * Handle touch event */ - bool handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint>& points, int actionIndex, int metaState); + bool handleTouchEvent(int action, WTF::Vector<int>& ids, + WTF::Vector<WebCore::IntPoint>& points, + int actionIndex, int metaState); /** * Handle motionUp event from the UI thread (called touchUp in the @@ -355,6 +350,11 @@ namespace android { WebCore::Node* node, int x, int y); /** + * Clicks the mouse at its current location + */ + bool performMouseClick(); + + /** * Sets the index of the label from a popup */ void popupReply(int index); @@ -382,11 +382,11 @@ namespace android { * direction - The direction in which to alter the selection. * granularity - The granularity of the selection modification. * - * returns - The selected HTML as a string. This is not a well formed + * returns - The selected HTML as a WTF::String. This is not a well formed * HTML, rather the selection annotated with the tags of all * intermediary elements it crosses. */ - String modifySelection(const int direction, const int granularity); + WTF::String modifySelection(const int direction, const int granularity); /** * Moves the selection to the given node in a given frame i.e. selects that node. @@ -396,11 +396,11 @@ namespace android { * frame - The frame in which to select is the node to be selected. * node - The node to be selected. * - * returns - The selected HTML as a string. This is not a well formed + * returns - The selected HTML as a WTF::String. This is not a well formed * HTML, rather the selection annotated with the tags of all * intermediary elements it crosses. */ - String moveSelection(WebCore::Frame* frame, WebCore::Node* node); + WTF::String moveSelection(WebCore::Frame* frame, WebCore::Node* node); /** * In the currently focused textfield, replace the characters from oldStart to oldEnd @@ -415,7 +415,7 @@ namespace android { /** * Scroll the focused textfield to (x, y) in document space */ - void scrollFocusedTextInput(float x, int y); + WebCore::IntRect scrollFocusedTextInput(float x, int y); /** * Set the FocusController's active and focused states, so that * the caret will draw (true) or not. @@ -457,7 +457,7 @@ namespace android { void sendPluginSurfaceReady(); // send onLoad event to plugins who are descendents of the given frame - void notifyPluginsOnFrameLoad(const Frame*); + void notifyPluginsOnFrameLoad(const WebCore::Frame*); // gets a rect representing the current on-screen portion of the document void getVisibleScreen(ANPRectI&); @@ -515,11 +515,11 @@ namespace android { void centerFitRect(int x, int y, int width, int height); // return a list of rects matching the touch point (x, y) with the slop - Vector<IntRect> getTouchHighlightRects(int x, int y, int slop, - Node** node, HitTestResult* hitTestResult); + WTF::Vector<WebCore::IntRect> getTouchHighlightRects(int x, int y, int slop, + WebCore::Node** node, WebCore::HitTestResult* hitTestResult); // This does a sloppy hit test AndroidHitTestResult hitTestAtPoint(int x, int y, int slop, bool doMoveMouse = false); - static bool nodeIsClickableOrFocusable(Node* node); + static bool nodeIsClickableOrFocusable(WebCore::Node* node); // Open a file chooser for selecting a file to upload void openFileChooser(PassRefPtr<WebCore::FileChooser> ); @@ -530,13 +530,13 @@ namespace android { bool focusBoundsChanged(); // record the inval area, and the picture size - BaseLayerAndroid* recordContent(SkRegion* , SkIPoint* ); + WebCore::BaseLayerAndroid* recordContent(SkRegion* , SkIPoint* ); // This creates a new BaseLayerAndroid by copying the current m_content // and doing a copy of the layers. The layers' content may be updated // as we are calling layersSync(). - BaseLayerAndroid* createBaseLayer(SkRegion*); - bool updateLayers(LayerAndroid*); + WebCore::BaseLayerAndroid* createBaseLayer(SkRegion*); + bool updateLayers(WebCore::LayerAndroid*); void notifyAnimationStarted(); int textWrapWidth() const { return m_textWrapWidth; } @@ -557,7 +557,7 @@ namespace android { // find on page void resetFindOnPage(); int findTextOnPage(const WTF::String &text); - void findNextOnPage(bool forward); + int findNextOnPage(bool forward); void updateMatchCount() const; #if ENABLE(VIDEO) @@ -600,14 +600,16 @@ namespace android { */ Vector<WebCore::VisibleSelection> getTextRanges( int startX, int startY, int endX, int endY); - static int platformLayerIdFromNode(Node* node, LayerAndroid** outLayer = 0); + static int platformLayerIdFromNode(WebCore::Node* node, + WebCore::LayerAndroid** outLayer = 0); void selectText(int startX, int startY, int endX, int endY); bool selectWordAt(int x, int y); // Converts from the global content coordinates that WebView sends // to frame-local content coordinates using the focused frame - IntPoint convertGlobalContentToFrameContent(const IntPoint& point, WebCore::Frame* frame = 0); - static void layerToAbsoluteOffset(const LayerAndroid* layer, IntPoint& offset); + WebCore::IntPoint convertGlobalContentToFrameContent(const WebCore::IntPoint& point, WebCore::Frame* frame = 0); + static void layerToAbsoluteOffset(const WebCore::LayerAndroid* layer, + WebCore::IntPoint& offset); /** * Returns a text position at a given coordinate. @@ -615,7 +617,7 @@ namespace android { WebCore::VisiblePosition visiblePositionForWindowPoint(int x, int y); // Retrieves the current locale from system properties - void getLocale(String& language, String& region); + void getLocale(String& language, WTF::String& region); // Handles changes in system locale void updateLocale(); @@ -645,6 +647,9 @@ namespace android { void recordPictureSet(PictureSet* master); SkPicture* rebuildPicture(const SkIRect& inval); +#ifdef CONTEXT_RECORDING + WebCore::GraphicsOperationCollection* rebuildGraphicsOperationCollection(const SkIRect& inval); +#endif void rebuildPictureSet(PictureSet* ); void sendNotifyProgressFinished(); /* @@ -660,28 +665,38 @@ namespace android { const WebCore::QualifiedName& ); WebCore::HTMLImageElement* retrieveImageElement(int x, int y); // below are members responsible for accessibility support - String modifySelectionTextNavigationAxis(DOMSelection* selection, int direction, int granularity); - String modifySelectionDomNavigationAxis(DOMSelection* selection, int direction, int granularity); - Text* traverseNextContentTextNode(Node* fromNode, Node* toNode ,int direction); - bool isVisible(Node* node); - bool isHeading(Node* node); - String formatMarkup(DOMSelection* selection); + WTF::String modifySelectionTextNavigationAxis(WebCore::DOMSelection* selection, + int direction, int granularity); + WTF::String modifySelectionDomNavigationAxis(WebCore::DOMSelection* selection, + int direction, int granularity); + WebCore::Text* traverseNextContentTextNode(WebCore::Node* fromNode, + WebCore::Node* toNode, + int direction); + bool isVisible(WebCore::Node* node); + bool isHeading(WebCore::Node* node); + WTF::String formatMarkup(WebCore::DOMSelection* selection); void selectAt(int x, int y); - void scrollNodeIntoView(Frame* frame, Node* node); - bool isContentTextNode(Node* node); - Node* getIntermediaryInputElement(Node* fromNode, Node* toNode, int direction); - bool isContentInputElement(Node* node); - bool isDescendantOf(Node* parent, Node* node); - void advanceAnchorNode(DOMSelection* selection, int direction, String& markup, bool ignoreFirstNode, ExceptionCode& ec); - Node* getNextAnchorNode(Node* anchorNode, bool skipFirstHack, int direction); - Node* getImplicitBoundaryNode(Node* node, unsigned offset, int direction); - jobject createTextFieldInitData(Node* node); + void scrollNodeIntoView(WebCore::Frame* frame, WebCore::Node* node); + bool isContentTextNode(WebCore::Node* node); + WebCore::Node* getIntermediaryInputElement(WebCore::Node* fromNode, + WebCore::Node* toNode, + int direction); + bool isContentInputElement(WebCore::Node* node); + bool isDescendantOf(WebCore::Node* parent, WebCore::Node* node); + void advanceAnchorNode(WebCore::DOMSelection* selection, int direction, + WTF::String& markup, bool ignoreFirstNode, + WebCore::ExceptionCode& ec); + WebCore::Node* getNextAnchorNode(WebCore::Node* anchorNode, + bool skipFirstHack, int direction); + WebCore::Node* getImplicitBoundaryNode(WebCore::Node* node, + unsigned offset, int direction); + jobject createTextFieldInitData(WebCore::Node* node); /** * Calls into java to reset the text edit field with the * current contents and selection. */ - void initEditField(Node* node); + void initEditField(WebCore::Node* node); /** * If node is not a text input field or if it explicitly requests @@ -689,55 +704,59 @@ namespace android { * it is a text input field then initEditField is called and * auto-fill information is requested for HTML form input fields. */ - void initializeTextInput(Node* node, bool fake = false); + void initializeTextInput(WebCore::Node* node, bool fake); /** * Gets the input type a Node. NONE is returned if it isn't an * input field. */ - InputType getInputType(Node* node); + InputType getInputType(WebCore::Node* node); /** * If node is an input field, the spellcheck value for the * field is returned. Otherwise true is returned. */ - static bool isSpellCheckEnabled(Node* node); + static bool isSpellCheckEnabled(WebCore::Node* node); /** * Returns the offsets of the selection area for both normal text * fields and content editable fields. start and end are modified * by this method. */ - static void getSelectionOffsets(Node* node, int& start, int& end); + static void getSelectionOffsets(WebCore::Node* node, int& start, int& end); /** * Gets the plain text of the specified editable text field. node * may be content-editable or a plain text fields. */ - static String getInputText(Node* node); + static WTF::String getInputText(WebCore::Node* node); /** * Gets the RenderTextControl for the given node if it has one. * If its renderer isn't a RenderTextControl, then NULL is returned. */ - static RenderTextControl* toRenderTextControl(Node *node); + static WebCore::RenderTextControl* toRenderTextControl(WebCore::Node *node); /** * Sets the selection for node's editable field to the offsets * between start (inclusive) and end (exclusive). */ - static void setSelection(Node* node, int start, int end); + static void setSelection(WebCore::Node* node, int start, int end); /** * Returns the Position for the given offset for an editable * field. The offset is relative to the node start. */ - static WebCore::Position getPositionForOffset(Node* node, int offset); - - VisiblePosition visiblePositionForContentPoint(int x, int y); - VisiblePosition visiblePositionForContentPoint(const IntPoint& point); - bool selectWordAroundPosition(Frame* frame, VisiblePosition pos); - SelectText* createSelectText(const VisibleSelection&); - static int getMaxLength(Node* node); - static String getFieldName(Node* node); - static bool isAutoCompleteEnabled(Node* node); - IntRect boundingRect(Node* node, LayerAndroid* layer); + static WebCore::Position getPositionForOffset(WebCore::Node* node, int offset); + + WebCore::VisiblePosition visiblePositionForContentPoint(int x, int y); + WebCore::VisiblePosition visiblePositionForContentPoint(const WebCore::IntPoint& point); + bool selectWordAroundPosition(WebCore::Frame* frame, + WebCore::VisiblePosition pos); + SelectText* createSelectText(const WebCore::VisibleSelection&); + static int getMaxLength(WebCore::Node* node); + static WTF::String getFieldName(WebCore::Node* node); + static bool isAutoCompleteEnabled(WebCore::Node* node); + WebCore::IntRect absoluteContentRect(WebCore::Node* node, + WebCore::LayerAndroid* layer); + static WebCore::IntRect positionToTextRect(const WebCore::Position& position, + WebCore::EAffinity affinity); // called from constructor, to add this to a global list static void addInstance(WebViewCore*); @@ -751,7 +770,6 @@ namespace android { struct TextFieldInitDataGlue* m_textFieldInitDataGlue; WebCore::Frame* m_mainFrame; WebCoreReply* m_popupReply; - int m_blurringNodePointer; PictureSet m_content; // the set of pictures to draw SkRegion m_addInval; // the accumulated inval region (not yet drawn) SkRegion m_rebuildInval; // the accumulated region for rebuilt pictures @@ -773,7 +791,7 @@ namespace android { int m_screenHeight;// height of the visible rect in document coordinates int m_textWrapWidth; float m_scale; - PageGroup* m_groupForVisitedLinks; + WebCore::PageGroup* m_groupForVisitedLinks; bool m_isPaused; int m_cacheMode; bool m_fullscreenVideoMode; @@ -791,7 +809,7 @@ namespace android { } int m_screenOnCounter; - Node* m_currentNodeDomNavigationAxis; + WebCore::Node* m_currentNodeDomNavigationAxis; DeviceMotionAndOrientationManager m_deviceMotionAndOrientationManager; #if ENABLE(TOUCH_EVENTS) diff --git a/Source/WebKit/android/nav/SelectText.h b/Source/WebKit/android/nav/SelectText.h index 904b2b9..50bc82e 100644 --- a/Source/WebKit/android/nav/SelectText.h +++ b/Source/WebKit/android/nav/SelectText.h @@ -43,6 +43,8 @@ public: IntRect& caretRect(HandleId id) { return m_caretRects[mapId(id)]; } void setCaretRect(HandleId id, const IntRect& rect) { m_caretRects[mapId(id)] = rect; } + IntRect& textRect(HandleId id) { return m_textRects[mapId(id)]; } + void setTextRect(HandleId id, const IntRect& rect) { m_textRects[mapId(id)] = rect; } int caretLayerId(HandleId id) { return m_caretLayerId[mapId(id)]; } void setCaretLayerId(HandleId id, int layerId) { m_caretLayerId[mapId(id)] = layerId; } @@ -56,6 +58,7 @@ private: HandleId mapId(HandleId id); IntRect m_caretRects[2]; + IntRect m_textRects[2]; int m_caretLayerId[2]; bool m_baseIsFirst; String m_text; diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index ddb9bcb..44ad1c5 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -30,8 +30,10 @@ #include "AndroidAnimation.h" #include "AndroidLog.h" #include "BaseLayerAndroid.h" +#include "BaseRenderer.h" #include "DrawExtra.h" #include "Frame.h" +#include "GLWebViewState.h" #include "GraphicsJNI.h" #include "HTMLInputElement.h" #include "IntPoint.h" @@ -51,6 +53,7 @@ #include "SkRect.h" #include "SkTime.h" #include "TilesManager.h" +#include "TransferQueue.h" #include "WebCoreJni.h" #include "WebRequestContext.h" #include "WebViewCore.h" @@ -125,6 +128,10 @@ struct JavaGlue { jfieldID m_rectTop; jmethodID m_rectWidth; jmethodID m_rectHeight; + jfieldID m_quadFP1; + jfieldID m_quadFP2; + jfieldID m_quadFP3; + jfieldID m_quadFP4; AutoJObject object(JNIEnv* env) { return getRealObject(env, m_obj); } @@ -156,6 +163,14 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir, m_javaGlue.m_rectHeight = GetJMethod(env, rectClass, "height", "()I"); env->DeleteLocalRef(rectClass); + 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_generation = 0; @@ -236,13 +251,13 @@ void scrollRectOnScreen(const IntRect& rect) viewInvalidate(); } -bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, +int drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::IntRect& webViewRect, int titleBarHeight, - WebCore::IntRect& clip, float scale, int extras) + WebCore::IntRect& clip, float scale, int extras, bool shouldDraw) { #if USE(ACCELERATED_COMPOSITING) if (!m_baseLayer) - return false; + return 0; if (!m_glWebViewState) { TilesManager::instance()->setHighEndGfx(m_isHighEndGfx); @@ -258,12 +273,12 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, // if the zoom manager is still initializing. We will be redrawn // once the correct scale is set if (!m_visibleRect.isFinite()) - return false; + return 0; bool treesSwapped = false; bool newTreeHasAnim = false; - bool ret = m_glWebViewState->drawGL(viewRect, m_visibleRect, invalRect, + int ret = m_glWebViewState->drawGL(viewRect, m_visibleRect, invalRect, webViewRect, titleBarHeight, clip, scale, - &treesSwapped, &newTreeHasAnim); + &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(); @@ -273,10 +288,9 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, checkException(env); } } - if (ret) - return !m_isDrawingPaused; + return m_isDrawingPaused ? 0 : ret; #endif - return false; + return 0; } PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool split) @@ -292,7 +306,8 @@ PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool spli int sc = canvas->save(SkCanvas::kClip_SaveFlag); canvas->clipRect(SkRect::MakeLTRB(0, 0, content->width(), content->height()), SkRegion::kDifference_Op); - canvas->drawColor(bgColor); + Color c = m_baseLayer->getBackgroundColor(); + canvas->drawColor(SkColorSetARGBInline(c.alpha(), c.red(), c.green(), c.blue())); canvas->restoreToCount(sc); // call this to be sure we've adjusted for any scrolling or animations @@ -578,43 +593,64 @@ void setTextSelection(SelectText *selection) { setDrawExtra(selection, DrawExtrasSelection); } -int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) { +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->updateLayerPositions(m_visibleRect); + 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); - cursorRect = selectText->caretRect(handleId); - if (layerId != -1) { - // We need to make sure the drawTransform is up to date as this is - // called before a draw() or drawGL() - m_baseLayer->updateLayerPositions(m_visibleRect); - LayerAndroid* root = m_baseLayer; - LayerAndroid* layer = root ? root->findById(layerId) : 0; - if (layer && layer->drawTransform()) { - const TransformationMatrix* transform = layer->drawTransform(); - // We're overloading the concept of Rect to be just the two - // points (bottom-left and top-right. - // TODO: Use FloatQuad instead. - IntPoint bottomLeft = transform->mapPoint(IntPoint(cursorRect.fLeft, - cursorRect.fBottom)); - IntPoint topRight = transform->mapPoint(IntPoint(cursorRect.fRight, - cursorRect.fTop)); - cursorRect.setLTRB(bottomLeft.x(), topRight.y(), topRight.x(), - bottomLeft.y()); - } + 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) { - if (layerId != -1) { - // We need to make sure the drawTransform is up to date as this is - // called before a draw() or drawGL() - m_baseLayer->updateLayerPositions(m_visibleRect); - LayerAndroid* layer = m_baseLayer ? m_baseLayer->findById(layerId) : 0; - if (layer && layer->drawTransform()) - rect = layer->drawTransform()->mapRect(rect); - } + const TransformationMatrix* transform = getLayerTransform(layerId); + if (transform) + 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 @@ -656,8 +692,8 @@ 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), + int (WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*, + WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint, bool), WebCore::IntRect _viewRect, float _scale, int _extras) { wvInstance = _wvInstance; funcPtr = _funcPtr; @@ -682,16 +718,15 @@ class GLDrawFunctor : Functor { WebCore::IntRect clip(info->clipLeft, info->clipTop, info->clipRight - info->clipLeft, info->clipBottom - info->clipTop); + bool shouldDraw = (messageId == uirenderer::DrawGlInfo::kModeDraw); TilesManager::instance()->shader()->setWebViewMatrix(info->transform, info->isLayer); - - bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect, - titlebarHeight, clip, scale, extras); - if (retVal) { + int returnFlags = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect, + titlebarHeight, clip, scale, extras, shouldDraw); + if ((returnFlags & uirenderer::DrawGlInfo::kStatusDraw) != 0) { IntRect finalInval; - if (inval.isEmpty()) { + if (inval.isEmpty()) finalInval = webViewRect; - retVal = true; - } else { + else { finalInval.setX(webViewRect.x() + inval.x()); finalInval.setY(webViewRect.y() + titlebarHeight + inval.y()); finalInval.setWidth(inval.width()); @@ -702,8 +737,9 @@ 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 updateRect(WebCore::IntRect& _viewRect) { viewRect = _viewRect; @@ -716,8 +752,8 @@ class GLDrawFunctor : Functor { } private: WebView* wvInstance; - bool (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, - WebCore::IntRect&, int, WebCore::IntRect&, float, int); + int (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, + WebCore::IntRect&, int, WebCore::IntRect&, float, int, bool); WebCore::IntRect viewRect; WebCore::IntRect webViewRect; jfloat scale; @@ -1140,13 +1176,18 @@ static void nativeSetTextSelection(JNIEnv *env, jobject obj, jint nativeView, } static jint nativeGetHandleLayerId(JNIEnv *env, jobject obj, jint nativeView, - jint handleIndex, jobject cursorRect) + jint handleIndex, jobject cursorPoint, + jobject textQuad) { WebView* webview = reinterpret_cast<WebView*>(nativeView); - SkIRect nativeRect; - int layerId = webview->getHandleLayerId((SelectText::HandleId) handleIndex, nativeRect); - if (cursorRect) - GraphicsJNI::irect_to_jrect(nativeRect, env, cursorRect); + 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; } @@ -1247,7 +1288,7 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeSetPauseDrawing }, { "nativeSetTextSelection", "(II)V", (void*) nativeSetTextSelection }, - { "nativeGetHandleLayerId", "(IILandroid/graphics/Rect;)I", + { "nativeGetHandleLayerId", "(IILandroid/graphics/Point;Landroid/webkit/QuadF;)I", (void*) nativeGetHandleLayerId }, { "nativeIsBaseFirst", "(I)Z", (void*) nativeIsBaseFirst }, diff --git a/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp b/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp index 513d251..92dbbcd 100644 --- a/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp +++ b/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp @@ -47,7 +47,7 @@ static struct ANPSurfaceInterfaceJavaGlue { jfieldID surfacePointer; } gSurfaceJavaGlue; -static inline sp<Surface> getSurface(JNIEnv* env, jobject view) { +static inline sp<android::Surface> getSurface(JNIEnv* env, jobject view) { if (!env || !view) { return NULL; } @@ -80,7 +80,7 @@ static inline sp<Surface> getSurface(JNIEnv* env, jobject view) { env->DeleteLocalRef(holder); env->DeleteLocalRef(surface); - return sp<Surface>((Surface*) surfacePointer); + return sp<android::Surface>((android::Surface*) surfacePointer); } static inline ANPBitmapFormat convertPixelFormat(PixelFormat format) { @@ -96,9 +96,9 @@ static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRec return false; } - sp<Surface> surface = getSurface(env, surfaceView); + sp<android::Surface> surface = getSurface(env, surfaceView); - if (!bitmap || !Surface::isValid(surface)) { + if (!bitmap || !android::Surface::isValid(surface)) { return false; } @@ -112,7 +112,7 @@ static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRec dirtyRegion.set(Rect(0x3FFF, 0x3FFF)); } - Surface::SurfaceInfo info; + android::Surface::SurfaceInfo info; status_t err = surface->lock(&info, &dirtyRegion); if (err < 0) { return false; @@ -150,9 +150,9 @@ static void anp_unlock(JNIEnv* env, jobject surfaceView) { return; } - sp<Surface> surface = getSurface(env, surfaceView); + sp<android::Surface> surface = getSurface(env, surfaceView); - if (!Surface::isValid(surface)) { + if (!android::Surface::isValid(surface)) { return; } |