| Index: cc/trees/layer_tree_host_impl_unittest.cc | 
| diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc | 
| index b0f357bf9d49f3c4e372c92181b3a29c347744b5..b2a1b5722b3ca09d3edbfa83f244966987ec0286 100644 | 
| --- a/cc/trees/layer_tree_host_impl_unittest.cc | 
| +++ b/cc/trees/layer_tree_host_impl_unittest.cc | 
| @@ -1425,6 +1425,120 @@ TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) { | 
| .did_scroll); | 
| } | 
|  | 
| +TEST_F(LayerTreeHostImplTest, ScrollBoundaryBehaviorPreventsPropagation) { | 
| +  LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); | 
| +  host_impl_->SetViewportSize(gfx::Size(100, 100)); | 
| + | 
| +  gfx::Size overflow_size(400, 400); | 
| +  ASSERT_EQ(1u, scroll_layer->test_properties()->children.size()); | 
| +  LayerImpl* overflow = scroll_layer->test_properties()->children[0]; | 
| +  overflow->SetBounds(overflow_size); | 
| +  overflow->SetScrollable(gfx::Size(100, 100)); | 
| +  overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id())); | 
| +  overflow->layer_tree_impl() | 
| +      ->property_trees() | 
| +      ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(), | 
| +                                                     gfx::ScrollOffset()); | 
| +  overflow->SetPosition(gfx::PointF(40, 40)); | 
| +  host_impl_->active_tree()->BuildPropertyTreesForTesting(); | 
| +  scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset(30, 30)); | 
| + | 
| +  DrawFrame(); | 
| +  gfx::Point scroll_position(50, 50); | 
| + | 
| +  // ScrollBoundaryBehaviorTypeAuto shouldn't prevent scroll propagation. | 
| +  EXPECT_EQ( | 
| +      InputHandler::SCROLL_ON_IMPL_THREAD, | 
| +      host_impl_ | 
| +          ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL) | 
| +          .thread); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(30, 30), scroll_layer->CurrentScrollOffset()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->CurrentScrollOffset()); | 
| + | 
| +  gfx::Vector2dF x_dominant_delta(-10, -5); | 
| +  gfx::Vector2dF y_dominant_delta(-5, -10); | 
| +  host_impl_->ScrollBy(UpdateState(scroll_position, x_dominant_delta).get()); | 
| +  host_impl_->ScrollEnd(EndState().get()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 25), scroll_layer->CurrentScrollOffset()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); | 
| + | 
| +  overflow->test_properties()->scroll_boundary_behavior = | 
| +      ScrollBoundaryBehavior( | 
| +          ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeNone, | 
| +          ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeAuto); | 
| +  host_impl_->active_tree()->BuildPropertyTreesForTesting(); | 
| + | 
| +  DrawFrame(); | 
| + | 
| +  // ScrollBoundaryBehaviorNone on x should prevent x-dominant-scroll | 
| +  // propagation. | 
| +  EXPECT_EQ( | 
| +      InputHandler::SCROLL_ON_IMPL_THREAD, | 
| +      host_impl_ | 
| +          ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL) | 
| +          .thread); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 25), scroll_layer->CurrentScrollOffset()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); | 
| + | 
| +  host_impl_->ScrollBy(UpdateState(scroll_position, x_dominant_delta).get()); | 
| +  host_impl_->ScrollEnd(EndState().get()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 25), scroll_layer->CurrentScrollOffset()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); | 
| + | 
| +  // ScrollBoundaryBehaviorNone on x shouldn't prevent y-dominant-scroll | 
| +  // propagation. | 
| +  EXPECT_EQ( | 
| +      InputHandler::SCROLL_ON_IMPL_THREAD, | 
| +      host_impl_ | 
| +          ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL) | 
| +          .thread); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 25), scroll_layer->CurrentScrollOffset()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); | 
| + | 
| +  host_impl_->ScrollBy(UpdateState(scroll_position, y_dominant_delta).get()); | 
| +  host_impl_->ScrollEnd(EndState().get()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(15, 15), scroll_layer->CurrentScrollOffset()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); | 
| + | 
| +  overflow->test_properties()->scroll_boundary_behavior = | 
| +      ScrollBoundaryBehavior( | 
| +          ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeAuto, | 
| +          ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeNone); | 
| +  host_impl_->active_tree()->BuildPropertyTreesForTesting(); | 
| + | 
| +  DrawFrame(); | 
| + | 
| +  // ScrollBoundaryBehaviorNone on y shouldn't prevent x-dominant-scroll | 
| +  // propagation. | 
| +  EXPECT_EQ( | 
| +      InputHandler::SCROLL_ON_IMPL_THREAD, | 
| +      host_impl_ | 
| +          ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL) | 
| +          .thread); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(15, 15), scroll_layer->CurrentScrollOffset()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); | 
| + | 
| +  host_impl_->ScrollBy(UpdateState(scroll_position, x_dominant_delta).get()); | 
| +  host_impl_->ScrollEnd(EndState().get()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10), scroll_layer->CurrentScrollOffset()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); | 
| + | 
| +  // ScrollBoundaryBehaviorNone on y should prevent y-dominant-scroll | 
| +  // propagation. | 
| +  EXPECT_EQ( | 
| +      InputHandler::SCROLL_ON_IMPL_THREAD, | 
| +      host_impl_ | 
| +          ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL) | 
| +          .thread); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10), scroll_layer->CurrentScrollOffset()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); | 
| + | 
| +  host_impl_->ScrollBy(UpdateState(scroll_position, y_dominant_delta).get()); | 
| +  host_impl_->ScrollEnd(EndState().get()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10), scroll_layer->CurrentScrollOffset()); | 
| +  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); | 
| +} | 
| + | 
| TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { | 
| LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); | 
| host_impl_->SetViewportSize(gfx::Size(100, 100)); | 
|  |