/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "core/page/scrolling/ScrollingCoordinator.h"

#include "core/frame/FrameView.h"
#include "core/layout/LayoutPart.h"
#include "core/layout/LayoutView.h"
#include "core/layout/compositing/CompositedLayerMapping.h"
#include "core/layout/compositing/PaintLayerCompositor.h"
#include "core/page/Page.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/testing/URLTestHelpers.h"
#include "public/platform/Platform.h"
#include "public/platform/WebLayer.h"
#include "public/platform/WebLayerPositionConstraint.h"
#include "public/platform/WebLayerTreeView.h"
#include "public/platform/WebUnitTestSupport.h"
#include "public/web/WebSettings.h"
#include "public/web/WebViewClient.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "web/WebLocalFrameImpl.h"
#include "web/WebViewImpl.h"
#include "web/tests/FrameTestHelpers.h"

namespace blink {

class ScrollingCoordinatorTest : public testing::Test {
public:
    ScrollingCoordinatorTest()
        : m_baseURL("http://www.test.com/")
    {
        m_helper.initialize(true, 0, &m_mockWebViewClient, &configureSettings);
        webViewImpl()->resize(IntSize(320, 240));

        // OSX attaches main frame scrollbars to the VisualViewport so the VisualViewport layers need
        // to be initialized.
        webViewImpl()->updateAllLifecyclePhases();
        webViewImpl()->setRootGraphicsLayer(
            webViewImpl()->mainFrameImpl()->frame()->view()->layoutView()->compositor()->rootGraphicsLayer());
    }

    ~ScrollingCoordinatorTest() override
    {
        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
    }

    void navigateTo(const std::string& url)
    {
        FrameTestHelpers::loadFrame(webViewImpl()->mainFrame(), url);
    }

    void forceFullCompositingUpdate()
    {
        webViewImpl()->updateAllLifecyclePhases();
    }

    void registerMockedHttpURLLoad(const std::string& fileName)
    {
        URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
    }

    WebLayer* getRootScrollLayer()
    {
        PaintLayerCompositor* compositor = frame()->contentLayoutObject()->compositor();
        ASSERT(compositor);
        ASSERT(compositor->scrollLayer());

        WebLayer* webScrollLayer = compositor->scrollLayer()->platformLayer();
        return webScrollLayer;
    }

    WebViewImpl* webViewImpl() const { return m_helper.webViewImpl(); }
    LocalFrame* frame() const { return m_helper.webViewImpl()->mainFrameImpl()->frame(); }

    WebLayerTreeView* webLayerTreeView() const { return webViewImpl()->layerTreeView(); }

protected:
    std::string m_baseURL;
    FrameTestHelpers::TestWebViewClient m_mockWebViewClient;

private:
    static void configureSettings(WebSettings* settings)
    {
        settings->setJavaScriptEnabled(true);
        settings->setAcceleratedCompositingEnabled(true);
        settings->setPreferCompositingToLCDTextEnabled(true);
    }

    FrameTestHelpers::WebViewHelper m_helper;
};

TEST_F(ScrollingCoordinatorTest, fastScrollingByDefault)
{
    navigateTo("about:blank");
    forceFullCompositingUpdate();

    // Make sure the scrolling coordinator is active.
    FrameView* frameView = frame()->view();
    Page* page = frame()->page();
    ASSERT_TRUE(page->scrollingCoordinator());
    ASSERT_TRUE(page->scrollingCoordinator()->coordinatesScrollingForFrameView(frameView));

    // Fast scrolling should be enabled by default.
    WebLayer* rootScrollLayer = getRootScrollLayer();
    ASSERT_TRUE(rootScrollLayer->scrollable());
    ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread());
    ASSERT_EQ(WebEventListenerProperties::Nothing, webLayerTreeView()->eventListenerProperties(WebEventListenerClass::Touch));
    ASSERT_EQ(WebEventListenerProperties::Nothing, webLayerTreeView()->eventListenerProperties(WebEventListenerClass::MouseWheel));
}

