blob: 2a0fd6b4778e7bd4370e28018408144be61ce8ab [file] [log] [blame]
[email protected]217690d2012-01-27 07:33:111// 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.
4
5#include <string>
6
7#include "content/common/view_messages.h"
[email protected]899617f2012-06-04 02:27:148#include "content/public/test/render_view_test.h"
[email protected]217690d2012-01-27 07:33:119#include "content/renderer/mouse_lock_dispatcher.h"
10#include "content/renderer/render_view_impl.h"
[email protected]217690d2012-01-27 07:33:1111#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14using ::testing::_;
15
[email protected]e9ff79c2012-10-19 21:31:2616namespace content {
[email protected]217690d2012-01-27 07:33:1117namespace {
18
19class MockLockTarget : public MouseLockDispatcher::LockTarget {
20 public:
21 MOCK_METHOD1(OnLockMouseACK, void(bool));
22 MOCK_METHOD0(OnMouseLockLost, void());
23 MOCK_METHOD1(HandleMouseLockedInputEvent,
[email protected]180ef242013-11-07 06:50:4624 bool(const blink::WebMouseEvent&));
[email protected]217690d2012-01-27 07:33:1125};
26
27// MouseLockDispatcher is a RenderViewObserver, and we test it by creating a
28// fixture containing a RenderViewImpl view() and interacting to that interface.
[email protected]e9ff79c2012-10-19 21:31:2629class MouseLockDispatcherTest : public RenderViewTest {
[email protected]217690d2012-01-27 07:33:1130 public:
dchengf5762152014-10-29 02:12:0631 void SetUp() override {
[email protected]e9ff79c2012-10-19 21:31:2632 RenderViewTest::SetUp();
[email protected]9f76c1e2012-03-05 15:15:5833 route_id_ = view()->GetRoutingID();
[email protected]217690d2012-01-27 07:33:1134 target_ = new MockLockTarget();
35 alternate_target_ = new MockLockTarget();
36 }
37
dchengf5762152014-10-29 02:12:0638 void TearDown() override {
[email protected]e9ff79c2012-10-19 21:31:2639 RenderViewTest::TearDown();
[email protected]217690d2012-01-27 07:33:1140 delete target_;
41 delete alternate_target_;
42 }
43
44 protected:
45 RenderViewImpl* view() { return static_cast<RenderViewImpl*>(view_); }
46 MouseLockDispatcher* dispatcher() { return view()->mouse_lock_dispatcher(); }
47 int route_id_;
48 MockLockTarget* target_;
49 MockLockTarget* alternate_target_;
50};
51
52} // namespace
53
54// Test simple use of RenderViewImpl interface to WebKit for pointer lock.
55TEST_F(MouseLockDispatcherTest, BasicWebWidget) {
56 // Start unlocked.
57 EXPECT_FALSE(view()->isPointerLocked());
58
59 // Lock.
60 EXPECT_TRUE(view()->requestPointerLock());
61 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
62 EXPECT_TRUE(view()->isPointerLocked());
63
64 // Unlock.
65 view()->requestPointerUnlock();
66 view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
67 EXPECT_FALSE(view()->isPointerLocked());
68
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());
73}
74
75// Test simple use of MouseLockDispatcher with a mock LockTarget.
76TEST_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));
82
83 // Start unlocked.
84 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(NULL));
85 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
86
87 // Lock.
88 EXPECT_TRUE(dispatcher()->LockMouse(target_));
89 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
90 EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
91
92 // Receive mouse event.
[email protected]180ef242013-11-07 06:50:4693 dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
[email protected]217690d2012-01-27 07:33:1194
95 // Unlock.
96 dispatcher()->UnlockMouse(target_);
97 view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
98 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
99
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_));
104}
105
106// Test deleting a target while it is in use by MouseLockDispatcher.
107TEST_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);
112
113 // Lock.
114 EXPECT_TRUE(dispatcher()->LockMouse(target_));
115 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
116 EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
117
118 // Unlock, with a deleted target.
119 // Don't receive mouse events or lock lost.
120 dispatcher()->OnLockTargetDestroyed(target_);
121 delete target_;
122 target_ = NULL;
[email protected]180ef242013-11-07 06:50:46123 dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
[email protected]217690d2012-01-27 07:33:11124 view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
125 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
126}
127
128// Test deleting a target that is pending a lock request response.
129TEST_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);
133
134 // Lock request.
135 EXPECT_TRUE(dispatcher()->LockMouse(target_));
136
137 // Before receiving response delete the target.
138 dispatcher()->OnLockTargetDestroyed(target_);
139 delete target_;
140 target_ = NULL;
141
142 // Lock response.
143 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
144}
145
146// Test deleting a target that is pending a lock request failure response.
147TEST_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);
151
152 // Lock request.
153 EXPECT_TRUE(dispatcher()->LockMouse(target_));
154
155 // Before receiving response delete the target.
156 dispatcher()->OnLockTargetDestroyed(target_);
157 delete target_;
158 target_ = NULL;
159
160 // Lock response.
161 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
162}
163
164// Test not receiving mouse events when a target is not locked.
165TEST_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);
172
173 // (Don't) receive mouse event.
[email protected]180ef242013-11-07 06:50:46174 dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
[email protected]217690d2012-01-27 07:33:11175
176 // Lock.
177 EXPECT_TRUE(dispatcher()->LockMouse(target_));
178 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
179 EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
180
181 // Receive mouse event.
[email protected]180ef242013-11-07 06:50:46182 dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
[email protected]217690d2012-01-27 07:33:11183
184 // Unlock.
185 dispatcher()->UnlockMouse(target_);
186 view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
187 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
188
189 // (Don't) receive mouse event.
[email protected]180ef242013-11-07 06:50:46190 dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
[email protected]217690d2012-01-27 07:33:11191}
192
193// Test multiple targets
194TEST_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());
202
203 // Lock request for target.
204 EXPECT_TRUE(dispatcher()->LockMouse(target_));
205
206 // Fail attempt to lock alternate.
207 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
208 EXPECT_FALSE(dispatcher()->LockMouse(alternate_target_));
209
210 // Lock completion for target.
211 view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
212 EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
213
214 // Fail attempt to lock alternate.
215 EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
216 EXPECT_FALSE(dispatcher()->LockMouse(alternate_target_));
217
218 // Receive mouse event to only one target.
[email protected]180ef242013-11-07 06:50:46219 dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
[email protected]217690d2012-01-27 07:33:11220
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_));
225
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_));
231}
232
[email protected]e9ff79c2012-10-19 21:31:26233} // namespace content