Home | History | Annotate | Download | only in renderer_host
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/basictypes.h"
      6 #include "base/memory/scoped_ptr.h"
      7 #include "base/time/time.h"
      8 #include "content/browser/renderer_host/render_widget_host_delegate.h"
      9 #include "content/browser/renderer_host/smooth_scroll_gesture_controller.h"
     10 #include "content/browser/renderer_host/test_render_view_host.h"
     11 #include "content/common/view_messages.h"
     12 #include "content/port/browser/render_widget_host_view_port.h"
     13 #include "content/port/browser/smooth_scroll_gesture.h"
     14 #include "content/public/test/mock_render_process_host.h"
     15 #include "content/public/test/test_browser_context.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 #if defined(USE_AURA)
     19 #include "ui/aura/env.h"
     20 #include "ui/aura/test/test_screen.h"
     21 #endif
     22 
     23 using base::TimeDelta;
     24 
     25 namespace content {
     26 
     27 namespace {
     28 
     29 class MockSmoothScrollGesture : public SmoothScrollGesture {
     30  public:
     31   MockSmoothScrollGesture() :
     32       called_(0) {
     33   }
     34 
     35   // SmoothScrollGesture implementation:
     36   virtual bool ForwardInputEvents(base::TimeTicks now,
     37                                   RenderWidgetHost* host) OVERRIDE {
     38     ++called_;
     39     return true;
     40   }
     41 
     42   int called_;
     43 
     44  protected:
     45   virtual ~MockSmoothScrollGesture() {
     46   }
     47 };
     48 
     49 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
     50  public:
     51   MockRenderWidgetHostDelegate() {
     52   }
     53   virtual ~MockRenderWidgetHostDelegate() {}
     54 };
     55 
     56 class MockRenderWidgetHost : public RenderWidgetHostImpl {
     57  public:
     58   MockRenderWidgetHost(
     59       RenderWidgetHostDelegate* delegate,
     60       RenderProcessHost* process,
     61       int routing_id)
     62       : RenderWidgetHostImpl(delegate, process, routing_id) {
     63   }
     64   virtual ~MockRenderWidgetHost() {}
     65 };
     66 
     67 class TestView : public TestRenderWidgetHostView {
     68  public:
     69   explicit TestView(RenderWidgetHostImpl* rwh)
     70       : TestRenderWidgetHostView(rwh),
     71         mock_gesture_(NULL) {
     72   }
     73   virtual ~TestView() {}
     74 
     75   // TestRenderWidgetHostView implementation:
     76   virtual SmoothScrollGesture* CreateSmoothScrollGesture(
     77       bool scroll_down, int pixels_to_scroll, int mouse_event_x,
     78       int mouse_event_y) OVERRIDE {
     79     mock_gesture_ = new MockSmoothScrollGesture();
     80     return mock_gesture_;
     81   }
     82 
     83   virtual RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE {
     84     return rwh_;
     85   }
     86 
     87   MockSmoothScrollGesture* mock_gesture_;
     88 };
     89 
     90 class SmoothScrollGestureControllerTest : public testing::Test {
     91  public:
     92   SmoothScrollGestureControllerTest() : process_(NULL) {
     93   }
     94   virtual ~SmoothScrollGestureControllerTest() {}
     95 
     96  protected:
     97   // testing::Test implementation:
     98   virtual void SetUp() OVERRIDE {
     99     browser_context_.reset(new TestBrowserContext());
    100     delegate_.reset(new MockRenderWidgetHostDelegate());
    101     process_ = new MockRenderProcessHost(browser_context_.get());
    102 #if defined(USE_AURA)
    103     screen_.reset(aura::TestScreen::Create());
    104     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
    105 #endif
    106     host_.reset(
    107         new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
    108     view_.reset(new TestView(host_.get()));
    109     host_->SetView(view_.get());
    110     host_->Init();
    111   }
    112 
    113   virtual void TearDown() OVERRIDE {
    114     view_.reset();
    115     host_.reset();
    116     delegate_.reset();
    117     process_ = NULL;
    118     browser_context_.reset();
    119 
    120 #if defined(USE_AURA)
    121     aura::Env::DeleteInstance();
    122     screen_.reset();
    123 #endif
    124 
    125     // Process all pending tasks to avoid leaks.
    126     base::MessageLoop::current()->RunUntilIdle();
    127   }
    128 
    129   void PostQuitMessageAndRun() {
    130     // Allow the message loop to process pending synthetic scrolls, then quit.
    131     base::MessageLoop::current()->PostDelayedTask(
    132         FROM_HERE, base::MessageLoop::QuitClosure(),
    133         TimeDelta::FromMilliseconds(
    134             controller_.GetSyntheticScrollMessageInterval().InMilliseconds() *
    135             3));
    136     base::MessageLoop::current()->Run();
    137   }
    138 
    139   base::MessageLoopForUI message_loop_;
    140 
    141   scoped_ptr<TestBrowserContext> browser_context_;
    142   MockRenderProcessHost* process_;  // Deleted automatically by the widget.
    143   scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
    144   scoped_ptr<MockRenderWidgetHost> host_;
    145   scoped_ptr<TestView> view_;
    146 #if defined(USE_AURA)
    147   scoped_ptr<gfx::Screen> screen_;
    148 #endif
    149 
    150   SmoothScrollGestureController controller_;
    151 };
    152 
    153 TEST_F(SmoothScrollGestureControllerTest, Tick) {
    154   ViewHostMsg_BeginSmoothScroll_Params params;
    155   params.scroll_down = true;
    156   params.pixels_to_scroll = 10;
    157   params.mouse_event_x = 20;
    158   params.mouse_event_y = 30;
    159 
    160   // Begin a smooth scroll, |mock_gesture_| won't be |called| until we post
    161   // message.
    162   controller_.BeginSmoothScroll(view_.get(), params);
    163   EXPECT_TRUE(view_->mock_gesture_ != NULL);
    164   EXPECT_EQ(0, view_->mock_gesture_->called_);
    165 
    166   PostQuitMessageAndRun();
    167   const int current_ticks = view_->mock_gesture_->called_;
    168   EXPECT_LT(0, current_ticks);
    169 
    170   // Ensure it won't start another smooth scroll.
    171   MockSmoothScrollGesture* original_gesture = view_->mock_gesture_;
    172   controller_.BeginSmoothScroll(view_.get(), params);
    173   PostQuitMessageAndRun();
    174   EXPECT_EQ(original_gesture, view_->mock_gesture_);
    175 
    176   // Ensure the smooth scroll is ticked.
    177   PostQuitMessageAndRun();
    178   EXPECT_LT(current_ticks, view_->mock_gesture_->called_);
    179 }
    180 
    181 }  // namespace
    182 
    183 }  // namespace content
    184