TEST_F(ScrollingCoordinatorTest, fastScrollingCanBeDisabledWithSetting)
{
    navigateTo("about:blank");
    webViewImpl()->settings()->setThreadedScrollingEnabled(false);
    forceFullCompositingUpdate();

    // Make sure the scrolling coordinator is active.
    FrameView* frameView = frame()->view();
    Page* page = frame()->page();
    ASSERT_TRUE(page->scrollingCoordinator());
    ASSERT_TRUE(page->scrollingCoordinator()->coordinatesScrollingForFrameView(frameView));

    // Main scrolling should be enabled with the setting override.
    WebLayer* rootScrollLayer = getRootScrollLayer();
    ASSERT_TRUE(rootScrollLayer->scrollable());
    ASSERT_TRUE(rootScrollLayer->shouldScrollOnMainThread());
}


TEST_F(ScrollingCoordinatorTest, fastFractionalScrollingDiv)
{
    registerMockedHttpURLLoad("fractional-scroll-div.html");
    navigateTo(m_baseURL + "fractional-scroll-div.html");
    forceFullCompositingUpdate();

    Document* document = frame()->document();
    Element* scrollableElement = document->getElementById("scroller");
    ASSERT(scrollableElement);

    scrollableElement->setScrollTop(1.0);
    scrollableElement->setScrollLeft(1.0);
    forceFullCompositingUpdate();

    // Make sure the fractional scroll offset change 1.0 -> 1.2 gets propagated
    // to compositor.
    scrollableElement->setScrollTop(1.2);
    scrollableElement->setScrollLeft(1.2);
    forceFullCompositingUpdate();

    LayoutObject* layoutObject = scrollableElement->layoutObject();
    ASSERT_TRUE(layoutObject->isBox());
    LayoutBox* box = toLayoutBox(layoutObject);
    ASSERT_TRUE(box->usesCompositedScrolling());
    CompositedLayerMapping* compositedLayerMapping = box->layer()->compositedLayerMapping();
    ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer());
    ASSERT(compositedLayerMapping->scrollingContentsLayer());
    WebLayer* webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer();
    ASSERT_TRUE(webScrollLayer);
    ASSERT_NEAR(1.2, webScrollLayer->scrollPositionDouble().x, 0.01);
    ASSERT_NEAR(1.2, webScrollLayer->scrollPositionDouble().y, 0.01);
}

static WebLayer* webLayerFromElement(Element* element)
{
    if (!element)
        return 0;
    LayoutObject* layoutObject = element->layoutObject();
    if (!layoutObject || !layoutObject->isBoxModelObject())
        return 0;
    PaintLayer* layer = toLayoutBoxModelObject(layoutObject)->layer();
    if (!layer)
        return 0;
    if (!layer->hasCompositedLayerMapping())
        return 0;
    CompositedLayerMapping* compositedLayerMapping = layer->compositedLayerMapping();
    GraphicsLayer* graphicsLayer = compositedLayerMapping->mainGraphicsLayer();
    if (!graphicsLayer)
        return 0;
    return graphicsLayer->platformLayer();
}


TEST_F(ScrollingCoordinatorTest, fractionalScrollingNonLayerFixedPosition)
{
    registerMockedHttpURLLoad("fractional-scroll-fixed-position.html");
    navigateTo(m_baseURL + "fractional-scroll-fixed-position.html");
    // Prevent fixed-position element from getting its own layer.
    webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false);
    forceFullCompositingUpdate();

    FrameView* frameView = frame()->view();
    frameView->scrollTo(DoublePoint(1.5, 1.5));
    WebLayer* rootScrollLayer = getRootScrollLayer();
    // Scroll on main if there is non-composited fixed position element.
    // And the containing scroll layer should not get fractional scroll offset.
    ASSERT_TRUE(rootScrollLayer->shouldScrollOnMainThread());
    ASSERT_EQ(1.0, rootScrollLayer->scrollPositionDouble().x);
    ASSERT_EQ(1.0, rootScrollLayer->scrollPositionDouble().y);
    ASSERT_EQ(0.0, rootScrollLayer->position().x);
    ASSERT_EQ(0.0, rootScrollLayer->position().y);
}

