Mark positioned elements as needing a relayout when checking for hit test.
This is necessary when using composited fixed layers, as the layers position
may have moved UI-side, while the webkit's related position of those layers
may not have been updated yet.

Fix Bug:2457215

Change-Id: If4f0e9c3d1a4786b29dcc7c2dc3510ba090b6a36
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index fa4a180..3571a49 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -115,6 +115,7 @@
     m_needsNotifyClient(false),
     m_haveContents(false),
     m_haveImage(false),
+    m_hasFixedLayers(false),
     m_translateX(0),
     m_translateY(0),
     m_currentTranslateX(0),
@@ -253,6 +254,13 @@
                                          offsetFromRenderer().width(),
                                          offsetFromRenderer().height(),
                                          w, h);
+
+        GraphicsLayerAndroid* rootGraphicsLayer = this;
+
+        while (rootGraphicsLayer->parent())
+            rootGraphicsLayer = static_cast<GraphicsLayerAndroid*>(rootGraphicsLayer->parent());
+
+        rootGraphicsLayer->setHasFixedLayers(true);
     }
 }
 
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 25f70b4..d0347a7 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -121,6 +121,9 @@
     void sendImmediateRepaint();
     LayerAndroid* contentLayer() { return m_contentLayer; }
 
+    bool hasFixedLayers() const { return m_hasFixedLayers; }
+    void setHasFixedLayers(bool val) { m_hasFixedLayers = val; }
+
     static int instancesCount();
 
 private:
@@ -139,6 +142,8 @@
     bool m_haveContents;
     bool m_haveImage;
 
+    bool m_hasFixedLayers;
+
     float m_translateX;
     float m_translateY;
     float m_currentTranslateX;
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 00ac725..554a835 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -1632,6 +1632,9 @@
         x, y, m_scrollOffsetX, m_scrollOffsetY);
     if (!frame || CacheBuilder::validNode(m_mainFrame, frame, NULL) == false)
         frame = m_mainFrame;
+#if USE(ACCELERATED_COMPOSITING) && ENABLE(COMPOSITED_FIXED_ELEMENTS)
+    markPositionedObjectsForLayout();
+#endif
     // mouse event expects the position in the window coordinate
     m_mousePos = WebCore::IntPoint(x - m_scrollOffsetX, y - m_scrollOffsetY);
     // validNode will still return true if the node is null, as long as we have
@@ -1979,6 +1982,9 @@
 
 bool WebViewCore::key(const PlatformKeyboardEvent& event)
 {
+#if USE(ACCELERATED_COMPOSITING) && ENABLE(COMPOSITED_FIXED_ELEMENTS)
+    markPositionedObjectsForLayout();
+#endif
     WebCore::EventHandler* eventHandler = m_mainFrame->eventHandler();
     WebCore::Node* focusNode = currentFocus();
     if (focusNode)
@@ -1990,6 +1996,9 @@
 
 // For when the user clicks the trackball
 void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node) {
+#if USE(ACCELERATED_COMPOSITING) && ENABLE(COMPOSITED_FIXED_ELEMENTS)
+    markPositionedObjectsForLayout();
+#endif
     if (!node) {
         WebCore::IntPoint pt = m_mousePos;
         pt.move(m_scrollOffsetX, m_scrollOffsetY);
@@ -2012,6 +2021,7 @@
 }
 
 #if USE(ACCELERATED_COMPOSITING)
+
 GraphicsLayerAndroid* WebViewCore::graphicsRootLayer() const
 {
     RenderView* contentRenderer = m_mainFrame->contentRenderer();
@@ -2020,7 +2030,24 @@
     return static_cast<GraphicsLayerAndroid*>(
           contentRenderer->compositor()->rootPlatformLayer());
 }
-#endif
+
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+
+// If we have composited fixed elements, we need to mark
+// fixed elements' as needing a relayout, as they could have
+// visually moved on the UI side, without that movement being
+// reflected in webkit.
+void WebViewCore::markPositionedObjectsForLayout()
+{
+    GraphicsLayerAndroid* graphicsLayer = graphicsRootLayer();
+    if (graphicsLayer && graphicsLayer->hasFixedLayers() &&
+        m_mainFrame->contentRenderer())
+        m_mainFrame->contentRenderer()->markPositionedObjectsForLayout();
+}
+
+#endif // ENABLE(COMPOSITED_FIXED_ELEMENTS)
+
+#endif // USE(ACCELERATED_COMPOSITING)
 
 bool WebViewCore::handleTouchEvent(int action, int x, int y, int metaState)
 {
@@ -2032,6 +2059,10 @@
       rootLayer->pauseDisplay(true);
 #endif
 
+#if USE(ACCELERATED_COMPOSITING) && ENABLE(COMPOSITED_FIXED_ELEMENTS)
+    markPositionedObjectsForLayout();
+#endif
+
 #if ENABLE(TOUCH_EVENTS) // Android
     WebCore::TouchEventType type = WebCore::TouchStart;
     WebCore::PlatformTouchPoint::State touchState = WebCore::PlatformTouchPoint::TouchPressed;
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 8c885e6..336ddca 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -139,6 +139,9 @@
         GraphicsLayerAndroid* graphicsRootLayer() const;
         void immediateRepaint();
         void setUIRootLayer(const LayerAndroid* layer);
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+        void markPositionedObjectsForLayout();
+#endif
 #endif
 
         /** Invalidate the view/screen, NOT the content/DOM, but expressed in