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
3 // found in the LICENSE file.
7 #include "content/common/view_messages.h"
8 #include "content/public/test/render_view_test.h"
9 #include "content/renderer/mouse_lock_dispatcher.h"
10 #include "content/renderer/render_view_impl.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
19 class MockLockTarget
: public MouseLockDispatcher::LockTarget
{
21 MOCK_METHOD1(OnLockMouseACK
, void(bool));
22 MOCK_METHOD0(OnMouseLockLost
, void());
23 MOCK_METHOD1(HandleMouseLockedInputEvent
,
24 bool(const WebKit::WebMouseEvent
&));
27 // MouseLockDispatcher is a RenderViewObserver, and we test it by creating a
28 // fixture containing a RenderViewImpl view() and interacting to that interface.
29 class MouseLockDispatcherTest
: public RenderViewTest
{
31 virtual void SetUp() {
32 RenderViewTest::SetUp();
33 route_id_
= view()->GetRoutingID();
34 target_
= new MockLockTarget();
35 alternate_target_
= new MockLockTarget();
38 virtual void TearDown() {
39 RenderViewTest::TearDown();
41 delete alternate_target_
;
45 RenderViewImpl
* view() { return static_cast<RenderViewImpl
*>(view_
); }
46 MouseLockDispatcher
* dispatcher() { return view()->mouse_lock_dispatcher(); }
48 MockLockTarget
* target_
;
49 MockLockTarget
* alternate_target_
;
54 // Test simple use of RenderViewImpl interface to WebKit for pointer lock.
55 TEST_F(MouseLockDispatcherTest
, BasicWebWidget
) {
57 EXPECT_FALSE(view()->isPointerLocked());
60 EXPECT_TRUE(view()->requestPointerLock());
61 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_
, true));
62 EXPECT_TRUE(view()->isPointerLocked());
65 view()->requestPointerUnlock();
66 view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_
));
67 EXPECT_FALSE(view()->isPointerLocked());
69 // Attempt a lock, and have it fail.
70 EXPECT_TRUE(view()->requestPointerLock());
71 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_
, false));
72 EXPECT_FALSE(view()->isPointerLocked());
75 // Test simple use of MouseLockDispatcher with a mock LockTarget.
76 TEST_F(MouseLockDispatcherTest
, BasicMockLockTarget
) {
77 ::testing::InSequence expect_calls_in_sequence
;
78 EXPECT_CALL(*target_
, OnLockMouseACK(true));
79 EXPECT_CALL(*target_
, HandleMouseLockedInputEvent(_
));
80 EXPECT_CALL(*target_
, OnMouseLockLost());
81 EXPECT_CALL(*target_
, OnLockMouseACK(false));
84 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(NULL
));
85 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_
));
88 EXPECT_TRUE(dispatcher()->LockMouse(target_
));
89 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_
, true));
90 EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_
));
92 // Receive mouse event.
93 dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
96 dispatcher()->UnlockMouse(target_
);
97 view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_
));
98 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_
));
100 // Attempt a lock, and have it fail.
101 EXPECT_TRUE(dispatcher()->LockMouse(target_
));
102 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_
, false));
103 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_
));
106 // Test deleting a target while it is in use by MouseLockDispatcher.
107 TEST_F(MouseLockDispatcherTest
, DeleteAndUnlock
) {
108 ::testing::InSequence expect_calls_in_sequence
;
109 EXPECT_CALL(*target_
, OnLockMouseACK(true));
110 EXPECT_CALL(*target_
, HandleMouseLockedInputEvent(_
)).Times(0);
111 EXPECT_CALL(*target_
, OnMouseLockLost()).Times(0);
114 EXPECT_TRUE(dispatcher()->LockMouse(target_
));
115 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_
, true));
116 EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_
));
118 // Unlock, with a deleted target.
119 // Don't receive mouse events or lock lost.
120 dispatcher()->OnLockTargetDestroyed(target_
);
123 dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
124 view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_
));
125 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_
));
128 // Test deleting a target that is pending a lock request response.
129 TEST_F(MouseLockDispatcherTest
, DeleteWithPendingLockSuccess
) {
130 ::testing::InSequence expect_calls_in_sequence
;
131 EXPECT_CALL(*target_
, OnLockMouseACK(true)).Times(0);
132 EXPECT_CALL(*target_
, OnMouseLockLost()).Times(0);
135 EXPECT_TRUE(dispatcher()->LockMouse(target_
));
137 // Before receiving response delete the target.
138 dispatcher()->OnLockTargetDestroyed(target_
);
143 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_
, true));
146 // Test deleting a target that is pending a lock request failure response.
147 TEST_F(MouseLockDispatcherTest
, DeleteWithPendingLockFail
) {
148 ::testing::InSequence expect_calls_in_sequence
;
149 EXPECT_CALL(*target_
, OnLockMouseACK(true)).Times(0);
150 EXPECT_CALL(*target_
, OnMouseLockLost()).Times(0);
153 EXPECT_TRUE(dispatcher()->LockMouse(target_
));
155 // Before receiving response delete the target.
156 dispatcher()->OnLockTargetDestroyed(target_
);
161 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_
, false));
164 // Test not receiving mouse events when a target is not locked.
165 TEST_F(MouseLockDispatcherTest
, MouseEventsNotReceived
) {
166 ::testing::InSequence expect_calls_in_sequence
;
167 EXPECT_CALL(*target_
, HandleMouseLockedInputEvent(_
)).Times(0);
168 EXPECT_CALL(*target_
, OnLockMouseACK(true));
169 EXPECT_CALL(*target_
, HandleMouseLockedInputEvent(_
));
170 EXPECT_CALL(*target_
, OnMouseLockLost());
171 EXPECT_CALL(*target_
, HandleMouseLockedInputEvent(_
)).Times(0);
173 // (Don't) receive mouse event.
174 dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
177 EXPECT_TRUE(dispatcher()->LockMouse(target_
));
178 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_
, true));
179 EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_
));
181 // Receive mouse event.
182 dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
185 dispatcher()->UnlockMouse(target_
);
186 view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_
));
187 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_
));
189 // (Don't) receive mouse event.
190 dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
193 // Test multiple targets
194 TEST_F(MouseLockDispatcherTest
, MultipleTargets
) {
195 ::testing::InSequence expect_calls_in_sequence
;
196 EXPECT_CALL(*target_
, OnLockMouseACK(true));
197 EXPECT_CALL(*target_
, HandleMouseLockedInputEvent(_
));
198 EXPECT_CALL(*alternate_target_
, HandleMouseLockedInputEvent(_
)).Times(0);
199 EXPECT_CALL(*target_
, OnMouseLockLost()).Times(0);
200 EXPECT_CALL(*alternate_target_
, OnMouseLockLost()).Times(0);
201 EXPECT_CALL(*target_
, OnMouseLockLost());
203 // Lock request for target.
204 EXPECT_TRUE(dispatcher()->LockMouse(target_
));
206 // Fail attempt to lock alternate.
207 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_
));
208 EXPECT_FALSE(dispatcher()->LockMouse(alternate_target_
));
210 // Lock completion for target.
211 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_
, true));
212 EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_
));
214 // Fail attempt to lock alternate.
215 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_
));
216 EXPECT_FALSE(dispatcher()->LockMouse(alternate_target_
));
218 // Receive mouse event to only one target.
219 dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
221 // Unlock alternate target has no effect.
222 dispatcher()->UnlockMouse(alternate_target_
);
223 EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_
));
224 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_
));
226 // Though the call to UnlockMouse should not unlock any target, we will
227 // cause an unlock (as if e.g. user escaped mouse lock) and verify the
228 // correct target is unlocked.
229 view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_
));
230 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_
));
233 } // namespace content