TEST_F(ScrollingCoordinatorTest, fastScrollingForFixedPosition)
{
    registerMockedHttpURLLoad("fixed-position.html");
    navigateTo(m_baseURL + "fixed-position.html");
    forceFullCompositingUpdate();

    // Fixed position should not fall back to main thread scrolling.
    WebLayer* rootScrollLayer = getRootScrollLayer();
    ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread());

    Document* document = frame()->document();
    {
        Element* element = document->getElementById("div-tl");
        ASSERT_TRUE(element);
        WebLayer* layer = webLayerFromElement(element);
        ASSERT_TRUE(layer);
        WebLayerPositionConstraint constraint = layer->positionConstraint();
        ASSERT_TRUE(constraint.isFixedPosition);
        ASSERT_TRUE(!constraint.isFixedToRightEdge && !constraint.isFixedToBottomEdge);
    }
    {
        Element* element = document->getElementById("div-tr");
        ASSERT_TRUE(element);
        WebLayer* layer = webLayerFromElement(element);
        ASSERT_TRUE(layer);
        WebLayerPositionConstraint constraint = layer->positionConstraint();
        ASSERT_TRUE(constraint.isFixedPosition);
        ASSERT_TRUE(constraint.isFixedToRightEdge && !constraint.isFixedToBottomEdge);
    }
    {
        Element* element = document->getElementById("div-bl");
        ASSERT_TRUE(element);
        WebLayer* layer = webLayerFromElement(element);
        ASSERT_TRUE(layer);
        WebLayerPositionConstraint constraint = layer->positionConstraint();
        ASSERT_TRUE(constraint.isFixedPosition);
        ASSERT_TRUE(!constraint.isFixedToRightEdge && constraint.isFixedToBottomEdge);
    }
    {
        Element* element = document->getElementById("div-br");
        ASSERT_TRUE(element);
        WebLayer* layer = webLayerFromElement(element);
        ASSERT_TRUE(layer);
        WebLayerPositionConstraint constraint = layer->positionConstraint();
        ASSERT_TRUE(constraint.isFixedPosition);
        ASSERT_TRUE(constraint.isFixedToRightEdge && constraint.isFixedToBottomEdge);
    }
    {
        Element* element = document->getElementById("span-tl");
        ASSERT_TRUE(element);
        WebLayer* layer = webLayerFromElement(element);
        ASSERT_TRUE(layer);
        WebLayerPositionConstraint constraint = layer->positionConstraint();
        ASSERT_TRUE(constraint.isFixedPosition);
        ASSERT_TRUE(!constraint.isFixedToRightEdge && !constraint.isFixedToBottomEdge);
    }
    {
        Element* element = document->getElementById("span-tr");
        ASSERT_TRUE(element);
        WebLayer* layer = webLayerFromElement(element);
        ASSERT_TRUE(layer);
        WebLayerPositionConstraint constraint = layer->positionConstraint();
        ASSERT_TRUE(constraint.isFixedPosition);
        ASSERT_TRUE(constraint.isFixedToRightEdge && !constraint.isFixedToBottomEdge);
    }
    {
        Element* element = document->getElementById("span-bl");
        ASSERT_TRUE(element);
        WebLayer* layer = webLayerFromElement(element);
        ASSERT_TRUE(layer);
        WebLayerPositionConstraint constraint = layer->positionConstraint();
        ASSERT_TRUE(constraint.isFixedPosition);
        ASSERT_TRUE(!constraint.isFixedToRightEdge && constraint.isFixedToBottomEdge);
    }
    {
        Element* element = document->getElementById("span-br");
        ASSERT_TRUE(element);
        WebLayer* layer = webLayerFromElement(element);
        ASSERT_TRUE(layer);
        WebLayerPositionConstraint constraint = layer->positionConstraint();
        ASSERT_TRUE(constraint.isFixedPosition);
        ASSERT_TRUE(constraint.isFixedToRightEdge && constraint.isFixedToBottomEdge);
    }
}

