summaryrefslogtreecommitdiffstats
path: root/content/renderer/mouse_lock_dispatcher_browsertest.cc
diff options
context:
space:
mode:
authorscheib@chromium.org <scheib@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-27 07:33:11 +0000
committerscheib@chromium.org <scheib@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-27 07:33:11 +0000
commit217690df70c213c482039242dd935786c37dcd3c (patch)
tree8d0a579099bf69e51866cffb682c28ba44330b4f /content/renderer/mouse_lock_dispatcher_browsertest.cc
parent15f08dde26dbb02c8e4441492ab967cb48fcd4e4 (diff)
downloadchromium_src-217690df70c213c482039242dd935786c37dcd3c.zip
chromium_src-217690df70c213c482039242dd935786c37dcd3c.tar.gz
chromium_src-217690df70c213c482039242dd935786c37dcd3c.tar.bz2
Mouse Lock is currently supported in Pepper, but not yet supported from WebKit.
Move the render thread logic for managing the mouse lock state out of the pepper_plugin_delegate_impl, and into a higher level dispatcher for render_view_impl. Handle mouse lock / pointer lock requests from both pepper and webkit (WebKit API not yet landed, small TODOs left in this code to enable once that lands). BUG=109957 TEST=Pepper examples/mouse_lock and NaCl mouse lock examples still work. Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=119206 Review URL: http://codereview.chromium.org/8970016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@119406 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/mouse_lock_dispatcher_browsertest.cc')
-rw-r--r--content/renderer/mouse_lock_dispatcher_browsertest.cc232
1 files changed, 232 insertions, 0 deletions
diff --git a/content/renderer/mouse_lock_dispatcher_browsertest.cc b/content/renderer/mouse_lock_dispatcher_browsertest.cc
new file mode 100644
index 0000000..5605aa4
--- /dev/null
+++ b/content/renderer/mouse_lock_dispatcher_browsertest.cc
@@ -0,0 +1,232 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "content/common/view_messages.h"
+#include "content/renderer/mouse_lock_dispatcher.h"
+#include "content/renderer/render_view_impl.h"
+#include "content/test/render_view_test.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+
+namespace {
+
+class MockLockTarget : public MouseLockDispatcher::LockTarget {
+ public:
+ MOCK_METHOD1(OnLockMouseACK, void(bool));
+ MOCK_METHOD0(OnMouseLockLost, void());
+ MOCK_METHOD1(HandleMouseLockedInputEvent,
+ bool(const WebKit::WebMouseEvent&));
+};
+
+// MouseLockDispatcher is a RenderViewObserver, and we test it by creating a
+// fixture containing a RenderViewImpl view() and interacting to that interface.
+class MouseLockDispatcherTest
+ : public content::RenderViewTest {
+ public:
+ virtual void SetUp() {
+ content::RenderViewTest::SetUp();
+ route_id_ = view()->GetRoutingId();
+ target_ = new MockLockTarget();
+ alternate_target_ = new MockLockTarget();
+ }
+
+ virtual void TearDown() {
+ content::RenderViewTest::TearDown();
+ delete target_;
+ delete alternate_target_;
+ }
+
+ protected:
+ RenderViewImpl* view() { return static_cast<RenderViewImpl*>(view_); }
+ MouseLockDispatcher* dispatcher() { return view()->mouse_lock_dispatcher(); }
+ int route_id_;
+ MockLockTarget* target_;
+ MockLockTarget* alternate_target_;
+};
+
+} // namespace
+
+// Test simple use of RenderViewImpl interface to WebKit for pointer lock.
+TEST_F(MouseLockDispatcherTest, BasicWebWidget) {
+ // Start unlocked.
+ EXPECT_FALSE(view()->isPointerLocked());
+
+ // Lock.
+ EXPECT_TRUE(view()->requestPointerLock());
+ view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ EXPECT_TRUE(view()->isPointerLocked());
+
+ // Unlock.
+ view()->requestPointerUnlock();
+ view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ EXPECT_FALSE(view()->isPointerLocked());
+
+ // Attempt a lock, and have it fail.
+ EXPECT_TRUE(view()->requestPointerLock());
+ view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
+ EXPECT_FALSE(view()->isPointerLocked());
+}
+
+// Test simple use of MouseLockDispatcher with a mock LockTarget.
+TEST_F(MouseLockDispatcherTest, BasicMockLockTarget) {
+ ::testing::InSequence expect_calls_in_sequence;
+ EXPECT_CALL(*target_, OnLockMouseACK(true));
+ EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_));
+ EXPECT_CALL(*target_, OnMouseLockLost());
+ EXPECT_CALL(*target_, OnLockMouseACK(false));
+
+ // Start unlocked.
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(NULL));
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
+
+ // Lock.
+ EXPECT_TRUE(dispatcher()->LockMouse(target_));
+ view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
+
+ // Receive mouse event.
+ dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
+
+ // Unlock.
+ dispatcher()->UnlockMouse(target_);
+ view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
+
+ // Attempt a lock, and have it fail.
+ EXPECT_TRUE(dispatcher()->LockMouse(target_));
+ view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
+}
+
+// Test deleting a target while it is in use by MouseLockDispatcher.
+TEST_F(MouseLockDispatcherTest, DeleteAndUnlock) {
+ ::testing::InSequence expect_calls_in_sequence;
+ EXPECT_CALL(*target_, OnLockMouseACK(true));
+ EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_)).Times(0);
+ EXPECT_CALL(*target_, OnMouseLockLost()).Times(0);
+
+ // Lock.
+ EXPECT_TRUE(dispatcher()->LockMouse(target_));
+ view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
+
+ // Unlock, with a deleted target.
+ // Don't receive mouse events or lock lost.
+ dispatcher()->OnLockTargetDestroyed(target_);
+ delete target_;
+ target_ = NULL;
+ dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
+ view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
+}
+
+// Test deleting a target that is pending a lock request response.
+TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockSuccess) {
+ ::testing::InSequence expect_calls_in_sequence;
+ EXPECT_CALL(*target_, OnLockMouseACK(true)).Times(0);
+ EXPECT_CALL(*target_, OnMouseLockLost()).Times(0);
+
+ // Lock request.
+ EXPECT_TRUE(dispatcher()->LockMouse(target_));
+
+ // Before receiving response delete the target.
+ dispatcher()->OnLockTargetDestroyed(target_);
+ delete target_;
+ target_ = NULL;
+
+ // Lock response.
+ view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+}
+
+// Test deleting a target that is pending a lock request failure response.
+TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockFail) {
+ ::testing::InSequence expect_calls_in_sequence;
+ EXPECT_CALL(*target_, OnLockMouseACK(true)).Times(0);
+ EXPECT_CALL(*target_, OnMouseLockLost()).Times(0);
+
+ // Lock request.
+ EXPECT_TRUE(dispatcher()->LockMouse(target_));
+
+ // Before receiving response delete the target.
+ dispatcher()->OnLockTargetDestroyed(target_);
+ delete target_;
+ target_ = NULL;
+
+ // Lock response.
+ view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
+}
+
+// Test not receiving mouse events when a target is not locked.
+TEST_F(MouseLockDispatcherTest, MouseEventsNotReceived) {
+ ::testing::InSequence expect_calls_in_sequence;
+ EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_)).Times(0);
+ EXPECT_CALL(*target_, OnLockMouseACK(true));
+ EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_));
+ EXPECT_CALL(*target_, OnMouseLockLost());
+ EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_)).Times(0);
+
+ // (Don't) receive mouse event.
+ dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
+
+ // Lock.
+ EXPECT_TRUE(dispatcher()->LockMouse(target_));
+ view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
+
+ // Receive mouse event.
+ dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
+
+ // Unlock.
+ dispatcher()->UnlockMouse(target_);
+ view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
+
+ // (Don't) receive mouse event.
+ dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
+}
+
+// Test multiple targets
+TEST_F(MouseLockDispatcherTest, MultipleTargets) {
+ ::testing::InSequence expect_calls_in_sequence;
+ EXPECT_CALL(*target_, OnLockMouseACK(true));
+ EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_));
+ EXPECT_CALL(*alternate_target_, HandleMouseLockedInputEvent(_)).Times(0);
+ EXPECT_CALL(*target_, OnMouseLockLost()).Times(0);
+ EXPECT_CALL(*alternate_target_, OnMouseLockLost()).Times(0);
+ EXPECT_CALL(*target_, OnMouseLockLost());
+
+ // Lock request for target.
+ EXPECT_TRUE(dispatcher()->LockMouse(target_));
+
+ // Fail attempt to lock alternate.
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
+ EXPECT_FALSE(dispatcher()->LockMouse(alternate_target_));
+
+ // Lock completion for target.
+ view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
+
+ // Fail attempt to lock alternate.
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
+ EXPECT_FALSE(dispatcher()->LockMouse(alternate_target_));
+
+ // Receive mouse event to only one target.
+ dispatcher()->WillHandleMouseEvent(WebKit::WebMouseEvent());
+
+ // Unlock alternate target has no effect.
+ dispatcher()->UnlockMouse(alternate_target_);
+ EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
+
+ // Though the call to UnlockMouse should not unlock any target, we will
+ // cause an unlock (as if e.g. user escaped mouse lock) and verify the
+ // correct target is unlocked.
+ view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
+}
+