summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit')
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp63
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.h26
-rw-r--r--WebKit/android/WebCoreSupport/PlatformBridge.cpp19
-rw-r--r--WebKit/android/jni/WebViewCore.cpp94
-rw-r--r--WebKit/android/jni/WebViewCore.h7
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp2
-rw-r--r--WebKit/android/nav/CachedFrame.cpp50
-rw-r--r--WebKit/android/nav/CachedFrame.h2
-rw-r--r--WebKit/android/nav/CachedInput.cpp15
-rw-r--r--WebKit/android/nav/CachedRoot.cpp23
-rw-r--r--WebKit/android/nav/CachedRoot.h7
-rw-r--r--WebKit/android/nav/WebView.cpp142
12 files changed, 367 insertions, 83 deletions
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index 8390cbc..f14c2c1 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -38,6 +38,7 @@
#include "FrameLoader.h"
#include "FrameView.h"
#include "Geolocation.h"
+#include "GraphicsLayerAndroid.h"
#include "Page.h"
#include "Screen.h"
#include "ScriptController.h"
@@ -49,6 +50,68 @@
namespace android {
+#if USE(ACCELERATED_COMPOSITING)
+
+void ChromeClientAndroid::syncTimerFired(Timer<ChromeClientAndroid>* client)
+{
+ m_syncTimer.stop();
+ compositingLayerSync();
+}
+
+void ChromeClientAndroid::compositingLayerSync()
+{
+ if (!m_rootGraphicsLayer) {
+ scheduleCompositingLayerSync();
+ return;
+ }
+
+ if (m_webFrame) {
+ FrameView* frameView = m_webFrame->page()->mainFrame()->view();
+ if (frameView && !frameView->layoutPending() && !frameView->needsLayout()) {
+ frameView->syncCompositingStateRecursive();
+ GraphicsLayerAndroid* androidGraphicsLayer =
+ static_cast<GraphicsLayerAndroid*>(m_rootGraphicsLayer);
+ if (androidGraphicsLayer)
+ androidGraphicsLayer->sendImmediateRepaint();
+ return;
+ }
+ }
+ if (m_askToDrawAgain) {
+ m_askToDrawAgain = false;
+ scheduleCompositingLayerSync();
+ }
+}
+
+void ChromeClientAndroid::scheduleCompositingLayerSync()
+{
+ if (!m_syncTimer.isActive())
+ m_syncTimer.startOneShot(0.001); // 1ms
+ else
+ m_askToDrawAgain = true;
+}
+
+void ChromeClientAndroid::setNeedsOneShotDrawingSynchronization()
+{
+ // This should not be needed
+}
+
+void ChromeClientAndroid::attachRootGraphicsLayer(WebCore::Frame* frame, WebCore::GraphicsLayer* layer)
+{
+ m_rootGraphicsLayer = layer;
+ if (!layer) {
+ WebViewCore::getWebViewCore(frame->view())->setRootLayer(0);
+ return;
+ }
+ WebCore::GraphicsLayerAndroid* androidGraphicsLayer = static_cast<GraphicsLayerAndroid*>(layer);
+ if (frame && frame->view() && androidGraphicsLayer) {
+ androidGraphicsLayer->setFrame(frame);
+ WebCore::LayerAndroid* androidLayer = new LayerAndroid(androidGraphicsLayer->contentLayer());
+ WebViewCore::getWebViewCore(frame->view())->setRootLayer((int)androidLayer);
+ }
+}
+
+#endif
+
void ChromeClientAndroid::setWebFrame(android::WebFrame* webframe)
{
Release(m_webFrame);
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
index 7396997..45dd078 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
@@ -43,7 +43,13 @@ namespace android {
class ChromeClientAndroid : public ChromeClient {
public:
- ChromeClientAndroid() : m_webFrame(0), m_geolocationPermissions(0) { }
+ ChromeClientAndroid() : m_webFrame(0), m_geolocationPermissions(0)
+#if USE(ACCELERATED_COMPOSITING)
+ , m_rootGraphicsLayer(0)
+ , m_askToDrawAgain(false)
+ , m_syncTimer(this, &ChromeClientAndroid::syncTimerFired)
+#endif
+ { }
virtual void chromeDestroyed();
virtual void setWindowRect(const FloatRect&);
@@ -149,13 +155,27 @@ namespace android {
// Android-specific
void setWebFrame(android::WebFrame* webframe);
void wakeUpMainThreadWithNewQuota(long newQuota);
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer* g);
+ virtual void setNeedsOneShotDrawingSynchronization();
+ virtual void scheduleCompositingLayerSync();
+ void compositingLayerSync();
+ void syncTimerFired(Timer<ChromeClientAndroid>*);
+#endif
+
private:
android::WebFrame* m_webFrame;
+ // The Geolocation permissions manager.
+ OwnPtr<GeolocationPermissions> m_geolocationPermissions;
+#if USE(ACCELERATED_COMPOSITING)
+ WebCore::GraphicsLayer* m_rootGraphicsLayer;
+ bool m_askToDrawAgain;
+ Timer<ChromeClientAndroid> m_syncTimer;
+#endif
WTF::ThreadCondition m_quotaThreadCondition;
WTF::Mutex m_quotaThreadLock;
long m_newQuota;
- // The Geolocation permissions manager.
- OwnPtr<GeolocationPermissions> m_geolocationPermissions;
};
}
diff --git a/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/WebKit/android/WebCoreSupport/PlatformBridge.cpp
index e4fe4ce..e93d3da 100644
--- a/WebKit/android/WebCoreSupport/PlatformBridge.cpp
+++ b/WebKit/android/WebCoreSupport/PlatformBridge.cpp
@@ -28,11 +28,28 @@
#include "JavaSharedClient.h"
#include "KeyGeneratorClient.h"
+#include "WebViewCore.h"
using namespace android;
namespace WebCore {
+#if USE(ACCELERATED_COMPOSITING)
+
+void PlatformBridge::setRootLayer(const WebCore::FrameView* view, int layer)
+{
+ android::WebViewCore* core = android::WebViewCore::getWebViewCore(view);
+ core->setRootLayer(layer);
+}
+
+void PlatformBridge::immediateRepaint(const WebCore::FrameView* view)
+{
+ android::WebViewCore* core = android::WebViewCore::getWebViewCore(view);
+ core->immediateRepaint();
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
WTF::Vector<String> PlatformBridge::getSupportedKeyStrengthList()
{
KeyGeneratorClient* client = JavaSharedClient::GetKeyGeneratorClient();
@@ -51,4 +68,4 @@ String PlatformBridge::getSignedPublicKeyAndChallengeString(unsigned index, cons
return client->getSignedPublicKeyAndChallengeString(index, challenge, url);
}
-} \ No newline at end of file
+}
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 896d902..ee1f880 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -57,6 +57,7 @@
#include "HTMLElement.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
+#include "HTMLLabelElement.h"
#include "HTMLMapElement.h"
#include "HTMLNames.h"
#include "HTMLOptGroupElement.h"
@@ -68,6 +69,7 @@
#include "KeyboardCodes.h"
#include "Navigator.h"
#include "Node.h"
+#include "NodeList.h"
#include "Page.h"
#include "PageGroup.h"
#include "PlatformKeyboardEvent.h"
@@ -130,6 +132,11 @@ FILE* gRenderTreeFile = 0;
#include "TimeCounter.h"
#endif
+#if USE(ACCELERATED_COMPOSITING)
+#include "GraphicsLayerAndroid.h"
+#include "RenderLayerCompositor.h"
+#endif
+
/* We pass this flag when recording the actual content, so that we don't spend
time actually regionizing complex path clips, when all we really want to do
is record them.
@@ -195,6 +202,8 @@ struct WebViewCore::JavaGlue {
jmethodID m_updateViewport;
jmethodID m_sendNotifyProgressFinished;
jmethodID m_sendViewInvalidate;
+ jmethodID m_sendImmediateRepaint;
+ jmethodID m_setRootLayer;
jmethodID m_updateTextfield;
jmethodID m_updateTextSelection;
jmethodID m_clearTextEntry;
@@ -277,6 +286,8 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_updateViewport = GetJMethod(env, clazz, "updateViewport", "()V");
m_javaGlue->m_sendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V");
m_javaGlue->m_sendViewInvalidate = GetJMethod(env, clazz, "sendViewInvalidate", "(IIII)V");
+ m_javaGlue->m_sendImmediateRepaint = GetJMethod(env, clazz, "sendImmediateRepaint", "()V");
+ m_javaGlue->m_setRootLayer = GetJMethod(env, clazz, "setRootLayer", "(I)V");
m_javaGlue->m_updateTextfield = GetJMethod(env, clazz, "updateTextfield", "(IZLjava/lang/String;I)V");
m_javaGlue->m_updateTextSelection = GetJMethod(env, clazz, "updateTextSelection", "(IIII)V");
m_javaGlue->m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V");
@@ -879,6 +890,28 @@ void WebViewCore::scrollBy(int dx, int dy, bool animate)
checkException(env);
}
+#if USE(ACCELERATED_COMPOSITING)
+
+void WebViewCore::immediateRepaint()
+{
+ LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_sendImmediateRepaint);
+ checkException(env);
+}
+
+void WebViewCore::setRootLayer(int layer)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_setRootLayer,
+ layer);
+ checkException(env);
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
void WebViewCore::contentDraw()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
@@ -1156,14 +1189,14 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height,
r->setNeedsLayoutAndPrefWidthsRecalc();
m_mainFrame->view()->forceLayout();
// scroll to restore current screen center
- if (!node)
- return;
- const WebCore::IntRect& newBounds = node->getRect();
- DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d,"
- "h=%d,ns=%d)", newBounds.x(), newBounds.y(),
- newBounds.width(), newBounds.height());
- scrollBy(newBounds.x() - bounds.x(), newBounds.y() - bounds.y(),
- false);
+ if (node) {
+ const WebCore::IntRect& newBounds = node->getRect();
+ DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d,"
+ "h=%d,ns=%d)", newBounds.x(), newBounds.y(),
+ newBounds.width(), newBounds.height());
+ scrollBy(newBounds.x() - bounds.x(), newBounds.y() - bounds.y(),
+ false);
+ }
}
}
@@ -1237,6 +1270,22 @@ WebCore::String WebViewCore::retrieveAnchorText(WebCore::Frame* frame, WebCore::
return anchor ? anchor->text() : WebCore::String();
}
+WebCore::String WebViewCore::requestLabel(WebCore::Frame* frame,
+ WebCore::Node* node)
+{
+ if (CacheBuilder::validNode(m_mainFrame, frame, node)) {
+ RefPtr<WebCore::NodeList> list = node->document()->getElementsByTagName("label");
+ unsigned length = list->length();
+ for (unsigned i = 0; i < length; i++) {
+ WebCore::HTMLLabelElement* label = static_cast<WebCore::HTMLLabelElement*>(
+ list->item(i));
+ if (label->correspondingControl() == node)
+ return label->innerHTML();
+ }
+ }
+ return WebCore::String();
+}
+
void WebViewCore::updateCacheOnNodeChange()
{
gCursorBoundsMutex.lock();
@@ -1267,6 +1316,12 @@ void WebViewCore::updateCacheOnNodeChange()
void WebViewCore::updateFrameCache()
{
+#if USE(ACCELERATED_COMPOSITING)
+ ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(
+ mainFrame()->page()->chrome()->client());
+ chromeC->scheduleCompositingLayerSync();
+#endif
+
if (!m_frameCacheOutOfDate) {
DBG_NAV_LOG("!m_frameCacheOutOfDate");
return;
@@ -2098,6 +2153,16 @@ int WebViewCore::handleTouchEvent(int action, int x, int y)
{
int preventDefault = 0;
+#if USE(ACCELERATED_COMPOSITING)
+ RenderView* contentRenderer = m_mainFrame->contentRenderer();
+ GraphicsLayerAndroid* rootLayer = 0;
+ if (contentRenderer)
+ rootLayer = static_cast<GraphicsLayerAndroid*>(
+ contentRenderer->compositor()->rootPlatformLayer());
+ if (rootLayer)
+ rootLayer->pauseDisplay(true);
+#endif
+
#if ENABLE(TOUCH_EVENTS) // Android
WebCore::TouchEventType type = WebCore::TouchEventCancel;
switch (action) {
@@ -2125,6 +2190,10 @@ int WebViewCore::handleTouchEvent(int action, int x, int y)
preventDefault = m_mainFrame->eventHandler()->handleTouchEvent(te);
#endif
+#if USE(ACCELERATED_COMPOSITING)
+ if (rootLayer)
+ rootLayer->pauseDisplay(false);
+#endif
return preventDefault;
}
@@ -2677,6 +2746,13 @@ static jstring WebCoreStringToJString(JNIEnv *env, WebCore::String string)
return ret;
}
+static jstring RequestLabel(JNIEnv *env, jobject obj, int framePointer,
+ int nodePointer)
+{
+ return WebCoreStringToJString(env, GET_NATIVE_VIEW(env, obj)->requestLabel(
+ (WebCore::Frame*) framePointer, (WebCore::Node*) nodePointer));
+}
+
static void UpdateFrameCacheIfLoading(JNIEnv *env, jobject obj)
{
GET_NATIVE_VIEW(env, obj)->updateFrameCacheIfLoading();
@@ -3357,6 +3433,8 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
{ "nativeResume", "()V", (void*) Resume },
{ "nativeFreeMemory", "()V", (void*) FreeMemory },
{ "nativeSetJsFlags", "(Ljava/lang/String;)V", (void*) SetJsFlags },
+ { "nativeRequestLabel", "(II)Ljava/lang/String;",
+ (void*) RequestLabel },
{ "nativeUpdateFrameCacheIfLoading", "()V",
(void*) UpdateFrameCacheIfLoading },
{ "nativeProvideVisitedHistory", "([Ljava/lang/String;)V",
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 4c8de78..912b8e6 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -126,6 +126,11 @@ namespace android {
*/
void contentDraw();
+#if USE(ACCELERATED_COMPOSITING)
+ void immediateRepaint();
+ void setRootLayer(int layer);
+#endif
+
/** Invalidate the view/screen, NOT the content/DOM, but expressed in
* content/DOM coordinates (i.e. they need to eventually be scaled,
* by webview into view.java coordinates
@@ -241,7 +246,7 @@ namespace android {
WebCore::String retrieveHref(WebCore::Frame* frame, WebCore::Node* node);
WebCore::String retrieveAnchorText(WebCore::Frame* frame, WebCore::Node* node);
-
+ WebCore::String requestLabel(WebCore::Frame* , WebCore::Node* );
WebCore::String getSelection(SkRegion* );
// Create a single picture to represent the drawn DOM (used by navcache)
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index ce78c29..c4c25db 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -1099,7 +1099,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
goto keepTextNode;
}
if (node->hasTagName(WebCore::HTMLNames::inputTag)) {
- HTMLInputElement* input = (HTMLInputElement*) node;
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
HTMLInputElement::InputType inputType = input->inputType();
if (input->isTextField()) {
type = TEXT_INPUT_CACHEDNODETYPE;
diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp
index a95a401..299dc53 100644
--- a/WebKit/android/nav/CachedFrame.cpp
+++ b/WebKit/android/nav/CachedFrame.cpp
@@ -441,14 +441,18 @@ const CachedFrame* CachedFrame::findBestFrameAt(int x, int y) const
}
const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect,
- int* best, const CachedFrame** framePtr, int* x, int* y) const
+ const CachedFrame** framePtr, int* x, int* y) const
{
- const CachedNode* result = NULL;
- int rectWidth = rect.width();
- WebCore::IntPoint center = WebCore::IntPoint(rect.x() + (rectWidth >> 1),
- rect.y() + (rect.height() >> 1));
mRoot->setupScrolledBounds();
- for (const CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) {
+ for (const CachedFrame* frame = mCachedFrames.end() - 1;
+ frame != mCachedFrames.begin() - 1; frame--) {
+ const CachedNode* frameResult = frame->findBestHitAt(rect,
+ framePtr, x, y);
+ if (NULL != frameResult)
+ return frameResult;
+ }
+ for (const CachedNode* test = mCachedNodes.end() - 1;
+ test != mCachedNodes.begin() - 1; test--) {
if (test->disabled())
continue;
const WebCore::IntRect& testRect = test->hitBounds();
@@ -459,29 +463,19 @@ const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect,
testData.mMouseBounds = testData.mNodeBounds = testRect;
if (mRoot->maskIfHidden(&testData) == true)
continue;
- const WebCore::IntRect& bounds = testData.mMouseBounds;
- WebCore::IntPoint testCenter = WebCore::IntPoint(bounds.x() +
- (bounds.width() >> 1), bounds.y() + (bounds.height() >> 1));
- int dx = testCenter.x() - center.x();
- int dy = testCenter.y() - center.y();
- int distance = dx * dx + dy * dy;
- if (*best < distance)
- continue;
- *best = distance;
- result = test;
- *framePtr = this;
- const WebCore::IntRect& cursorRect = test->cursorRings().at(0);
- *x = cursorRect.x() + (cursorRect.width() >> 1);
- *y = cursorRect.y() + (cursorRect.height() >> 1);
- }
- for (const CachedFrame* frame = mCachedFrames.begin();
- frame != mCachedFrames.end(); frame++) {
- const CachedNode* frameResult = frame->findBestHitAt(rect, best,
- framePtr, x, y);
- if (NULL != frameResult)
- result = frameResult;
+ for (unsigned i = 0; i < test->cursorRings().size(); i++) {
+ const WebCore::IntRect& cursorRect = test->cursorRings().at(i);
+ if (cursorRect.intersects(rect)) {
+ WebCore::IntRect intersection(cursorRect);
+ intersection.intersect(rect);
+ *x = intersection.x() + (intersection.width() >> 1);
+ *y = intersection.y() + (intersection.height() >> 1);
+ *framePtr = this;
+ return test;
+ }
+ }
}
- return result;
+ return NULL;
}
void CachedFrame::findClosest(BestData* bestData, Direction originalDirection,
diff --git a/WebKit/android/nav/CachedFrame.h b/WebKit/android/nav/CachedFrame.h
index f0996f7..7a00539 100644
--- a/WebKit/android/nav/CachedFrame.h
+++ b/WebKit/android/nav/CachedFrame.h
@@ -85,7 +85,7 @@ public:
int* y, bool checkForHidden) const;
const CachedFrame* findBestFrameAt(int x, int y) const;
const CachedNode* findBestHitAt(const WebCore::IntRect& ,
- int* best, const CachedFrame** , int* x, int* y) const;
+ const CachedFrame** , int* x, int* y) const;
void finishInit();
CachedFrame* firstChild() { return mCachedFrames.begin(); }
const CachedFrame* firstChild() const { return mCachedFrames.begin(); }
diff --git a/WebKit/android/nav/CachedInput.cpp b/WebKit/android/nav/CachedInput.cpp
index 52d2066..d7b96e3 100644
--- a/WebKit/android/nav/CachedInput.cpp
+++ b/WebKit/android/nav/CachedInput.cpp
@@ -38,18 +38,23 @@ CachedInput* CachedInput::Debug::base() const {
return nav;
}
-void CachedInput::Debug::print() const
-{
- CachedInput* b = base();
+static void printWebCoreString(const char* label,
+ const WebCore::String& string) {
char scratch[256];
- size_t index = snprintf(scratch, sizeof(scratch), "// char* mName=\"");
- const UChar* ch = b->mName.characters();
+ size_t index = snprintf(scratch, sizeof(scratch), label);
+ const UChar* ch = string.characters();
while (ch && *ch && index < sizeof(scratch)) {
UChar c = *ch++;
if (c < ' ' || c >= 0x7f) c = ' ';
scratch[index++] = c;
}
DUMP_NAV_LOGD("%.*s\"\n", index, scratch);
+}
+
+void CachedInput::Debug::print() const
+{
+ CachedInput* b = base();
+ printWebCoreString("// char* mName=\"", b->mName);
DUMP_NAV_LOGD("// void* mForm=%p;", b->mForm);
DUMP_NAV_LOGD("// int mMaxLength=%d;\n", b->mMaxLength);
DUMP_NAV_LOGD("// int mTextSize=%d;\n", b->mTextSize);
diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp
index 2354ebc..e783eae 100644
--- a/WebKit/android/nav/CachedRoot.cpp
+++ b/WebKit/android/nav/CachedRoot.cpp
@@ -756,14 +756,17 @@ bool CachedRoot::checkRings(const WTF::Vector<WebCore::IntRect>& rings,
return ringCheck.success();
}
-CachedRoot::ImeAction CachedRoot::cursorTextFieldAction() const
+CachedRoot::ImeAction CachedRoot::currentTextFieldAction() const
{
- const CachedFrame* cursorFrame;
- const CachedNode* cursor = currentCursor(&cursorFrame);
- if (!cursor) {
- // Error case. The cursor has no action, because there is no node under
- // the cursor
- return FAILURE;
+ const CachedFrame* currentFrame;
+ const CachedNode* current = currentCursor(&currentFrame);
+ if (!current) {
+ // Although the cursor is not on a textfield, a textfield may have
+ // focus. Find the action for that textfield.
+ current = currentFocus(&currentFrame);
+ if (!current)
+ // Error case. No cursor and no focus.
+ return FAILURE;
}
const CachedNode* firstTextfield = nextTextField(0, 0, false);
if (!firstTextfield) {
@@ -773,8 +776,8 @@ CachedRoot::ImeAction CachedRoot::cursorTextFieldAction() const
// Now find the next textfield/area starting with the cursor
const CachedFrame* potentialFrame;
const CachedNode* potentialNext
- = cursorFrame->nextTextField(cursor, &potentialFrame, true);
- if (potentialNext && cursorFrame->textInput(cursor)->formPointer()
+ = currentFrame->nextTextField(current, &potentialFrame, true);
+ if (potentialNext && currentFrame->textInput(current)->formPointer()
== potentialFrame->textInput(potentialNext)->formPointer()) {
// There is a textfield/area after the cursor in the same form,
// so the textfield under the cursor should have the NEXT action
@@ -797,7 +800,7 @@ const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect,
DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(),
node == NULL ? NULL : node->nodePointer());
if (node == NULL) {
- node = findBestHitAt(rect, &best, framePtr, x, y);
+ node = findBestHitAt(rect, framePtr, x, y);
DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(),
node == NULL ? NULL : node->nodePointer());
}
diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h
index 435937a..5fdf8df 100644
--- a/WebKit/android/nav/CachedRoot.h
+++ b/WebKit/android/nav/CachedRoot.h
@@ -52,11 +52,12 @@ public:
void checkForJiggle(int* ) const;
bool checkRings(const WTF::Vector<WebCore::IntRect>& rings,
const WebCore::IntRect& bounds) const;
- WebCore::IntPoint cursorLocation() const;
// This method returns the desired ImeAction for the textfield where the
- // mouse cursor currently is. If the mouse cursor is not on a textfield,
+ // mouse cursor currently is, or where the focus is if there is no mouse
+ // cursor. If the mouse cursor is not on a textfield,
// it will return FAILURE
- ImeAction cursorTextFieldAction() const;
+ ImeAction currentTextFieldAction() const;
+ WebCore::IntPoint cursorLocation() const;
int documentHeight() { return mContents.height(); }
int documentWidth() { return mContents.width(); }
const CachedNode* findAt(const WebCore::IntRect& , const CachedFrame** ,
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index c29cb22..1267647 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -28,6 +28,7 @@
#include <config.h>
#include "android_graphics.h"
+#include "AndroidAnimation.h"
#include "AndroidLog.h"
#include "AtomicString.h"
#include "CachedFrame.h"
@@ -39,6 +40,7 @@
#include "HTMLInputElement.h"
#include "IntPoint.h"
#include "IntRect.h"
+#include "LayerAndroid.h"
#include "Node.h"
#include "PlatformGraphicsContext.h"
#include "PlatformString.h"
@@ -104,11 +106,11 @@ struct JavaGlue {
jmethodID m_sendMoveMouse;
jmethodID m_sendMoveMouseIfLatest;
jmethodID m_sendMotionUp;
+ jmethodID m_domChangedFocus;
jmethodID m_getScaledMaxXScroll;
jmethodID m_getScaledMaxYScroll;
jmethodID m_getVisibleRect;
jmethodID m_rebuildWebTextView;
- jmethodID m_setOkayToNotMatch;
jmethodID m_displaySoftKeyboard;
jmethodID m_viewInvalidate;
jmethodID m_viewInvalidateRect;
@@ -134,11 +136,11 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl)
m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V");
m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "(Z)V");
m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIII)V");
+ m_javaGlue.m_domChangedFocus = GetJMethod(env, clazz, "domChangedFocus", "()V");
m_javaGlue.m_getScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I");
m_javaGlue.m_getScaledMaxYScroll = GetJMethod(env, clazz, "getScaledMaxYScroll", "()I");
m_javaGlue.m_getVisibleRect = GetJMethod(env, clazz, "sendOurVisibleRect", "()Landroid/graphics/Rect;");
m_javaGlue.m_rebuildWebTextView = GetJMethod(env, clazz, "rebuildWebTextView", "()V");
- m_javaGlue.m_setOkayToNotMatch = GetJMethod(env, clazz, "setOkayNotToMatch", "()V");
m_javaGlue.m_displaySoftKeyboard = GetJMethod(env, clazz, "displaySoftKeyboard", "(Z)V");
m_javaGlue.m_viewInvalidate = GetJMethod(env, clazz, "viewInvalidate", "()V");
m_javaGlue.m_viewInvalidateRect = GetJMethod(env, clazz, "viewInvalidate", "(IIII)V");
@@ -613,6 +615,7 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer)
}
DBG_NAV_LOGD("%s", "m_viewImpl->m_updatedFrameCache == true");
bool hadCursor = m_frameCacheUI && m_frameCacheUI->currentCursor();
+ const CachedNode* oldFocus = m_frameCacheUI ? m_frameCacheUI->currentFocus() : 0;
m_viewImpl->gFrameCacheMutex.lock();
delete m_frameCacheUI;
delete m_navPictureUI;
@@ -623,6 +626,19 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer)
m_viewImpl->m_navPictureKit = 0;
m_viewImpl->gFrameCacheMutex.unlock();
fixCursor();
+ if (oldFocus && m_frameCacheUI) {
+ const CachedNode* newFocus = m_frameCacheUI->currentFocus();
+ if (newFocus && oldFocus != newFocus && newFocus->isTextInput()
+ && oldFocus->isTextInput()
+ && newFocus != m_frameCacheUI->currentCursor()) {
+ // The focus has changed. We may need to update things.
+ LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_domChangedFocus);
+ checkException(env);
+ }
+ }
if (hadCursor && (!m_frameCacheUI || !m_frameCacheUI->currentCursor()))
viewInvalidate(); // redraw in case cursor ring is still visible
return m_frameCacheUI;
@@ -839,7 +855,7 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll)
void notifyProgressFinished()
{
DBG_NAV_LOGD("cursorIsTextInput=%d", cursorIsTextInput(DontAllowNewer));
- rebuildWebTextView(false);
+ rebuildWebTextView();
#if DEBUG_NAV_UI
if (m_frameCacheUI) {
const CachedNode* focus = m_frameCacheUI->currentFocus();
@@ -951,7 +967,9 @@ bool motionUp(int x, int y, int slop)
}
DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result,
result->index(), x, y, rx, ry);
- setNavBounds(WebCore::IntRect(rx, ry, 1, 1));
+ WebCore::IntRect navBounds = WebCore::IntRect(rx, ry, 1, 1);
+ setNavBounds(navBounds);
+ root->rootHistory()->setMouseBounds(navBounds);
updateCursorBounds(root, frame, result);
root->setCursor(const_cast<CachedFrame*>(frame),
const_cast<CachedNode*>(result));
@@ -964,7 +982,7 @@ bool motionUp(int x, int y, int slop)
viewInvalidate();
if (result->isTextInput()) {
bool isReadOnly = frame->textInput(result)->isReadOnly();
- rebuildWebTextView(true);
+ rebuildWebTextView();
if (!isReadOnly)
displaySoftKeyboard(true);
} else {
@@ -1277,7 +1295,7 @@ bool hasFocusNode()
return focusNode;
}
-void rebuildWebTextView(bool needNotMatchFocus)
+void rebuildWebTextView()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject obj = m_javaGlue.object(env);
@@ -1287,10 +1305,6 @@ void rebuildWebTextView(bool needNotMatchFocus)
return;
env->CallVoidMethod(obj.get(), m_javaGlue.m_rebuildWebTextView);
checkException(env);
- if (needNotMatchFocus) {
- env->CallVoidMethod(obj.get(), m_javaGlue.m_setOkayToNotMatch);
- checkException(env);
- }
}
void displaySoftKeyboard(bool isTextView)
@@ -1592,6 +1606,86 @@ static void nativeDrawMatches(JNIEnv *env, jobject obj, jobject canv)
view->drawMatches(canvas);
}
+static void nativeDrawLayers(JNIEnv *env, jobject obj,
+ jint layer, jfloat scrollX, jfloat scrollY,
+ jfloat scale, jobject canv)
+{
+ if (!env)
+ return;
+ if (!layer)
+ return;
+ if (!canv)
+ return;
+
+#if USE(ACCELERATED_COMPOSITING)
+ LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer);
+ SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv);
+ if (canvas)
+ layerImpl->paintOn(scrollX, scrollY, scale, canvas);
+#endif
+}
+
+static void nativeUpdateLayers(JNIEnv *env, jobject obj,
+ jint layer, jint updates)
+{
+ if (!env)
+ return;
+ if (!layer)
+ return;
+ if (!updates)
+ return;
+
+#if USE(ACCELERATED_COMPOSITING)
+ Vector<RefPtr<AndroidAnimationValue> >* updatesImpl =
+ reinterpret_cast<Vector<RefPtr<AndroidAnimationValue> >* >(updates);
+ if (updatesImpl) {
+ for (unsigned int i = 0; i < updatesImpl->size(); i++)
+ (updatesImpl->at(i))->apply();
+ delete updatesImpl;
+ }
+#endif
+}
+
+static bool nativeLayersHaveAnimations(JNIEnv *env, jobject obj, jint layer)
+{
+ if (!env)
+ return false;
+ if (!layer)
+ return false;
+#if USE(ACCELERATED_COMPOSITING)
+ LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer);
+ return layerImpl->hasAnimations();
+#else
+ return false;
+#endif
+}
+
+static int nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj, jint layer)
+{
+ if (!env)
+ return 0;
+ if (!layer)
+ return 0;
+#if USE(ACCELERATED_COMPOSITING)
+ LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer);
+ return reinterpret_cast<int>(layerImpl->evaluateAnimations());
+#else
+ return 0;
+#endif
+}
+
+static void nativeDestroyLayer(JNIEnv *env, jobject obj, jint layer)
+{
+ if (!env)
+ return;
+ if (!layer)
+ return;
+#if USE(ACCELERATED_COMPOSITING)
+ LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer);
+ delete layerImpl;
+#endif
+}
+
static void nativeDrawCursorRing(JNIEnv *env, jobject obj, jobject canv)
{
SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv);
@@ -1767,12 +1861,6 @@ static int nativeFocusCandidateType(JNIEnv *env, jobject obj)
}
}
-static bool nativeFocusCandidateIsPlugin(JNIEnv *env, jobject obj)
-{
- const CachedNode* node = getFocusCandidate(env, obj);
- return node ? node->isPlugin() : false;
-}
-
static bool nativeFocusIsPlugin(JNIEnv *env, jobject obj)
{
const CachedNode* node = getFocusNode(env, obj);
@@ -2002,11 +2090,13 @@ static void nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj)
CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
if (!root)
return;
- const CachedNode* cursor = root->currentCursor();
- if (!cursor)
+ const CachedNode* current = root->currentCursor();
+ if (!current)
+ current = root->currentFocus();
+ if (!current)
return;
const CachedFrame* frame;
- const CachedNode* next = root->nextTextField(cursor, &frame, true);
+ const CachedNode* next = root->nextTextField(current, &frame, true);
if (!next)
return;
const WebCore::IntRect& bounds = next->bounds();
@@ -2027,7 +2117,7 @@ static jint nativeTextFieldAction(JNIEnv *env, jobject obj)
CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
if (!root)
return static_cast<jint>(CachedRoot::FAILURE);
- return static_cast<jint>(root->cursorTextFieldAction());
+ return static_cast<jint>(root->currentTextFieldAction());
}
static int nativeMoveGeneration(JNIEnv *env, jobject obj)
@@ -2131,6 +2221,16 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeDestroy },
{ "nativeDrawCursorRing", "(Landroid/graphics/Canvas;)V",
(void*) nativeDrawCursorRing },
+ { "nativeDestroyLayer", "(I)V",
+ (void*) nativeDestroyLayer },
+ { "nativeLayersHaveAnimations", "(I)Z",
+ (void*) nativeLayersHaveAnimations },
+ { "nativeEvaluateLayersAnimations", "(I)I",
+ (void*) nativeEvaluateLayersAnimations },
+ { "nativeDrawLayers", "(IFFFLandroid/graphics/Canvas;)V",
+ (void*) nativeDrawLayers },
+ { "nativeUpdateLayers", "(II)V",
+ (void*) nativeUpdateLayers },
{ "nativeDrawMatches", "(Landroid/graphics/Canvas;)V",
(void*) nativeDrawMatches },
{ "nativeDrawSelectionPointer", "(Landroid/graphics/Canvas;FIIZ)V",
@@ -2147,8 +2247,6 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeFocusCandidateFramePointer },
{ "nativeFocusCandidateIsPassword", "()Z",
(void*) nativeFocusCandidateIsPassword },
- { "nativeFocusCandidateIsPlugin", "()Z",
- (void*) nativeFocusCandidateIsPlugin },
{ "nativeFocusCandidateIsRtlText", "()Z",
(void*) nativeFocusCandidateIsRtlText },
{ "nativeFocusCandidateIsTextInput", "()Z",