TEST_F(ScrollingCoordinatorTest, touchEventHandler)
{
    registerMockedHttpURLLoad("touch-event-handler.html");
    navigateTo(m_baseURL + "touch-event-handler.html");
    forceFullCompositingUpdate();

    ASSERT_EQ(WebEventListenerProperties::Blocking, webLayerTreeView()->eventListenerProperties(WebEventListenerClass::Touch));
}

TEST_F(ScrollingCoordinatorTest, touchEventHandlerPassive)
{
    registerMockedHttpURLLoad("touch-event-handler-passive.html");
    navigateTo(m_baseURL + "touch-event-handler-passive.html");
    forceFullCompositingUpdate();

    ASSERT_EQ(WebEventListenerProperties::Passive, webLayerTreeView()->eventListenerProperties(WebEventListenerClass::Touch));
}

TEST_F(ScrollingCoordinatorTest, touchEventHandlerBoth)
{
    registerMockedHttpURLLoad("touch-event-handler-both.html");
    navigateTo(m_baseURL + "touch-event-handler-both.html");
    forceFullCompositingUpdate();

    ASSERT_EQ(WebEventListenerProperties::Blocking, webLayerTreeView()->eventListenerProperties(WebEventListenerClass::Touch));
}

TEST_F(ScrollingCoordinatorTest, wheelEventHandler)
{
    registerMockedHttpURLLoad("wheel-event-handler.html");
    navigateTo(m_baseURL + "wheel-event-handler.html");
    forceFullCompositingUpdate();

    ASSERT_EQ(WebEventListenerProperties::Blocking, webLayerTreeView()->eventListenerProperties(WebEventListenerClass::MouseWheel));
}

TEST_F(ScrollingCoordinatorTest, wheelEventHandlerPassive)
{
    registerMockedHttpURLLoad("wheel-event-handler-passive.html");
    navigateTo(m_baseURL + "wheel-event-handler-passive.html");
    forceFullCompositingUpdate();

    ASSERT_EQ(WebEventListenerProperties::Passive, webLayerTreeView()->eventListenerProperties(WebEventListenerClass::MouseWheel));
}

TEST_F(ScrollingCoordinatorTest, wheelEventHandlerBoth)
{
    registerMockedHttpURLLoad("wheel-event-handler-both.html");
    navigateTo(m_baseURL + "wheel-event-handler-both.html");
    forceFullCompositingUpdate();

    ASSERT_EQ(WebEventListenerProperties::Blocking, webLayerTreeView()->eventListenerProperties(WebEventListenerClass::MouseWheel));
}

TEST_F(ScrollingCoordinatorTest, scrollEventHandler)
{
    registerMockedHttpURLLoad("scroll-event-handler.html");
    navigateTo(m_baseURL + "scroll-event-handler.html");
    forceFullCompositingUpdate();

    ASSERT_TRUE(webLayerTreeView()->haveScrollEventHandlers());
}

TEST_F(ScrollingCoordinatorTest, updateEventHandlersDuringTeardown)
{
    registerMockedHttpURLLoad("scroll-event-handler-window.html");
    navigateTo(m_baseURL + "scroll-event-handler-window.html");
    forceFullCompositingUpdate();

    // Simulate detaching the document from its DOM window. This should not
    // cause a crash when the WebViewImpl is closed by the test runner.
    frame()->document()->detach();
}

TEST_F(ScrollingCoordinatorTest, clippedBodyTest)
{
    registerMockedHttpURLLoad("clipped-body.html");
    navigateTo(m_baseURL + "clipped-body.html");
    forceFullCompositingUpdate();

    WebLayer* rootScrollLayer = getRootScrollLayer();
    ASSERT_EQ(0u, rootScrollLayer->nonFastScrollableRegion().size());
}

