diff options
Diffstat (limited to 'WebKit/android')
-rw-r--r-- | WebKit/android/jni/JavaBridge.cpp | 50 | ||||
-rw-r--r-- | WebKit/android/jni/JavaSharedClient.cpp | 11 | ||||
-rw-r--r-- | WebKit/android/jni/JavaSharedClient.h | 4 | ||||
-rw-r--r-- | WebKit/android/jni/WebSettings.cpp | 31 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 198 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.h | 17 | ||||
-rw-r--r-- | WebKit/android/nav/CacheBuilder.cpp | 8 | ||||
-rw-r--r-- | WebKit/android/nav/CacheBuilder.h | 4 | ||||
-rw-r--r-- | WebKit/android/nav/CachedNode.cpp | 2 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 89 | ||||
-rw-r--r-- | WebKit/android/plugins/ANPTypefaceInterface.cpp | 27 | ||||
-rw-r--r-- | WebKit/android/plugins/PluginWidgetAndroid.cpp | 25 | ||||
-rw-r--r-- | WebKit/android/plugins/PluginWidgetAndroid.h | 17 | ||||
-rw-r--r-- | WebKit/android/plugins/android_npapi.h | 67 |
14 files changed, 380 insertions, 170 deletions
diff --git a/WebKit/android/jni/JavaBridge.cpp b/WebKit/android/jni/JavaBridge.cpp index 98d7c43..7c4636f 100644 --- a/WebKit/android/jni/JavaBridge.cpp +++ b/WebKit/android/jni/JavaBridge.cpp @@ -31,6 +31,7 @@ #include "Cache.h" #include "CookieClient.h" #include "JavaSharedClient.h" +#include "KeyGeneratorClient.h" #include "KURL.h" #include "NetworkStateNotifier.h" #include "Page.h" @@ -58,7 +59,7 @@ static jfieldID gJavaBridge_ObjectID; // ---------------------------------------------------------------------------- -class JavaBridge : public TimerClient, public CookieClient, public PluginClient +class JavaBridge : public TimerClient, public CookieClient, public PluginClient, public KeyGeneratorClient { public: JavaBridge(JNIEnv* env, jobject obj); @@ -76,6 +77,10 @@ public: virtual WTF::Vector<WebCore::String> getPluginDirectories(); + virtual WTF::Vector<String> getSupportedKeyStrengthList(); + virtual WebCore::String getSignedPublicKeyAndChallengeString(unsigned index, + const WebCore::String& challenge, const WebCore::KURL& url); + //////////////////////////////////////////// virtual void setSharedTimerCallback(void (*f)()); @@ -103,6 +108,8 @@ private: jmethodID mCookiesEnabled; jmethodID mGetPluginDirectories; jmethodID mSignalFuncPtrQueue; + jmethodID mGetKeyStrengthList; + jmethodID mGetSignedPublicKey; }; static void (*sSharedTimerFiredCallback)(); @@ -119,16 +126,21 @@ JavaBridge::JavaBridge(JNIEnv* env, jobject obj) mCookiesEnabled = env->GetMethodID(clazz, "cookiesEnabled", "()Z"); mGetPluginDirectories = env->GetMethodID(clazz, "getPluginDirectories", "()[Ljava/lang/String;"); mSignalFuncPtrQueue = env->GetMethodID(clazz, "signalServiceFuncPtrQueue", "()V"); + mGetKeyStrengthList = env->GetMethodID(clazz, "getKeyStrengthList", "()[Ljava/lang/String;"); + mGetSignedPublicKey = env->GetMethodID(clazz, "getSignedPublicKey", "(ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); LOG_ASSERT(mSetSharedTimer, "Could not find method setSharedTimer"); LOG_ASSERT(mStopSharedTimer, "Could not find method stopSharedTimer"); LOG_ASSERT(mSetCookies, "Could not find method setCookies"); LOG_ASSERT(mCookies, "Could not find method cookies"); LOG_ASSERT(mCookiesEnabled, "Could not find method cookiesEnabled"); + LOG_ASSERT(mGetKeyStrengthList, "Could not find method getKeyStrengthList"); + LOG_ASSERT(mGetSignedPublicKey, "Could not find method getSignedPublicKey"); JavaSharedClient::SetTimerClient(this); JavaSharedClient::SetCookieClient(this); JavaSharedClient::SetPluginClient(this); + JavaSharedClient::SetKeyGeneratorClient(this); } JavaBridge::~JavaBridge() @@ -141,6 +153,8 @@ JavaBridge::~JavaBridge() JavaSharedClient::SetTimerClient(NULL); JavaSharedClient::SetCookieClient(NULL); + JavaSharedClient::SetPluginClient(NULL); + JavaSharedClient::SetKeyGeneratorClient(NULL); } void @@ -236,6 +250,40 @@ void JavaBridge::signalServiceFuncPtrQueue() env->CallVoidMethod(obj.get(), mSignalFuncPtrQueue); } +WTF::Vector<WebCore::String>JavaBridge::getSupportedKeyStrengthList() { + WTF::Vector<WebCore::String> list; + JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = getRealObject(env, mJavaObject); + jobjectArray array = (jobjectArray) env->CallObjectMethod(obj.get(), + mGetKeyStrengthList); + int count = env->GetArrayLength(array); + for (int i = 0; i < count; ++i) { + jstring keyStrength = (jstring) env->GetObjectArrayElement(array, i); + list.append(to_string(env, keyStrength)); + env->DeleteLocalRef(keyStrength); + } + env->DeleteLocalRef(array); + checkException(env); + return list; +} + +WebCore::String JavaBridge::getSignedPublicKeyAndChallengeString(unsigned index, + const WebCore::String& challenge, const WebCore::KURL& url) { + JNIEnv* env = JSC::Bindings::getJNIEnv(); + jstring jChallenge = env->NewString(challenge.characters(), + challenge.length()); + const WebCore::String& urlStr = url.string(); + jstring jUrl = env->NewString(urlStr.characters(), urlStr.length()); + AutoJObject obj = getRealObject(env, mJavaObject); + jstring key = (jstring) env->CallObjectMethod(obj.get(), + mGetSignedPublicKey, index, jChallenge, jUrl); + WebCore::String ret = to_string(env, key); + env->DeleteLocalRef(jChallenge); + env->DeleteLocalRef(jUrl); + env->DeleteLocalRef(key); + return ret; +} + // ---------------------------------------------------------------------------- void JavaBridge::Constructor(JNIEnv* env, jobject obj) diff --git a/WebKit/android/jni/JavaSharedClient.cpp b/WebKit/android/jni/JavaSharedClient.cpp index 3ddf726..2eec7b9 100644 --- a/WebKit/android/jni/JavaSharedClient.cpp +++ b/WebKit/android/jni/JavaSharedClient.cpp @@ -45,6 +45,11 @@ namespace android { return gPluginClient; } + KeyGeneratorClient* JavaSharedClient::GetKeyGeneratorClient() + { + return gKeyGeneratorClient; + } + void JavaSharedClient::SetTimerClient(TimerClient* client) { gTimerClient = client; @@ -60,9 +65,15 @@ namespace android { gPluginClient = client; } + void JavaSharedClient::SetKeyGeneratorClient(KeyGeneratorClient* client) + { + gKeyGeneratorClient = client; + } + TimerClient* JavaSharedClient::gTimerClient = NULL; CookieClient* JavaSharedClient::gCookieClient = NULL; PluginClient* JavaSharedClient::gPluginClient = NULL; + KeyGeneratorClient* JavaSharedClient::gKeyGeneratorClient = NULL; /////////////////////////////////////////////////////////////////////////// diff --git a/WebKit/android/jni/JavaSharedClient.h b/WebKit/android/jni/JavaSharedClient.h index 69c05ce..bf59969 100644 --- a/WebKit/android/jni/JavaSharedClient.h +++ b/WebKit/android/jni/JavaSharedClient.h @@ -31,6 +31,7 @@ namespace android { class TimerClient; class CookieClient; class PluginClient; + class KeyGeneratorClient; class JavaSharedClient { @@ -38,10 +39,12 @@ namespace android { static TimerClient* GetTimerClient(); static CookieClient* GetCookieClient(); static PluginClient* GetPluginClient(); + static KeyGeneratorClient* GetKeyGeneratorClient(); static void SetTimerClient(TimerClient* client); static void SetCookieClient(CookieClient* client); static void SetPluginClient(PluginClient* client); + static void SetKeyGeneratorClient(KeyGeneratorClient* client); // can be called from any thread, to be executed in webkit thread static void EnqueueFunctionPtr(void (*proc)(void*), void* payload); @@ -52,6 +55,7 @@ namespace android { static TimerClient* gTimerClient; static CookieClient* gCookieClient; static PluginClient* gPluginClient; + static KeyGeneratorClient* gKeyGeneratorClient; }; } #endif diff --git a/WebKit/android/jni/WebSettings.cpp b/WebKit/android/jni/WebSettings.cpp index 110cde0..7d2b12d 100644 --- a/WebKit/android/jni/WebSettings.cpp +++ b/WebKit/android/jni/WebSettings.cpp @@ -28,17 +28,13 @@ #include <config.h> #include <wtf/Platform.h> -#if ENABLE(DATABASE) -#include "DatabaseTracker.h" -#endif -#if ENABLE(OFFLINE_WEB_APPLICATIONS) #include "ApplicationCacheStorage.h" -#endif +#include "DatabaseTracker.h" +#include "DocLoader.h" #include "Document.h" #include "Frame.h" #include "FrameLoader.h" #include "FrameView.h" -#include "DocLoader.h" #include "Page.h" #include "RenderTable.h" #include "Settings.h" @@ -84,6 +80,13 @@ struct FieldIds { mPluginsEnabled = env->GetFieldID(clazz, "mPluginsEnabled", "Z"); #if ENABLE(DATABASE) mDatabaseEnabled = env->GetFieldID(clazz, "mDatabaseEnabled", "Z"); +#endif +#if ENABLE(DOM_STORAGE) + mDomStorageEnabled = env->GetFieldID(clazz, "mDomStorageEnabled", "Z"); +#endif +#if ENABLE(DATABASE) || ENABLE(DOM_STORAGE) + // The databases saved to disk for both the SQL and DOM Storage APIs are stored + // in the same base directory. mDatabasePath = env->GetFieldID(clazz, "mDatabasePath", "Ljava/lang/String;"); #endif #if ENABLE(OFFLINE_WEB_APPLICATIONS) @@ -173,6 +176,11 @@ struct FieldIds { #if ENABLE(DATABASE) jfieldID mDatabaseEnabled; +#endif +#if ENABLE(DOM_STORAGE) + jfieldID mDomStorageEnabled; +#endif +#if ENABLE(DATABASE) || ENABLE(DOM_STORAGE) jfieldID mDatabasePath; #endif }; @@ -312,6 +320,17 @@ public: str = (jstring)env->GetObjectField(obj, gFieldIds->mDatabasePath); WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(to_string(env, str)); #endif +#if ENABLE(DOM_STORAGE) + flag = env->GetBooleanField(obj, gFieldIds->mDomStorageEnabled); + s->setLocalStorageEnabled(flag); + str = (jstring)env->GetObjectField(obj, gFieldIds->mDatabasePath); + if (str) { + WebCore::String localStorageDatabasePath = to_string(env,str); + if (localStorageDatabasePath.length()) { + s->setLocalStorageDatabasePath(localStorageDatabasePath); + } + } +#endif } }; diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index 0d5a3dd..ebe5d23 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -288,12 +288,12 @@ void WebViewCore::reset(bool fromConstructor) m_updatedFrameCache = true; m_frameCacheOutOfDate = true; m_snapAnchorNode = 0; - m_useReplay = false; m_skipContentDraw = false; m_findIsUp = false; m_domtree_version = 0; m_check_domtree_version = true; m_progressDone = false; + m_hasCursorBounds = false; } static bool layoutIfNeededRecursive(WebCore::Frame* f) @@ -489,12 +489,15 @@ void WebViewCore::recordPictureSet(PictureSet* content) bool update = m_lastFocused != oldFocusNode || m_lastFocusedBounds != oldBounds || m_findIsUp || (m_check_domtree_version && latestVersion != m_domtree_version); - if (!update && m_hasCursorBounds) { // avoid mutex when possible - bool hasCursorBounds; - void* cursorNode; + if (!update) { // avoid mutex when possible + // This block is specifically for the floating bar in gmail messages + // it has been disabled because it adversely affects the performance + // of loading all pages. + if (true || !m_hasCursorBounds) + return; gCursorBoundsMutex.lock(); - hasCursorBounds = m_hasCursorBounds; - cursorNode = m_cursorNode; + bool hasCursorBounds = m_hasCursorBounds; + void* cursorNode = m_cursorNode; IntRect bounds = m_cursorBounds; gCursorBoundsMutex.unlock(); if (hasCursorBounds && cursorNode) { @@ -502,10 +505,10 @@ void WebViewCore::recordPictureSet(PictureSet* content) bounds.y() + (bounds.height() >> 1)); HitTestResult hitTestResult = m_mainFrame->eventHandler()-> hitTestResultAtPoint(center, false); - if (m_cursorNode == hitTestResult.innerNode()) - return; // don't update DBG_NAV_LOGD("at (%d,%d) old=%p new=%p", center.x(), center.y(), - m_cursorNode, hitTestResult.innerNode()); + cursorNode, hitTestResult.innerNode()); + if (cursorNode == hitTestResult.innerNode()) + return; // don't update } } m_lastFocused = oldFocusNode; @@ -858,9 +861,10 @@ void WebViewCore::doMaxScroll(CacheBuilder::Direction dir) this->scrollBy(dx, dy, true); } -void WebViewCore::setScrollOffset(int dx, int dy) +void WebViewCore::setScrollOffset(int moveGeneration, int dx, int dy) { - DBG_NAV_LOGD("{%d,%d}", dx, dy); + DBG_NAV_LOGD("{%d,%d} m_scrollOffset=(%d,%d)", dx, dy, + m_scrollOffsetX, m_scrollOffsetY); if (m_scrollOffsetX != dx || m_scrollOffsetY != dy) { m_scrollOffsetX = dx; m_scrollOffsetY = dy; @@ -871,6 +875,14 @@ void WebViewCore::setScrollOffset(int dx, int dy) m_scrollOffsetY); m_mainFrame->eventHandler()->sendScrollEvent(); } + gCursorBoundsMutex.lock(); + bool hasCursorBounds = m_hasCursorBounds; + Frame* frame = (Frame*) m_cursorFrame; + IntPoint location = m_cursorLocation; + gCursorBoundsMutex.unlock(); + if (!hasCursorBounds) + return; + moveMouseIfLatest(moveGeneration, frame, location.x(), location.y()); } void WebViewCore::setGlobalBounds(int x, int y, int h, int v) @@ -993,11 +1005,11 @@ WebCore::String WebViewCore::retrieveHref(WebCore::Frame* frame, WebCore::Node* return anchor->href(); } -bool WebViewCore::prepareFrameCache() +void WebViewCore::updateFrameCache() { if (!m_frameCacheOutOfDate) { DBG_NAV_LOG("!m_frameCacheOutOfDate"); - return false; + return; } #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreBuildNavTimeCounter); @@ -1026,61 +1038,9 @@ bool WebViewCore::prepareFrameCache() recordPicture(m_tempPict); m_temp->setPicture(m_tempPict); m_temp->setTextGeneration(m_textGeneration); -// if (m_temp->currentFocus()) -// return true; WebCoreViewBridge* window = m_mainFrame->view()->platformWidget(); m_temp->setVisibleRect(WebCore::IntRect(m_scrollOffsetX, m_scrollOffsetY, window->width(), window->height())); - bool hasCursorBounds; - gCursorBoundsMutex.lock(); - hasCursorBounds = m_hasCursorBounds; - IntRect bounds = m_cursorBounds; - gCursorBoundsMutex.unlock(); - if (!hasCursorBounds) - return true; - int x, y; - const CachedFrame* frame; - const CachedNode* node = m_temp->findAt(bounds, &frame, &x, &y, false); - if (!node) - return true; - // 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(); - 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 true; - if (abs(oldCenter.y() - newCenter.y()) > 2) - return true; - if (abs(bounds.x() - newBounds.x()) > 4) - return true; - if (abs(bounds.y() - newBounds.y()) > 4) - return true; - if (abs(bounds.right() - newBounds.right()) > 4) - return true; - if (abs(bounds.bottom() - newBounds.bottom()) > 4) - return true; - 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_temp->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); - return true; -} - -void WebViewCore::releaseFrameCache(bool newCache) -{ - if (!newCache) { - DBG_NAV_LOG("!newCache"); - return; - } gFrameCacheMutex.lock(); delete m_frameCacheKit; delete m_navPictureKit; @@ -1088,25 +1048,12 @@ void WebViewCore::releaseFrameCache(bool newCache) m_navPictureKit = m_tempPict; m_updatedFrameCache = true; #if DEBUG_NAV_UI - const CachedNode* cachedCursorNode = m_frameCacheKit->currentCursor(); const CachedNode* cachedFocusNode = m_frameCacheKit->currentFocus(); - DBG_NAV_LOGD("cachedCursor=%d (%p) cachedFocusNode=%d (nodePointer=%p)", - cachedCursorNode ? cachedCursorNode->index() : 0, - cachedCursorNode ? cachedCursorNode->nodePointer() : 0, + DBG_NAV_LOGD("cachedFocusNode=%d (nodePointer=%p)", cachedFocusNode ? cachedFocusNode->index() : 0, cachedFocusNode ? cachedFocusNode->nodePointer() : 0); #endif gFrameCacheMutex.unlock(); - // it's tempting to send an invalidate here, but it's a bad idea - // the cache is now up to date, but the focus is not -- the event - // may need to be recomputed from the prior history. An invalidate - // will draw the stale location causing the ring to flash at the wrong place. -} - -void WebViewCore::updateFrameCache() -{ - m_useReplay = false; - releaseFrameCache(prepareFrameCache()); } /////////////////////////////////////////////////////////////////////////////// @@ -1173,30 +1120,18 @@ void WebViewCore::sendPluginEvent(const ANPEvent& evt) /////////////////////////////////////////////////////////////////////////////// void WebViewCore::moveMouseIfLatest(int moveGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus) + WebCore::Frame* frame, int x, int y) { DBG_NAV_LOGD("m_moveGeneration=%d moveGeneration=%d" - " frame=%p node=%p x=%d y=%d", - m_moveGeneration, moveGeneration, frame, node, x, y); - if (m_moveGeneration > moveGeneration) { - DBG_NAV_LOGD("m_moveGeneration=%d > moveGeneration=%d", - m_moveGeneration, moveGeneration); - return; // short-circuit if a newer move has already been generated - } - m_useReplay = true; - bool newCache = prepareFrameCache(); // must wait for possible recompute before using + " frame=%p x=%d y=%d", + m_moveGeneration, moveGeneration, frame, x, y); if (m_moveGeneration > moveGeneration) { DBG_NAV_LOGD("m_moveGeneration=%d > moveGeneration=%d", m_moveGeneration, moveGeneration); - releaseFrameCache(newCache); return; // short-circuit if a newer move has already been generated } - releaseFrameCache(newCache); m_lastGeneration = moveGeneration; - if (!node && ignoreNullFocus) - return; - moveMouse(frame, node, x, y); + moveMouse(frame, x, y); } static bool nodeIsPlugin(Node* node) { @@ -1209,10 +1144,10 @@ static bool nodeIsPlugin(Node* node) { } // Update mouse position and may change focused node. -bool WebViewCore::moveMouse(WebCore::Frame* frame, WebCore::Node* node, - int x, int y) +void WebViewCore::moveMouse(WebCore::Frame* frame, int x, int y) { - DBG_NAV_LOGD("frame=%p node=%p x=%d y=%d ", frame, node, x, y); + DBG_NAV_LOGD("frame=%p x=%d y=%d scrollOffset=(%d,%d)", frame, + x, y, m_scrollOffsetX, m_scrollOffsetY); if (!frame || CacheBuilder::validNode(m_mainFrame, frame, NULL) == false) frame = m_mainFrame; // mouse event expects the position in the window coordinate @@ -1223,16 +1158,6 @@ bool WebViewCore::moveMouse(WebCore::Frame* frame, WebCore::Node* node, WebCore::NoButton, WebCore::MouseEventMoved, 1, false, false, false, false, WTF::currentTime()); frame->eventHandler()->handleMouseMoveEvent(mouseEvent); - bool valid = CacheBuilder::validNode(m_mainFrame, frame, node); - if (!node || !valid) { - DBG_NAV_LOGD("exit: node=%p valid=%s", node, valid ? "true" : "false"); - return false; - } - - // hack to give the plugin focus (for keys). better fix on the way - if (nodeIsPlugin(node)) - node->document()->setFocusedNode(node); - return true; } static int findTextBoxIndex(WebCore::Node* node, const WebCore::IntPoint& pt) @@ -1432,6 +1357,7 @@ void WebViewCore::replaceTextfieldText(int oldStart, WebCore::TypingCommand::insertText(focus->document(), replace, false); setSelection(start, end); + setFocusControllerActive(true); } void WebViewCore::passToJs( @@ -1460,6 +1386,7 @@ void WebViewCore::passToJs( WebCore::RenderObject* renderer = focus->renderer(); if (!renderer || (!renderer->isTextField() && !renderer->isTextArea())) return; + setFocusControllerActive(true); WebCore::RenderTextControl* renderText = static_cast<WebCore::RenderTextControl*>(renderer); WebCore::String test = renderText->text(); @@ -1669,6 +1596,7 @@ bool WebViewCore::key(int keyCode, UChar32 unichar, int repeatCount, bool isShif return eventHandler->keyEvent(evt); } +// For when the user clicks the trackball bool WebViewCore::click() { bool keyHandled = false; WebCore::IntPoint pt = m_mousePos; @@ -1677,9 +1605,7 @@ bool WebViewCore::click() { hitTestResultAtPoint(pt, false); WebCore::Node* focusNode = hitTestResult.innerNode(); if (focusNode) { - WebFrame::getWebFrame(m_mainFrame)->setUserInitiatedClick(true); keyHandled = handleMouseClick(focusNode->document()->frame(), focusNode); - WebFrame::getWebFrame(m_mainFrame)->setUserInitiatedClick(false); } return keyHandled; } @@ -1720,7 +1646,7 @@ void WebViewCore::touchUp(int touchGeneration, " x=%d y=%d", m_touchGeneration, touchGeneration, x, y); return; // short circuit if a newer touch has been generated } - moveMouse(frame, node, x, y); + moveMouse(frame, x, y); m_lastGeneration = touchGeneration; if (frame && CacheBuilder::validNode(m_mainFrame, frame, 0)) { frame->loader()->resetMultipleFormSubmissionProtection(); @@ -1733,6 +1659,7 @@ void WebViewCore::touchUp(int touchGeneration, client->setFromClick(false); } +// Common code for both clicking with the trackball and touchUp bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr) { bool valid = framePtr == NULL @@ -1790,6 +1717,15 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node WTF::currentTime()); bool handled = framePtr->eventHandler()->handleMouseReleaseEvent(mouseUp); webFrame->setUserInitiatedClick(false); + + // If the user clicked on a textfield, make the focusController active + // so we show the blinking cursor. + WebCore::Node* focusNode = currentFocus(); + if (focusNode) { + WebCore::RenderObject* renderer = focusNode->renderer(); + if (renderer && (renderer->isTextField() || renderer->isTextArea())) + setFocusControllerActive(true); + } return handled; } @@ -2008,7 +1944,7 @@ static void SetSize(JNIEnv *env, jobject obj, jint width, jint height, realScreenWidth, screenHeight); } -static void SetScrollOffset(JNIEnv *env, jobject obj, jint dx, jint dy) +static void SetScrollOffset(JNIEnv *env, jobject obj, jint gen, jint x, jint y) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); @@ -2016,7 +1952,7 @@ static void SetScrollOffset(JNIEnv *env, jobject obj, jint dx, jint dy) WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(viewImpl, "need viewImpl"); - viewImpl->setScrollOffset(dx, dy); + viewImpl->setScrollOffset(gen, x, y); } static void SetGlobalBounds(JNIEnv *env, jobject obj, jint x, jint y, jint h, @@ -2100,15 +2036,15 @@ static void PassToJs(JNIEnv *env, jobject obj, generation, current, keyCode, keyValue, down, cap, fn, sym); } -static void SetFocusControllerActive(JNIEnv *env, jobject obj, jboolean active) +static void SetFocusControllerInactive(JNIEnv *env, jobject obj) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); #endif - LOGV("webviewcore::nativeSetFocusControllerActive()\n"); + LOGV("webviewcore::nativeSetFocusControllerInactive()\n"); WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSetFocusControllerActive"); - viewImpl->setFocusControllerActive(active); + LOG_ASSERT(viewImpl, "viewImpl not set in nativeSetFocusControllerInactive"); + viewImpl->setFocusControllerActive(false); } static void SaveDocumentState(JNIEnv *env, jobject obj, jint frame) @@ -2181,7 +2117,8 @@ static void SendListBoxChoices(JNIEnv* env, jobject obj, jbooleanArray jArray, viewImpl->popupReply(array, count); } -static jstring FindAddress(JNIEnv *env, jobject obj, jstring addr) +static jstring FindAddress(JNIEnv *env, jobject obj, jstring addr, + jboolean caseInsensitive) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); @@ -2194,7 +2131,7 @@ static jstring FindAddress(JNIEnv *env, jobject obj, jstring addr) const jchar* addrChars = env->GetStringChars(addr, 0); int start, end; bool success = CacheBuilder::FindAddress(addrChars, length, - &start, &end) == CacheBuilder::FOUND_COMPLETE; + &start, &end, caseInsensitive) == CacheBuilder::FOUND_COMPLETE; jstring ret = 0; if (success) { ret = env->NewString((jchar*) addrChars + start, end - start); @@ -2241,7 +2178,7 @@ static jstring RetrieveHref(JNIEnv *env, jobject obj, jint frame, return 0; } -static void MoveMouse(JNIEnv *env, jobject obj, jint frame, jint node, +static void MoveMouse(JNIEnv *env, jobject obj, jint frame, jint x, jint y) { #ifdef ANDROID_INSTRUMENT @@ -2249,13 +2186,11 @@ static void MoveMouse(JNIEnv *env, jobject obj, jint frame, jint node, #endif WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->moveMouse((WebCore::Frame*) frame, (WebCore::Node*) node, x, - y); + viewImpl->moveMouse((WebCore::Frame*) frame, x, y); } static void MoveMouseIfLatest(JNIEnv *env, jobject obj, jint moveGeneration, - jint frame, jint node, jint x, jint y, - jboolean ignoreNullFocus) + jint frame, jint x, jint y) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); @@ -2263,8 +2198,7 @@ static void MoveMouseIfLatest(JNIEnv *env, jobject obj, jint moveGeneration, WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); viewImpl->moveMouseIfLatest(moveGeneration, - (WebCore::Frame*) frame, (WebCore::Node*) node, x, y, - ignoreNullFocus); + (WebCore::Frame*) frame, x, y); } static void UpdateFrameCache(JNIEnv *env, jobject obj) @@ -2494,7 +2428,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) SendListBoxChoice }, { "nativeSetSize", "(IIIFII)V", (void*) SetSize }, - { "nativeSetScrollOffset", "(II)V", + { "nativeSetScrollOffset", "(III)V", (void*) SetScrollOffset }, { "nativeSetGlobalBounds", "(IIII)V", (void*) SetGlobalBounds }, @@ -2504,17 +2438,17 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) DeleteSelection } , { "nativeReplaceTextfieldText", "(IILjava/lang/String;II)V", (void*) ReplaceTextfieldText } , - { "nativeMoveMouse", "(IIII)V", + { "nativeMoveMouse", "(III)V", (void*) MoveMouse }, - { "nativeMoveMouseIfLatest", "(IIIIIZ)V", + { "nativeMoveMouseIfLatest", "(IIII)V", (void*) MoveMouseIfLatest }, { "passToJs", "(ILjava/lang/String;IIZZZZ)V", (void*) PassToJs } , - { "nativeSetFocusControllerActive", "(Z)V", - (void*) SetFocusControllerActive }, + { "nativeSetFocusControllerInactive", "()V", + (void*) SetFocusControllerInactive }, { "nativeSaveDocumentState", "(I)V", (void*) SaveDocumentState }, - { "nativeFindAddress", "(Ljava/lang/String;)Ljava/lang/String;", + { "nativeFindAddress", "(Ljava/lang/String;Z)Ljava/lang/String;", (void*) FindAddress }, { "nativeHandleTouchEvent", "(III)Z", (void*) HandleTouchEvent }, diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index 7231941..4ba0074 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -195,14 +195,12 @@ namespace android { // Create a set of pictures to represent the drawn DOM, driven by // the invalidated region and the time required to draw (used to draw) void recordPictureSet(PictureSet* master); - bool moveMouse(WebCore::Frame* frame, WebCore::Node* node, - int x, int y); + void moveMouse(WebCore::Frame* frame, int x, int y); void moveMouseIfLatest(int moveGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus); + WebCore::Frame* frame, int x, int y); // set the scroll amount that webview.java is currently showing - void setScrollOffset(int dx, int dy); + void setScrollOffset(int moveGeneration, int dx, int dy); void setGlobalBounds(int x, int y, int h, int v); @@ -327,10 +325,11 @@ namespace android { int m_touchGeneration; // copy of state in WebViewNative triggered by touch int m_lastGeneration; // last action using up to date cache bool m_updatedFrameCache; - bool m_useReplay; bool m_findIsUp; bool m_hasCursorBounds; WebCore::IntRect m_cursorBounds; + void* m_cursorFrame; + IntPoint m_cursorLocation; void* m_cursorNode; static Mutex gCursorBoundsMutex; // These two fields go together: we use the mutex to protect access to @@ -396,17 +395,11 @@ namespace android { this->drawPlugins(); } - WebCore::Frame* changedKitFocus(WebCore::Frame* frame, - WebCore::Node* node, int x, int y); void doMaxScroll(CacheBuilder::Direction dir); SkPicture* rebuildPicture(const SkIRect& inval); void rebuildPictureSet(PictureSet* ); - void sendMarkNodeInvalid(WebCore::Node* ); void sendNotifyProgressFinished(); - void sendRecomputeFocus(); bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr); - bool prepareFrameCache(); - void releaseFrameCache(bool newCache); #if DEBUG_NAV_UI uint32_t m_now; #endif diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp index d8d8076..475d2b7 100644 --- a/WebKit/android/nav/CacheBuilder.cpp +++ b/WebKit/android/nav/CacheBuilder.cpp @@ -1457,11 +1457,13 @@ static bool validZip(int stateIndex, const UChar* zipPtr) #define MAX_PLACE_NAME_LENGTH 25 // the longest allowable one word place name -CacheBuilder::FoundState CacheBuilder::FindAddress(const UChar* chars, unsigned length, int* start, int* end) +CacheBuilder::FoundState CacheBuilder::FindAddress(const UChar* chars, + unsigned length, int* start, int* end, bool caseInsensitive) { FindState addressState; FindReset(&addressState); addressState.mWords[0] = addressState.mStarts[0] = chars; + addressState.mCaseInsensitive = caseInsensitive; FoundState state = FindPartialAddress(chars, chars, length, &addressState); if (state == FOUND_PARTIAL && addressState.mProgress == ZIP_CODE && addressState.mNumberCount == 0) { @@ -1682,6 +1684,8 @@ CacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars } else if (s->mLetterCount >= MAX_PLACE_NAME_LENGTH) { break; } else if (s->mFirstLower != NULL) { + if (s->mCaseInsensitive) + goto resetWord; size_t length = chars - s->mFirstLower; if (length > 3) break; @@ -2884,7 +2888,7 @@ bool CacheBuilder::ConstructTextRects(Text* node, int start, if ((int) textBox->end() >= start) break; } while ((textBox = textBox->nextTextBox()) != NULL); - if (ConstructTextRect(node, textBox, start, relEnd, + if (textBox && ConstructTextRect(node, textBox, start, relEnd, x, y, focusBounds, clipBounds, result) == false) return false; } diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h index 3990cab..35bd623 100644 --- a/WebKit/android/nav/CacheBuilder.h +++ b/WebKit/android/nav/CacheBuilder.h @@ -88,7 +88,8 @@ public: mAllowableTypes & ~EMAIL_CACHEDNODETYPE); } void disallowPhoneDetection() { mAllowableTypes = (CachedNodeType) ( mAllowableTypes & ~PHONE_CACHEDNODETYPE); } - static FoundState FindAddress(const UChar* , unsigned length, int* start, int* end); + static FoundState FindAddress(const UChar* , unsigned length, int* start, + int* end, bool caseInsensitive); static void GetGlobalOffset(Frame* , int* x, int * y); static void GetGlobalOffset(Node* , int* x, int * y); static bool validNode(Frame* startFrame, void* framePtr, void* nodePtr); @@ -163,6 +164,7 @@ private: bool mOpenParen; bool mInitialized; bool mContinuationNode; + bool mCaseInsensitive; }; struct ClipColumnTracker { IntRect mBounds; diff --git a/WebKit/android/nav/CachedNode.cpp b/WebKit/android/nav/CachedNode.cpp index e7cab9e..cab1f15 100644 --- a/WebKit/android/nav/CachedNode.cpp +++ b/WebKit/android/nav/CachedNode.cpp @@ -211,7 +211,7 @@ void CachedNode::hideCursor(CachedFrame* parent) CachedFrame* child = const_cast<CachedFrame*>(parent->hasFrame(this)); child->hideCursor(); } - mIsHidden = false; + mIsHidden = true; } void CachedNode::init(WebCore::Node* node) diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 22b07bc..116cfdd 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -128,7 +128,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) m_javaGlue.m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V"); m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V"); m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V"); - m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "()V"); + m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "(Z)V"); m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIIII)V"); m_javaGlue.m_getScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I"); m_javaGlue.m_getScaledMaxYScroll = GetJMethod(env, clazz, "getScaledMaxYScroll", "()I"); @@ -536,6 +536,50 @@ void cursorRingBounds(WebCore::IntRect* bounds) *bounds = WebCore::IntRect(0, 0, 0, 0); } +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, false); + 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(); + 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.right() - newBounds.right()) > 4) + return; + if (abs(bounds.bottom() - newBounds.bottom()) > 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)); +} + CachedRoot* getFrameCache(FrameCachePermission allowNewer) { if (!m_viewImpl->m_updatedFrameCache) { @@ -558,6 +602,7 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer) m_viewImpl->m_frameCacheKit = 0; m_viewImpl->m_navPictureKit = 0; m_viewImpl->gFrameCacheMutex.unlock(); + fixCursor(); if (hadCursor && (!m_frameCacheUI || !m_frameCacheUI->currentCursor())) viewInvalidate(); // redraw in case cursor ring is still visible return m_frameCacheUI; @@ -680,8 +725,10 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll) } if (cachedNode) { m_viewImpl->gCursorBoundsMutex.lock(); - m_viewImpl->m_hasCursorBounds = true; + m_viewImpl->m_hasCursorBounds = cachedNode->hasCursorRing(); m_viewImpl->m_cursorBounds = cachedNode->bounds(); + m_viewImpl->m_cursorFrame = cachedFrame->framePointer(); + root->getSimulatedMousePosition(&m_viewImpl->m_cursorLocation); m_viewImpl->m_cursorNode = cachedNode->nodePointer(); m_viewImpl->gCursorBoundsMutex.unlock(); } @@ -710,8 +757,11 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll) } bool result = false; if (cachedNode) { - root->setCursor((CachedFrame*) cachedFrame, (CachedNode*) cachedNode); - sendMoveMouseIfLatest(); + root->setCursor(const_cast<CachedFrame*>(cachedFrame), + const_cast<CachedNode*>(cachedNode)); + bool disableFocusController = cachedNode != root->currentFocus() + && cachedNode->wantsKeyEvents(); + sendMoveMouseIfLatest(disableFocusController); viewInvalidate(); } else { int docHeight = root->documentHeight(); @@ -763,18 +813,23 @@ void selectBestAt(const WebCore::IntRect& rect) { const CachedFrame* frame; int rx, ry; + bool disableFocusController = false; CachedRoot* root = getFrameCache(DontAllowNewer); const CachedNode* node = findAt(root, rect, &frame, &rx, &ry); if (!node) { DBG_NAV_LOGD("no nodes found root=%p", root); + disableFocusController = true; if (root) root->setCursor(0, 0); } else { DBG_NAV_LOGD("CachedNode:%p (%d)", node, node->index()); root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); + const_cast<CachedNode*>(node)); + if (!node->wantsKeyEvents()) { + disableFocusController = true; + } } - sendMoveMouseIfLatest(); + sendMoveMouseIfLatest(disableFocusController); viewInvalidate(); } @@ -1014,12 +1069,12 @@ void sendMoveMouse(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int checkException(env); } -void sendMoveMouseIfLatest() +void sendMoveMouseIfLatest(bool disableFocusController) { LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_sendMoveMouseIfLatest); + m_javaGlue.m_sendMoveMouseIfLatest, disableFocusController); checkException(env); } @@ -1291,6 +1346,19 @@ static jint nativeCursorNodePointer(JNIEnv *env, jobject obj) return reinterpret_cast<int>(node ? node->nodePointer() : 0); } +static jobject nativeCursorPosition(JNIEnv *env, jobject obj) +{ + WebView* view = GET_NATIVE_VIEW(env, obj); + 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()); + return point; +} + static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj) { int L, T, R, B; @@ -1681,6 +1749,9 @@ static void nativeDestroy(JNIEnv *env, jobject obj) static int nativeMoveGeneration(JNIEnv *env, jobject obj) { + WebView* view = GET_NATIVE_VIEW(env, obj); + if (!view) + return 0; return GET_NATIVE_VIEW(env, obj)->moveGeneration(); } @@ -1757,6 +1828,8 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeCursorIsAnchor }, { "nativeCursorIsTextInput", "()Z", (void*) nativeCursorIsTextInput }, + { "nativeCursorPosition", "()Landroid/graphics/Point;", + (void*) nativeCursorPosition }, { "nativeCursorText", "()Ljava/lang/String;", (void*) nativeCursorText }, { "nativeCursorWantsKeyEvents", "()Z", diff --git a/WebKit/android/plugins/ANPTypefaceInterface.cpp b/WebKit/android/plugins/ANPTypefaceInterface.cpp index 17b3067..f4823d6 100644 --- a/WebKit/android/plugins/ANPTypefaceInterface.cpp +++ b/WebKit/android/plugins/ANPTypefaceInterface.cpp @@ -26,6 +26,7 @@ // must include config.h first for webkit to fiddle with new/delete #include "config.h" #include "SkANP.h" +#include "SkFontHost.h" static ANPTypeface* anp_createFromName(const char name[], ANPTypefaceStyle s) { SkTypeface* tf = SkTypeface::CreateFromName(name, @@ -57,6 +58,28 @@ static ANPTypefaceStyle anp_getStyle(const ANPTypeface* tf) { return static_cast<ANPTypefaceStyle>(s); } +static uint32_t anp_countTables(const ANPTypeface* tf) { + SkFontID id = SkTypeface::UniqueID(tf); + return SkFontHost::CountTables(id); +} + +static uint32_t anp_getTableTags(const ANPTypeface* tf, + ANPFontTableTag tags[]) { + SkFontID id = SkTypeface::UniqueID(tf); + return SkFontHost::GetTableTags(id, tags); +} + +static uint32_t anp_getTableSize(const ANPTypeface* tf, ANPFontTableTag tag) { + SkFontID id = SkTypeface::UniqueID(tf); + return SkFontHost::GetTableSize(id, tag); +} + +static uint32_t anp_getTableData(const ANPTypeface* tf, ANPFontTableTag tag, + uint32_t offset, uint32_t length, void* data) { + SkFontID id = SkTypeface::UniqueID(tf); + return SkFontHost::GetTableData(id, tag, offset, length, data); +} + /////////////////////////////////////////////////////////////////////////////// #define ASSIGN(obj, name) (obj)->name = anp_##name @@ -70,5 +93,9 @@ void ANPTypefaceInterfaceV0_Init(ANPInterface* v) { ASSIGN(i, ref); ASSIGN(i, unref); ASSIGN(i, getStyle); + ASSIGN(i, countTables); + ASSIGN(i, getTableTags); + ASSIGN(i, getTableSize); + ASSIGN(i, getTableData); } diff --git a/WebKit/android/plugins/PluginWidgetAndroid.cpp b/WebKit/android/plugins/PluginWidgetAndroid.cpp index 350243e..ddb07bf 100644 --- a/WebKit/android/plugins/PluginWidgetAndroid.cpp +++ b/WebKit/android/plugins/PluginWidgetAndroid.cpp @@ -25,6 +25,9 @@ #include "config.h" #include "android_graphics.h" +#include "Document.h" +#include "Element.h" +#include "Frame.h" #include "PluginPackage.h" #include "PluginView.h" #include "PluginWidgetAndroid.h" @@ -37,6 +40,7 @@ PluginWidgetAndroid::PluginWidgetAndroid(WebCore::PluginView* view) m_flipPixelRef = NULL; m_core = NULL; m_drawingModel = kBitmap_ANPDrawingModel; + m_eventFlags = 0; m_x = m_y = 0; } @@ -156,3 +160,24 @@ bool PluginWidgetAndroid::sendEvent(const ANPEvent& evt) { return false; } +void PluginWidgetAndroid::updateEventFlags(ANPEventFlags flags) { + + // if there are no differences then immediately return + if (m_eventFlags == flags) { + return; + } + + Document* doc = m_pluginView->getParentFrame()->document(); + if((m_eventFlags ^ flags) & kTouch_ANPEventFlag) { + if(flags & kTouch_ANPEventFlag) + doc->addTouchEventListener(m_pluginView->getElement()); + else + doc->removeTouchEventListener(m_pluginView->getElement()); + } + + m_eventFlags = flags; +} + +bool PluginWidgetAndroid::isAcceptingEvent(ANPEventFlag flag) { + return m_eventFlags & flag; +} diff --git a/WebKit/android/plugins/PluginWidgetAndroid.h b/WebKit/android/plugins/PluginWidgetAndroid.h index 157651c..1b0cfa9 100644 --- a/WebKit/android/plugins/PluginWidgetAndroid.h +++ b/WebKit/android/plugins/PluginWidgetAndroid.h @@ -62,7 +62,7 @@ struct PluginWidgetAndroid { /* Called whenever the plugin itself requests a new drawing model */ void setDrawingModel(ANPDrawingModel); - + /* Utility method to convert from local (plugin) coordinates to docuemnt coordinates. Needed (for instance) to convert the dirty rectangle into document coordinates to inturn inval the screen. @@ -78,22 +78,33 @@ struct PluginWidgetAndroid { a subsequent call to draw(NULL). */ void inval(const WebCore::IntRect&, bool signalRedraw); - + /* Called to draw into the plugin's bitmap. If canvas is non-null, the bitmap itself is then drawn into the canvas. */ void draw(SkCanvas* canvas = NULL); - + /* Send this event to the plugin instance, and return true if the plugin handled it. */ bool sendEvent(const ANPEvent&); + /* Update the plugins event flags. If a flag is set to true then the plugin + wants to be notified of events of this type. + */ + void updateEventFlags(ANPEventFlags); + + /* Called to check if a plugin wants to accept a given event type. It + returns true if the plugin wants the events and false otherwise. + */ + bool isAcceptingEvent(ANPEventFlag); + private: WebCore::PluginView* m_pluginView; android::WebViewCore* m_core; SkFlipPixelRef* m_flipPixelRef; ANPDrawingModel m_drawingModel; + ANPEventFlags m_eventFlags; int m_x; int m_y; }; diff --git a/WebKit/android/plugins/android_npapi.h b/WebKit/android/plugins/android_npapi.h index bda8eeb..32fa1c0 100644 --- a/WebKit/android/plugins/android_npapi.h +++ b/WebKit/android/plugins/android_npapi.h @@ -126,9 +126,9 @@ typedef uint32_t ANPMatrixFlag; #define kSupportedDrawingModel_ANPGetValue ((NPNVariable)2000) /////////////////////////////////////////////////////////////////////////////// -// NPN_GetValue +// NPN_SetValue -/** Reqeust to set the drawing model. +/** Request to set the drawing model. NPN_SetValue(inst, ANPRequestDrawingModel_EnumValue, (void*)foo_DrawingModel) */ @@ -147,6 +147,24 @@ enum ANPDrawingModels { }; typedef int32_t ANPDrawingModel; +/** Request to receive/disable events. If the pointer is NULL then all input will + be disabled. Otherwise, the input type will be enabled iff its corresponding + bit in the EventFlags bit field is set. + + NPN_SetValue(inst, ANPAcceptEvents, (void*)EventFlags) + */ +#define kAcceptEvents_ANPSetValue ((NPPVariable)1001) + +/* The EventFlags are a set of bits used to determine which types of input the + plugin wishes to receive. For example, if the value is 0x03 then both key + and touch events will be provided to the plugin. + */ +enum ANPEventFlag { + kKey_ANPEventFlag = 0x01, + kTouch_ANPEventFlag = 0x02, +}; +typedef uint32_t ANPEventFlags; + /* Interfaces provide additional functionality to the plugin via function ptrs. Once an interface is retrived, it is valid for the lifetime of the plugin (just like browserfuncs). @@ -347,6 +365,8 @@ enum ANPTypefaceStyles { }; typedef uint32_t ANPTypefaceStyle; +typedef uint32_t ANPFontTableTag; + struct ANPFontMetrics { //! The greatest distance above the baseline for any glyph (will be <= 0) float fTop; @@ -403,6 +423,43 @@ struct ANPTypefaceInterfaceV0 : ANPInterface { /** Return the style bits for the specified typeface */ ANPTypefaceStyle (*getStyle)(const ANPTypeface*); + + /** Return the number of tables in the font + */ + uint32_t (*countTables)(const ANPTypeface*); + + /** Copy into tags[] (allocated by the caller) the list of table tags in + the font, and return the number. This will be the same as CountTables() + or 0 if an error occured. + */ + uint32_t (*getTableTags)(const ANPTypeface*, ANPFontTableTag tags[]); + + /** Given a table tag, return the size of its contents, or 0 if not present + */ + uint32_t (*getTableSize)(const ANPTypeface*, ANPFontTableTag); + + /** Copy the contents of a table into data (allocated by the caller). Note + that the contents of the table will be in their native endian order + (which for most truetype tables is big endian). If the table tag is + not found, or there is an error copying the data, then 0 is returned. + If this happens, it is possible that some or all of the memory pointed + to by data may have been written to, even though an error has occured. + + @param fontID the font to copy the table from + @param tag The table tag whose contents are to be copied + @param offset The offset in bytes into the table's contents where the + copy should start from. + @param length The number of bytes, starting at offset, of table data + to copy. + @param data storage address where the table contents are copied to + @return the number of bytes actually copied into data. If offset+length + exceeds the table's size, then only the bytes up to the table's + size are actually copied, and this is the value returned. If + offset > the table's size, or tag is not a valid table, + then 0 is returned. + */ + uint32_t (*getTableData)(const ANPTypeface*, ANPFontTableTag, + uint32_t offset, uint32_t length, void* data); }; struct ANPPaintInterfaceV0 : ANPInterface { @@ -660,8 +717,10 @@ enum ANPKeyModifiers { typedef uint32_t ANPKeyModifier; enum ANPTouchActions { - kDown_ANPTouchAction = 0, - kUp_ANPTouchAction = 1, + kDown_ANPTouchAction = 0, + kUp_ANPTouchAction = 1, + kMove_ANPTouchAction = 2, + kCancel_ANPTouchAction = 3, }; typedef int32_t ANPTouchAction; |