Chromium Code Reviews| Index: content/browser/renderer_host/render_widget_host_view_mac_unittest.mm |
| diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm |
| index e482c755c8966ead410ed6881e340c63afa52a83..17e4afa5ece25b4ee5716817fc0d72eb78b878c8 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm |
| +++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm |
| @@ -16,7 +16,9 @@ |
| #include "base/run_loop.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/test/histogram_tester.h" |
| +#include "base/test/scoped_feature_list.h" |
| #include "base/test/simple_test_tick_clock.h" |
| +#include "base/threading/thread_task_runner_handle.h" |
| #include "content/browser/browser_thread_impl.h" |
| #include "content/browser/compositor/test/no_transport_image_transport_factory.h" |
| #include "content/browser/frame_host/render_widget_host_view_guest.h" |
| @@ -28,6 +30,7 @@ |
| #include "content/common/view_messages.h" |
| #include "content/public/browser/notification_types.h" |
| #include "content/public/browser/render_widget_host_view_mac_delegate.h" |
| +#include "content/public/common/content_features.h" |
| #include "content/public/common/content_switches.h" |
| #include "content/public/test/mock_render_process_host.h" |
| #include "content/public/test/test_browser_context.h" |
| @@ -52,6 +55,7 @@ |
| @interface MockPhaseMethods : NSObject { |
| } |
| +- (NSEventPhase)phaseNone; |
| - (NSEventPhase)phaseBegan; |
| - (NSEventPhase)phaseChanged; |
| - (NSEventPhase)phaseEnded; |
| @@ -59,6 +63,9 @@ |
| @implementation MockPhaseMethods |
| +- (NSEventPhase)phaseNone { |
| + return NSEventPhaseNone; |
| +} |
| - (NSEventPhase)phaseBegan { |
| return NSEventPhaseBegan; |
| } |
| @@ -297,6 +304,26 @@ NSEvent* MockScrollWheelEventWithPhase(SEL mockPhaseSelector, int32_t delta) { |
| return event; |
| } |
| +NSEvent* MockScrollWheelEventWithMomentumPhase(SEL mockPhaseSelector, |
| + int32_t delta) { |
| + // Create a dum event with phaseNone. This is for resetting the phase info of |
|
tdresser
2017/05/25 15:18:37
dum -> dummy?
sahel
2017/05/25 16:00:04
Done.
|
| + // CGEventRef. |
| + MockScrollWheelEventWithPhase(@selector(phaseNone), 0); |
| + CGEventRef cg_event1 = CGEventCreateScrollWheelEvent( |
|
tdresser
2017/05/25 15:18:36
Why event1 instead of just event? (and below with
sahel
2017/05/25 16:00:04
Done.
|
| + nullptr, kCGScrollEventUnitLine, 1, delta, 0); |
| + CGEventTimestamp timestamp = 0; |
| + CGEventSetTimestamp(cg_event1, timestamp); |
| + // CGEventSetIntegerValueField(cg_event1, kCGScrollWheelEventMomentumPhase, |
| + // cg_momentum_phase); |
|
tdresser
2017/05/25 15:18:36
Should these lines be removed?
sahel
2017/05/25 16:00:04
Done, I am sorry for the sloppy unittest file, I d
|
| + // CGEventSetFlags(cg_event1, static_cast<CGEventFlags>(0)); |
| + NSEvent* event1 = [NSEvent eventWithCGEvent:cg_event1]; |
| + CFRelease(cg_event1); |
| + method_setImplementation( |
| + class_getInstanceMethod([NSEvent class], @selector(momentumPhase)), |
| + [MockPhaseMethods instanceMethodForSelector:mockPhaseSelector]); |
| + return event1; |
| +} |
| + |
| } // namespace |
| class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness { |
| @@ -1308,6 +1335,177 @@ TEST_F(RenderWidgetHostViewMacTest, Background) { |
| host->ShutdownAndDestroyWidget(true); |
| } |
| +class RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest |
| + : public RenderWidgetHostViewMacTest { |
| + public: |
| + RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest() { |
| + feature_list_.InitFromCommandLine( |
| + features::kTouchpadAndWheelScrollLatching.name, ""); |
| + } |
| + |
| + private: |
| + base::test::ScopedFeatureList feature_list_; |
| +}; |
| + |
| +TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest, |
| + WheelWithPhaseEndedIsNotForwardedImmediately) { |
|
tdresser
2017/05/25 15:18:36
Can you add a comment briefly explaining why it sh
sahel
2017/05/25 16:00:04
Done.
|
| + // Initialize the view associated with a MockRenderWidgetHostImpl, rather than |
| + // the MockRenderProcessHost that is set up by the test harness which mocks |
| + // out |OnMessageReceived()|. |
| + TestBrowserContext browser_context; |
| + MockRenderProcessHost* process_host = |
| + new MockRenderProcessHost(&browser_context); |
| + process_host->Init(); |
| + MockRenderWidgetHostDelegate delegate; |
| + int32_t routing_id = process_host->GetNextRoutingID(); |
| + MockRenderWidgetHostImpl* host = |
| + new MockRenderWidgetHostImpl(&delegate, process_host, routing_id); |
| + RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Send an initial wheel event for scrolling by 3 lines. |
| + NSEvent* wheelEvent1 = |
| + MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); |
| + [view->cocoa_view() scrollWheel:wheelEvent1]; |
| + ASSERT_EQ(1U, process_host->sink().message_count()); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Indicate that the wheel event was unhandled. |
| + InputEventAck unhandled_ack(InputEventAckSource::COMPOSITOR_THREAD, |
| + blink::WebInputEvent::kMouseWheel, |
| + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| + std::unique_ptr<IPC::Message> response1( |
| + new InputHostMsg_HandleInputEvent_ACK(0, unhandled_ack)); |
| + host->OnMessageReceived(*response1); |
| + ASSERT_EQ(2U, process_host->sink().message_count()); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Send a wheel event with phaseEnded. When wheel scroll latching is enabled |
| + // the evnet will be dropped and the mouse_wheel_end_dispatch_timer_ will |
|
tdresser
2017/05/25 15:18:37
evnet -> event
sahel
2017/05/25 16:00:04
Done.
|
| + // start. |
| + NSEvent* wheelEvent2 = |
| + MockScrollWheelEventWithPhase(@selector(phaseEnded), 0); |
| + [view->cocoa_view() scrollWheel:wheelEvent2]; |
| + ASSERT_EQ(0U, process_host->sink().message_count()); |
| + DCHECK(view->mouse_wheel_end_dispatch_timer_.IsRunning()); |
| + process_host->sink().ClearMessages(); |
| + |
| + host->ShutdownAndDestroyWidget(true); |
| +} |
| + |
| +TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest, |
| + WheelWithMomentumPhaseBeganStopsTheWheelEndDispatchTimer) { |
| + // Initialize the view associated with a MockRenderWidgetHostImpl, rather than |
| + // the MockRenderProcessHost that is set up by the test harness which mocks |
| + // out |OnMessageReceived()|. |
| + TestBrowserContext browser_context; |
| + MockRenderProcessHost* process_host = |
| + new MockRenderProcessHost(&browser_context); |
| + process_host->Init(); |
| + MockRenderWidgetHostDelegate delegate; |
| + int32_t routing_id = process_host->GetNextRoutingID(); |
| + MockRenderWidgetHostImpl* host = |
| + new MockRenderWidgetHostImpl(&delegate, process_host, routing_id); |
| + RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Send an initial wheel event for scrolling by 3 lines. |
| + NSEvent* wheelEvent1 = |
| + MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); |
| + [view->cocoa_view() scrollWheel:wheelEvent1]; |
| + ASSERT_EQ(1U, process_host->sink().message_count()); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Indicate that the wheel event was unhandled. |
| + InputEventAck unhandled_ack(InputEventAckSource::COMPOSITOR_THREAD, |
| + blink::WebInputEvent::kMouseWheel, |
| + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| + std::unique_ptr<IPC::Message> response1( |
| + new InputHostMsg_HandleInputEvent_ACK(0, unhandled_ack)); |
| + host->OnMessageReceived(*response1); |
| + ASSERT_EQ(2U, process_host->sink().message_count()); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Send a wheel event with phaseEnded. When wheel scroll latching is enabled |
| + // the evnet will be dropped and the mouse_wheel_end_dispatch_timer_ will |
|
tdresser
2017/05/25 15:18:37
evnet -> event
sahel
2017/05/25 16:00:04
Done.
|
| + // start. |
| + NSEvent* wheelEvent2 = |
| + MockScrollWheelEventWithPhase(@selector(phaseEnded), 0); |
| + [view->cocoa_view() scrollWheel:wheelEvent2]; |
| + ASSERT_EQ(0U, process_host->sink().message_count()); |
| + DCHECK(view->mouse_wheel_end_dispatch_timer_.IsRunning()); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Send a wheel event with momentum phase started, this should stop the wheel |
| + // end dispatch timer. |
| + NSEvent* wheelEvent3 = |
| + MockScrollWheelEventWithMomentumPhase(@selector(phaseBegan), 3); |
| + ASSERT_TRUE(wheelEvent3); |
| + [view->cocoa_view() scrollWheel:wheelEvent3]; |
| + ASSERT_EQ(1U, process_host->sink().message_count()); |
| + DCHECK(!view->mouse_wheel_end_dispatch_timer_.IsRunning()); |
| + process_host->sink().ClearMessages(); |
| + |
| + host->ShutdownAndDestroyWidget(true); |
| +} |
| + |
| +TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest, |
| + WheelWithPhaseBeganDispatchesThePendingWheelEnd) { |
| + // Initialize the view associated with a MockRenderWidgetHostImpl, rather than |
| + // the MockRenderProcessHost that is set up by the test harness which mocks |
| + // out |OnMessageReceived()|. |
| + TestBrowserContext browser_context; |
| + MockRenderProcessHost* process_host = |
| + new MockRenderProcessHost(&browser_context); |
| + process_host->Init(); |
| + MockRenderWidgetHostDelegate delegate; |
| + int32_t routing_id = process_host->GetNextRoutingID(); |
| + MockRenderWidgetHostImpl* host = |
| + new MockRenderWidgetHostImpl(&delegate, process_host, routing_id); |
| + RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Send an initial wheel event for scrolling by 3 lines. |
| + NSEvent* wheelEvent1 = |
| + MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); |
| + [view->cocoa_view() scrollWheel:wheelEvent1]; |
| + ASSERT_EQ(1U, process_host->sink().message_count()); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Indicate that the wheel event was unhandled. |
| + InputEventAck unhandled_ack(InputEventAckSource::COMPOSITOR_THREAD, |
| + blink::WebInputEvent::kMouseWheel, |
| + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| + std::unique_ptr<IPC::Message> response1( |
| + new InputHostMsg_HandleInputEvent_ACK(0, unhandled_ack)); |
| + host->OnMessageReceived(*response1); |
| + ASSERT_EQ(2U, process_host->sink().message_count()); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Send a wheel event with phaseEnded. When wheel scroll latching is enabled |
| + // the evnet will be dropped and the mouse_wheel_end_dispatch_timer_ will |
|
tdresser
2017/05/25 15:18:36
evnet -> event
sahel
2017/05/25 16:00:04
Done.
|
| + // start. |
| + NSEvent* wheelEvent2 = |
| + MockScrollWheelEventWithPhase(@selector(phaseEnded), 0); |
| + [view->cocoa_view() scrollWheel:wheelEvent2]; |
| + ASSERT_EQ(0U, process_host->sink().message_count()); |
| + DCHECK(view->mouse_wheel_end_dispatch_timer_.IsRunning()); |
| + process_host->sink().ClearMessages(); |
| + |
| + // Send a wheel event with phase started, this should stop the wheel end |
| + // dispatch timer and dispatch the pending wheel end event for the previous |
| + // scroll sequence. |
| + NSEvent* wheelEvent3 = |
| + MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); |
| + ASSERT_TRUE(wheelEvent3); |
| + [view->cocoa_view() scrollWheel:wheelEvent3]; |
| + ASSERT_EQ(2U, process_host->sink().message_count()); |
| + DCHECK(!view->mouse_wheel_end_dispatch_timer_.IsRunning()); |
| + process_host->sink().ClearMessages(); |
| + |
| + host->ShutdownAndDestroyWidget(true); |
| +} |
| + |
| class RenderWidgetHostViewMacPinchTest : public RenderWidgetHostViewMacTest { |
| public: |
| RenderWidgetHostViewMacPinchTest() : process_host_(nullptr) {} |