TEST_F(ScrollingCoordinatorTest, overflowScrolling)
{
    registerMockedHttpURLLoad("overflow-scrolling.html");
    navigateTo(m_baseURL + "overflow-scrolling.html");
    forceFullCompositingUpdate();

    // Verify the properties of the accelerated scrolling element starting from the LayoutObject
    // all the way to the WebLayer.
    Element* scrollableElement = frame()->document()->getElementById("scrollable");
    ASSERT(scrollableElement);

    LayoutObject* layoutObject = scrollableElement->layoutObject();
    ASSERT_TRUE(layoutObject->isBox());
    ASSERT_TRUE(layoutObject->hasLayer());

    LayoutBox* box = toLayoutBox(layoutObject);
    ASSERT_TRUE(box->usesCompositedScrolling());
    ASSERT_EQ(PaintsIntoOwnBacking, box->layer()->compositingState());

    CompositedLayerMapping* compositedLayerMapping = box->layer()->compositedLayerMapping();
    ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer());
    ASSERT(compositedLayerMapping->scrollingContentsLayer());

    GraphicsLayer* graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
    ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea());

    WebLayer* webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer();
    ASSERT_TRUE(webScrollLayer->scrollable());
    ASSERT_TRUE(webScrollLayer->userScrollableHorizontal());
    ASSERT_TRUE(webScrollLayer->userScrollableVertical());

#if OS(ANDROID)
    // Now verify we've attached impl-side scrollbars onto the scrollbar layers
    ASSERT_TRUE(compositedLayerMapping->layerForHorizontalScrollbar());
    ASSERT_TRUE(compositedLayerMapping->layerForHorizontalScrollbar()->hasContentsLayer());
    ASSERT_TRUE(compositedLayerMapping->layerForVerticalScrollbar());
    ASSERT_TRUE(compositedLayerMapping->layerForVerticalScrollbar()->hasContentsLayer());
#endif
}

TEST_F(ScrollingCoordinatorTest, overflowHidden)
{
    registerMockedHttpURLLoad("overflow-hidden.html");
    navigateTo(m_baseURL + "overflow-hidden.html");
    forceFullCompositingUpdate();

    // Verify the properties of the accelerated scrolling element starting from the LayoutObject
    // all the way to the WebLayer.
    Element* overflowElement = frame()->document()->getElementById("unscrollable-y");
    ASSERT(overflowElement);

    LayoutObject* layoutObject = overflowElement->layoutObject();
    ASSERT_TRUE(layoutObject->isBox());
    ASSERT_TRUE(layoutObject->hasLayer());

    LayoutBox* box = toLayoutBox(layoutObject);
    ASSERT_TRUE(box->usesCompositedScrolling());
    ASSERT_EQ(PaintsIntoOwnBacking, box->layer()->compositingState());

    CompositedLayerMapping* compositedLayerMapping = box->layer()->compositedLayerMapping();
    ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer());
    ASSERT(compositedLayerMapping->scrollingContentsLayer());

    GraphicsLayer* graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
    ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea());

    WebLayer* webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer();
    ASSERT_TRUE(webScrollLayer->scrollable());
    ASSERT_TRUE(webScrollLayer->userScrollableHorizontal());
    ASSERT_FALSE(webScrollLayer->userScrollableVertical());

    overflowElement = frame()->document()->getElementById("unscrollable-x");
    ASSERT(overflowElement);

    layoutObject = overflowElement->layoutObject();
    ASSERT_TRUE(layoutObject->isBox());
    ASSERT_TRUE(layoutObject->hasLayer());

    box = toLayoutBox(layoutObject);
    ASSERT_TRUE(box->scrollableArea()->usesCompositedScrolling());
    ASSERT_EQ(PaintsIntoOwnBacking, box->layer()->compositingState());

    compositedLayerMapping = box->layer()->compositedLayerMapping();
    ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer());
    ASSERT(compositedLayerMapping->scrollingContentsLayer());

    graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
    ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea());

    webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer();
    ASSERT_TRUE(webScrollLayer->scrollable());
    ASSERT_FALSE(webScrollLayer->userScrollableHorizontal());
    ASSERT_TRUE(webScrollLayer->userScrollableVertical());
}

