| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" |
| 6 | 6 |
| 7 #include <Cocoa/Cocoa.h> | 7 #include <Cocoa/Cocoa.h> |
| 8 | 8 |
| 9 #include "base/mac/mac_util.h" | 9 #include "base/mac/mac_util.h" |
| 10 #include "base/mac/scoped_nsautorelease_pool.h" | 10 #include "base/mac/scoped_nsautorelease_pool.h" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 - (BOOL)canRubberbandRight:(NSView*)view { | 85 - (BOOL)canRubberbandRight:(NSView*)view { |
| 86 return true; | 86 return true; |
| 87 } | 87 } |
| 88 | 88 |
| 89 @end | 89 @end |
| 90 | 90 |
| 91 namespace content { | 91 namespace content { |
| 92 | 92 |
| 93 namespace { | 93 namespace { |
| 94 | 94 |
| 95 id MockGestureEvent( | 95 id MockGestureEvent(NSEventType type, double magnification) { |
| 96 NSEventType type, NSTimeInterval timestamp, double magnification) { | |
| 97 id event = [OCMockObject mockForClass:[NSEvent class]]; | 96 id event = [OCMockObject mockForClass:[NSEvent class]]; |
| 98 NSPoint locationInWindow = NSMakePoint(0, 0); | 97 NSPoint locationInWindow = NSMakePoint(0, 0); |
| 99 CGFloat deltaX = 0; | 98 CGFloat deltaX = 0; |
| 100 CGFloat deltaY = 0; | 99 CGFloat deltaY = 0; |
| 100 NSTimeInterval timestamp = 1; |
| 101 NSUInteger modifierFlags = 0; | 101 NSUInteger modifierFlags = 0; |
| 102 |
| 102 [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type]; | 103 [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type]; |
| 103 [(NSEvent*)[[event stub] | 104 [(NSEvent*)[[event stub] |
| 104 andReturnValue:OCMOCK_VALUE(locationInWindow)] locationInWindow]; | 105 andReturnValue:OCMOCK_VALUE(locationInWindow)] locationInWindow]; |
| 105 [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaX)] deltaX]; | 106 [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaX)] deltaX]; |
| 106 [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaY)] deltaY]; | 107 [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaY)] deltaY]; |
| 107 [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(timestamp)] timestamp]; | 108 [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(timestamp)] timestamp]; |
| 108 [(NSEvent*)[[event stub] | 109 [(NSEvent*)[[event stub] |
| 109 andReturnValue:OCMOCK_VALUE(modifierFlags)] modifierFlags]; | 110 andReturnValue:OCMOCK_VALUE(modifierFlags)] modifierFlags]; |
| 110 [(NSEvent*)[[event stub] | 111 [(NSEvent*)[[event stub] |
| 111 andReturnValue:OCMOCK_VALUE(magnification)] magnification]; | 112 andReturnValue:OCMOCK_VALUE(magnification)] magnification]; |
| (...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 859 EXPECT_TRUE([view->cocoa_view() isOpaque]); | 860 EXPECT_TRUE([view->cocoa_view() isOpaque]); |
| 860 set_background = process_host->sink().GetUniqueMessageMatching( | 861 set_background = process_host->sink().GetUniqueMessageMatching( |
| 861 ViewMsg_SetBackgroundOpaque::ID); | 862 ViewMsg_SetBackgroundOpaque::ID); |
| 862 ASSERT_TRUE(set_background); | 863 ASSERT_TRUE(set_background); |
| 863 ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background); | 864 ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background); |
| 864 EXPECT_TRUE(get<0>(sent_background)); | 865 EXPECT_TRUE(get<0>(sent_background)); |
| 865 | 866 |
| 866 host->Shutdown(); | 867 host->Shutdown(); |
| 867 } | 868 } |
| 868 | 869 |
| 869 TEST_F(RenderWidgetHostViewMacTest, PinchThresholding) { | 870 class RenderWidgetHostViewMacPinchTest : public RenderWidgetHostViewMacTest { |
| 871 public: |
| 872 RenderWidgetHostViewMacPinchTest() : process_host_(NULL) {} |
| 873 |
| 874 bool ZoomDisabledForPinchUpdateMessage() { |
| 875 const IPC::Message* message = NULL; |
| 876 // The first message may be a PinchBegin. Go for the second message if |
| 877 // there are two. |
| 878 switch (process_host_->sink().message_count()) { |
| 879 case 1: |
| 880 message = process_host_->sink().GetMessageAt(0); |
| 881 break; |
| 882 case 2: |
| 883 message = process_host_->sink().GetMessageAt(1); |
| 884 break; |
| 885 default: |
| 886 NOTREACHED(); |
| 887 break; |
| 888 } |
| 889 DCHECK(message); |
| 890 Tuple<IPC::WebInputEventPointer, ui::LatencyInfo, bool> data; |
| 891 InputMsg_HandleInputEvent::Read(message, &data); |
| 892 IPC::WebInputEventPointer ipc_event = get<0>(data); |
| 893 const blink::WebGestureEvent* gesture_event = |
| 894 static_cast<const blink::WebGestureEvent*>(ipc_event); |
| 895 return gesture_event->data.pinchUpdate.zoomDisabled; |
| 896 } |
| 897 |
| 898 MockRenderProcessHost* process_host_; |
| 899 }; |
| 900 |
| 901 TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) { |
| 870 // This tests Lion+ functionality, so don't run the test pre-Lion. | 902 // This tests Lion+ functionality, so don't run the test pre-Lion. |
| 871 if (!base::mac::IsOSLionOrLater()) | 903 if (!base::mac::IsOSLionOrLater()) |
| 872 return; | 904 return; |
| 873 | 905 |
| 874 // Initialize the view associated with a MockRenderWidgetHostImpl, rather than | 906 // Initialize the view associated with a MockRenderWidgetHostImpl, rather than |
| 875 // the MockRenderProcessHost that is set up by the test harness which mocks | 907 // the MockRenderProcessHost that is set up by the test harness which mocks |
| 876 // out |OnMessageReceived()|. | 908 // out |OnMessageReceived()|. |
| 877 TestBrowserContext browser_context; | 909 TestBrowserContext browser_context; |
| 878 MockRenderProcessHost* process_host = | 910 process_host_ = new MockRenderProcessHost(&browser_context); |
| 879 new MockRenderProcessHost(&browser_context); | |
| 880 MockRenderWidgetHostDelegate delegate; | 911 MockRenderWidgetHostDelegate delegate; |
| 881 MockRenderWidgetHostImpl* host = new MockRenderWidgetHostImpl( | 912 MockRenderWidgetHostImpl* host = new MockRenderWidgetHostImpl( |
| 882 &delegate, process_host, MSG_ROUTING_NONE); | 913 &delegate, process_host_, MSG_ROUTING_NONE); |
| 883 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false); | 914 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false); |
| 884 | 915 |
| 885 // We'll use this IPC message to ack events. | 916 // We'll use this IPC message to ack events. |
| 886 InputHostMsg_HandleInputEvent_ACK_Params ack; | 917 InputHostMsg_HandleInputEvent_ACK_Params ack; |
| 887 ack.type = blink::WebInputEvent::GesturePinchUpdate; | 918 ack.type = blink::WebInputEvent::GesturePinchUpdate; |
| 888 ack.state = INPUT_EVENT_ACK_STATE_CONSUMED; | 919 ack.state = INPUT_EVENT_ACK_STATE_CONSUMED; |
| 889 scoped_ptr<IPC::Message> response( | 920 scoped_ptr<IPC::Message> response( |
| 890 new InputHostMsg_HandleInputEvent_ACK(0, ack)); | 921 new InputHostMsg_HandleInputEvent_ACK(0, ack)); |
| 891 | 922 |
| 892 // Do a gesture that crosses the threshold. | 923 // Do a gesture that crosses the threshold. |
| 893 { | 924 { |
| 894 NSEvent* pinchBeginEvent = | 925 NSEvent* pinchBeginEvent = |
| 895 MockGestureEvent(NSEventTypeBeginGesture, 100.1, 0); | 926 MockGestureEvent(NSEventTypeBeginGesture, 0); |
| 896 NSEvent* pinchUpdateEvents[3] = { | 927 NSEvent* pinchUpdateEvents[3] = { |
| 897 MockGestureEvent(NSEventTypeMagnify, 100.2, 0.25), | 928 MockGestureEvent(NSEventTypeMagnify, 0.25), |
| 898 MockGestureEvent(NSEventTypeMagnify, 100.3, 0.25), | 929 MockGestureEvent(NSEventTypeMagnify, 0.25), |
| 899 MockGestureEvent(NSEventTypeMagnify, 100.4, 0.25), | 930 MockGestureEvent(NSEventTypeMagnify, 0.25), |
| 900 }; | 931 }; |
| 901 NSEvent* pinchEndEvent = | 932 NSEvent* pinchEndEvent = |
| 902 MockGestureEvent(NSEventTypeEndGesture, 100.5, 0); | 933 MockGestureEvent(NSEventTypeEndGesture, 0); |
| 903 | 934 |
| 904 // No messages are sent for the pinch begin and the first update event. | |
| 905 [view->cocoa_view() beginGestureWithEvent:pinchBeginEvent]; | 935 [view->cocoa_view() beginGestureWithEvent:pinchBeginEvent]; |
| 936 EXPECT_EQ(0U, process_host_->sink().message_count()); |
| 937 |
| 938 // No zoom is sent for the first update event. |
| 906 [view->cocoa_view() magnifyWithEvent:pinchUpdateEvents[0]]; | 939 [view->cocoa_view() magnifyWithEvent:pinchUpdateEvents[0]]; |
| 907 ASSERT_EQ(0U, process_host->sink().message_count()); | 940 host->OnMessageReceived(*response); |
| 941 EXPECT_EQ(2U, process_host_->sink().message_count()); |
| 942 EXPECT_TRUE(ZoomDisabledForPinchUpdateMessage()); |
| 943 process_host_->sink().ClearMessages(); |
| 908 | 944 |
| 909 // The second update event crosses the threshold of 0.4, and so a begin | 945 // The second update event crosses the threshold of 0.4, and so zoom is no |
| 910 // and update are sent. | 946 // longer disabled. |
| 911 [view->cocoa_view() magnifyWithEvent:pinchUpdateEvents[1]]; | 947 [view->cocoa_view() magnifyWithEvent:pinchUpdateEvents[1]]; |
| 912 ASSERT_EQ(2U, process_host->sink().message_count()); | 948 EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage()); |
| 913 host->OnMessageReceived(*response); | 949 host->OnMessageReceived(*response); |
| 950 EXPECT_EQ(1U, process_host_->sink().message_count()); |
| 951 process_host_->sink().ClearMessages(); |
| 914 | 952 |
| 915 // The third update only causes one event to be sent. | 953 // The third update still has zoom enabled. |
| 916 [view->cocoa_view() magnifyWithEvent:pinchUpdateEvents[2]]; | 954 [view->cocoa_view() magnifyWithEvent:pinchUpdateEvents[2]]; |
| 917 ASSERT_EQ(3U, process_host->sink().message_count()); | 955 EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage()); |
| 918 host->OnMessageReceived(*response); | 956 host->OnMessageReceived(*response); |
| 957 EXPECT_EQ(1U, process_host_->sink().message_count()); |
| 958 process_host_->sink().ClearMessages(); |
| 919 | 959 |
| 920 // As does the end. | |
| 921 [view->cocoa_view() endGestureWithEvent:pinchEndEvent]; | 960 [view->cocoa_view() endGestureWithEvent:pinchEndEvent]; |
| 922 ASSERT_EQ(4U, process_host->sink().message_count()); | 961 EXPECT_EQ(1U, process_host_->sink().message_count()); |
| 923 | 962 process_host_->sink().ClearMessages(); |
| 924 process_host->sink().ClearMessages(); | |
| 925 } | 963 } |
| 926 | 964 |
| 927 // Do a gesture that doesn't cross the threshold, but happens within 1 second, | 965 // Do a gesture that doesn't cross the threshold, but happens when we're not |
| 928 // so it should be sent to the renderer. | 966 // at page scale factor one, so it should be sent to the renderer. |
| 929 { | 967 { |
| 930 NSEvent* pinchBeginEvent = | 968 NSEvent* pinchBeginEvent = MockGestureEvent(NSEventTypeBeginGesture, 0); |
| 931 MockGestureEvent(NSEventTypeBeginGesture, 101.0, 0); | 969 NSEvent* pinchUpdateEvent = MockGestureEvent(NSEventTypeMagnify, 0.25); |
| 932 NSEvent* pinchUpdateEvent = | 970 NSEvent* pinchEndEvent = MockGestureEvent(NSEventTypeEndGesture, 0); |
| 933 MockGestureEvent(NSEventTypeMagnify, 101.1, 0.25); | |
| 934 NSEvent* pinchEndEvent = | |
| 935 MockGestureEvent(NSEventTypeEndGesture, 101.2, 0); | |
| 936 | 971 |
| 937 // No message comes for the begin event. | 972 view->page_is_at_scale_one_ = false; |
| 973 |
| 938 [view->cocoa_view() beginGestureWithEvent:pinchBeginEvent]; | 974 [view->cocoa_view() beginGestureWithEvent:pinchBeginEvent]; |
| 939 ASSERT_EQ(0U, process_host->sink().message_count()); | 975 EXPECT_EQ(0U, process_host_->sink().message_count()); |
| 940 | 976 |
| 941 // Two messages come for the first update event. | 977 // Expect that a zoom happen because the time threshold has not passed. |
| 942 [view->cocoa_view() magnifyWithEvent:pinchUpdateEvent]; | 978 [view->cocoa_view() magnifyWithEvent:pinchUpdateEvent]; |
| 943 ASSERT_EQ(2U, process_host->sink().message_count()); | 979 EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage()); |
| 944 host->OnMessageReceived(*response); | 980 host->OnMessageReceived(*response); |
| 981 EXPECT_EQ(2U, process_host_->sink().message_count()); |
| 982 process_host_->sink().ClearMessages(); |
| 945 | 983 |
| 946 // The end event sends one message. | |
| 947 [view->cocoa_view() endGestureWithEvent:pinchEndEvent]; | 984 [view->cocoa_view() endGestureWithEvent:pinchEndEvent]; |
| 948 ASSERT_EQ(3U, process_host->sink().message_count()); | 985 EXPECT_EQ(1U, process_host_->sink().message_count()); |
| 949 | 986 process_host_->sink().ClearMessages(); |
| 950 process_host->sink().ClearMessages(); | |
| 951 } | 987 } |
| 952 | 988 |
| 953 // Do a gesture that doesn't cross the threshold and happens more than one | 989 // Do a gesture again, after the page scale is no longer at one, and ensure |
| 954 // second later. | 990 // that it is thresholded again. |
| 955 { | 991 { |
| 956 NSEvent* pinchBeginEvent = | 992 NSEvent* pinchBeginEvent = MockGestureEvent(NSEventTypeBeginGesture, 0); |
| 957 MockGestureEvent(NSEventTypeBeginGesture, 103.0, 0); | 993 NSEvent* pinchUpdateEvent = MockGestureEvent(NSEventTypeMagnify, 0.25); |
| 958 NSEvent* pinchUpdateEvent = | 994 NSEvent* pinchEndEvent = MockGestureEvent(NSEventTypeEndGesture, 0); |
| 959 MockGestureEvent(NSEventTypeMagnify, 103.1, 0.25); | |
| 960 NSEvent* pinchEndEvent = | |
| 961 MockGestureEvent(NSEventTypeEndGesture, 103.2, 0); | |
| 962 | 995 |
| 963 // No message comes for the begin event. | 996 view->page_is_at_scale_one_ = true; |
| 997 |
| 964 [view->cocoa_view() beginGestureWithEvent:pinchBeginEvent]; | 998 [view->cocoa_view() beginGestureWithEvent:pinchBeginEvent]; |
| 965 ASSERT_EQ(0U, process_host->sink().message_count()); | 999 EXPECT_EQ(0U, process_host_->sink().message_count()); |
| 966 | 1000 |
| 967 // Two messages come for the first update event. | 1001 // Get back to zoom one right after the begin event. This should still keep |
| 1002 // the thresholding in place (it is latched at the begin event). |
| 1003 view->page_is_at_scale_one_ = false; |
| 1004 |
| 1005 // Expect that zoom be disabled because the time threshold has passed. |
| 968 [view->cocoa_view() magnifyWithEvent:pinchUpdateEvent]; | 1006 [view->cocoa_view() magnifyWithEvent:pinchUpdateEvent]; |
| 969 ASSERT_EQ(0U, process_host->sink().message_count()); | 1007 EXPECT_EQ(2U, process_host_->sink().message_count()); |
| 1008 EXPECT_TRUE(ZoomDisabledForPinchUpdateMessage()); |
| 1009 host->OnMessageReceived(*response); |
| 1010 process_host_->sink().ClearMessages(); |
| 970 | 1011 |
| 971 // As does the end. | |
| 972 [view->cocoa_view() endGestureWithEvent:pinchEndEvent]; | 1012 [view->cocoa_view() endGestureWithEvent:pinchEndEvent]; |
| 973 ASSERT_EQ(0U, process_host->sink().message_count()); | 1013 EXPECT_EQ(1U, process_host_->sink().message_count()); |
| 974 | 1014 process_host_->sink().ClearMessages(); |
| 975 process_host->sink().ClearMessages(); | |
| 976 } | 1015 } |
| 977 | 1016 |
| 978 // Clean up. | 1017 // Clean up. |
| 979 host->Shutdown(); | 1018 host->Shutdown(); |
| 980 } | 1019 } |
| 981 | 1020 |
| 982 | 1021 |
| 983 } // namespace content | 1022 } // namespace content |
| OLD | NEW |