TEST_F(ScrollingCoordinatorTest, iframeScrolling)
{
    registerMockedHttpURLLoad("iframe-scrolling.html");
    registerMockedHttpURLLoad("iframe-scrolling-inner.html");
    navigateTo(m_baseURL + "iframe-scrolling.html");
    forceFullCompositingUpdate();

    // Verify the properties of the accelerated scrolling element starting from the LayoutObject
    // all the way to the WebLayer.
    Element* scrollableFrame = frame()->document()->getElementById("scrollable");
    ASSERT_TRUE(scrollableFrame);

    LayoutObject* layoutObject = scrollableFrame->layoutObject();
    ASSERT_TRUE(layoutObject);
    ASSERT_TRUE(layoutObject->isLayoutPart());

    LayoutPart* layoutPart = toLayoutPart(layoutObject);
    ASSERT_TRUE(layoutPart);
    ASSERT_TRUE(layoutPart->widget());
    ASSERT_TRUE(layoutPart->widget()->isFrameView());

    FrameView* innerFrameView = toFrameView(layoutPart->widget());
    LayoutView* innerLayoutView = innerFrameView->layoutView();
    ASSERT_TRUE(innerLayoutView);

    PaintLayerCompositor* innerCompositor = innerLayoutView->compositor();
    ASSERT_TRUE(innerCompositor->inCompositingMode());
    ASSERT_TRUE(innerCompositor->scrollLayer());

    GraphicsLayer* scrollLayer = innerCompositor->scrollLayer();
    ASSERT_EQ(innerFrameView, scrollLayer->scrollableArea());

    WebLayer* webScrollLayer = scrollLayer->platformLayer();
    ASSERT_TRUE(webScrollLayer->scrollable());

#if OS(ANDROID)
    // Now verify we've attached impl-side scrollbars onto the scrollbar layers
    ASSERT_TRUE(innerCompositor->layerForHorizontalScrollbar());
    ASSERT_TRUE(innerCompositor->layerForHorizontalScrollbar()->hasContentsLayer());
    ASSERT_TRUE(innerCompositor->layerForVerticalScrollbar());
    ASSERT_TRUE(innerCompositor->layerForVerticalScrollbar()->hasContentsLayer());
#endif
}

TEST_F(ScrollingCoordinatorTest, rtlIframe)
{
    registerMockedHttpURLLoad("rtl-iframe.html");
    registerMockedHttpURLLoad("rtl-iframe-inner.html");
    navigateTo(m_baseURL + "rtl-iframe.html");
    forceFullCompositingUpdate();

    // Verify the properties of the accelerated scrolling element starting from the LayoutObject
    // all the way to the WebLayer.
    Element* scrollableFrame = frame()->document()->getElementById("scrollable");
    ASSERT_TRUE(scrollableFrame);

    LayoutObject* layoutObject = scrollableFrame->layoutObject();
    ASSERT_TRUE(layoutObject);
    ASSERT_TRUE(layoutObject->isLayoutPart());

    LayoutPart* layoutPart = toLayoutPart(layoutObject);
    ASSERT_TRUE(layoutPart);
    ASSERT_TRUE(layoutPart->widget());
    ASSERT_TRUE(layoutPart->widget()->isFrameView());

    FrameView* innerFrameView = toFrameView(layoutPart->widget());
    LayoutView* innerLayoutView = innerFrameView->layoutView();
    ASSERT_TRUE(innerLayoutView);

    PaintLayerCompositor* innerCompositor = innerLayoutView->compositor();
    ASSERT_TRUE(innerCompositor->inCompositingMode());
    ASSERT_TRUE(innerCompositor->scrollLayer());

    GraphicsLayer* scrollLayer = innerCompositor->scrollLayer();
    ASSERT_EQ(innerFrameView, scrollLayer->scrollableArea());

    WebLayer* webScrollLayer = scrollLayer->platformLayer();
    ASSERT_TRUE(webScrollLayer->scrollable());

    int expectedScrollPosition = 958 + (innerFrameView->verticalScrollbar()->isOverlayScrollbar() ? 0 : 15);
    ASSERT_EQ(expectedScrollPosition, webScrollLayer->scrollPositionDouble().x);
}

TEST_F(ScrollingCoordinatorTest, setupScrollbarLayerShouldNotCrash)
{
    registerMockedHttpURLLoad("setup_scrollbar_layer_crash.html");
    navigateTo(m_baseURL + "setup_scrollbar_layer_crash.html");
    forceFullCompositingUpdate();
    // This test document setup an iframe with scrollbars, then switch to
    // an empty document by javascript.
}

TEST_F(ScrollingCoordinatorTest, scrollbarsForceMainThreadOrHaveWebScrollbarLayer)
{
    registerMockedHttpURLLoad("trivial-scroller.html");
    navigateTo(m_baseURL + "trivial-scroller.html");
    forceFullCompositingUpdate();

    Document* document = frame()->document();
    Element* scrollableElement = document->getElementById("scroller");
    ASSERT(scrollableElement);

    LayoutObject* layoutObject = scrollableElement->layoutObject();
    ASSERT_TRUE(layoutObject->isBox());
    LayoutBox* box = toLayoutBox(layoutObject);
    ASSERT_TRUE(box->usesCompositedScrolling());
    CompositedLayerMapping* compositedLayerMapping = box->layer()->compositedLayerMapping();
    GraphicsLayer* scrollbarGraphicsLayer = compositedLayerMapping->layerForVerticalScrollbar();
    ASSERT_TRUE(scrollbarGraphicsLayer);

    bool hasWebScrollbarLayer = !scrollbarGraphicsLayer->drawsContent();
    ASSERT_TRUE(hasWebScrollbarLayer || scrollbarGraphicsLayer->platformLayer()->shouldScrollOnMainThread());
}

#if OS(MACOSX) || OS(ANDROID)
TEST_F(ScrollingCoordinatorTest, DISABLED_setupScrollbarLayerShouldSetScrollLayerOpaque)
#else
TEST_F(ScrollingCoordinatorTest, setupScrollbarLayerShouldSetScrollLayerOpaque)
#endif
{
    registerMockedHttpURLLoad("wide_document.html");
    navigateTo(m_baseURL + "wide_document.html");
    forceFullCompositingUpdate();

    FrameView* frameView = frame()->view();
    ASSERT_TRUE(frameView);

    GraphicsLayer* scrollbarGraphicsLayer = frameView->layerForHorizontalScrollbar();
    ASSERT_TRUE(scrollbarGraphicsLayer);

    WebLayer* platformLayer = scrollbarGraphicsLayer->platformLayer();
    ASSERT_TRUE(platformLayer);

    WebLayer* contentsLayer = scrollbarGraphicsLayer->contentsLayer();
    ASSERT_TRUE(contentsLayer);

    // After scrollableAreaScrollbarLayerDidChange,
    // if the main frame's scrollbarLayer is opaque,
    // contentsLayer should be opaque too.
    ASSERT_EQ(platformLayer->opaque(), contentsLayer->opaque());
}

TEST_F(ScrollingCoordinatorTest, FixedPositionLosingBackingShouldTriggerMainThreadScroll)
{
    webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false);
    registerMockedHttpURLLoad("fixed-position-losing-backing.html");
    navigateTo(m_baseURL + "fixed-position-losing-backing.html");
    forceFullCompositingUpdate();

    WebLayer* scrollLayer = frame()->page()->deprecatedLocalMainFrame()->view()->layerForScrolling()->platformLayer();
    Document* document = frame()->document();
    Element* fixedPos = document->getElementById("fixed");

    EXPECT_TRUE(static_cast<LayoutBoxModelObject*>(fixedPos->layoutObject())->layer()->hasCompositedLayerMapping());
    EXPECT_FALSE(scrollLayer->shouldScrollOnMainThread());

    fixedPos->setInlineStyleProperty(CSSPropertyTransform, CSSValueNone);
    forceFullCompositingUpdate();

    EXPECT_FALSE(static_cast<LayoutBoxModelObject*>(fixedPos->layoutObject())->layer()->hasCompositedLayerMapping());
    EXPECT_TRUE(scrollLayer->shouldScrollOnMainThread());
}

} // namespace blink
