• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/renderer/mouse_lock_dispatcher.h"
6 
7 #include "base/logging.h"
8 #include "third_party/WebKit/public/web/WebInputEvent.h"
9 
10 namespace content {
11 
MouseLockDispatcher()12 MouseLockDispatcher::MouseLockDispatcher() : mouse_locked_(false),
13                                              pending_lock_request_(false),
14                                              pending_unlock_request_(false),
15                                              unlocked_by_target_(false),
16                                              target_(NULL) {
17 }
18 
~MouseLockDispatcher()19 MouseLockDispatcher::~MouseLockDispatcher() {
20 }
21 
LockMouse(LockTarget * target)22 bool MouseLockDispatcher::LockMouse(LockTarget* target) {
23   if (MouseLockedOrPendingAction())
24     return false;
25 
26   pending_lock_request_ = true;
27   target_ = target;
28 
29   SendLockMouseRequest(unlocked_by_target_);
30   unlocked_by_target_ = false;
31   return true;
32 }
33 
UnlockMouse(LockTarget * target)34 void MouseLockDispatcher::UnlockMouse(LockTarget* target) {
35   if (target && target == target_ && !pending_unlock_request_) {
36     pending_unlock_request_ = true;
37 
38     // When a target application voluntarily unlocks the mouse we permit
39     // relocking the mouse silently and with no user gesture requirement.
40     // Check that the lock request is not currently pending and not yet
41     // accepted by the browser process before setting |unlocked_by_target_|.
42     if (!pending_lock_request_)
43       unlocked_by_target_ = true;
44 
45     SendUnlockMouseRequest();
46   }
47 }
48 
OnLockTargetDestroyed(LockTarget * target)49 void MouseLockDispatcher::OnLockTargetDestroyed(LockTarget* target) {
50   if (target == target_) {
51     UnlockMouse(target);
52     target_ = NULL;
53   }
54 }
55 
IsMouseLockedTo(LockTarget * target)56 bool MouseLockDispatcher::IsMouseLockedTo(LockTarget* target) {
57   return mouse_locked_ && target_ == target;
58 }
59 
WillHandleMouseEvent(const blink::WebMouseEvent & event)60 bool MouseLockDispatcher::WillHandleMouseEvent(
61     const blink::WebMouseEvent& event) {
62   if (mouse_locked_ && target_)
63     return target_->HandleMouseLockedInputEvent(event);
64   return false;
65 }
66 
OnLockMouseACK(bool succeeded)67 void MouseLockDispatcher::OnLockMouseACK(bool succeeded) {
68   DCHECK(!mouse_locked_ && pending_lock_request_);
69 
70   mouse_locked_ = succeeded;
71   pending_lock_request_ = false;
72   if (pending_unlock_request_ && !succeeded) {
73     // We have sent an unlock request after the lock request. However, since
74     // the lock request has failed, the unlock request will be ignored by the
75     // browser side and there won't be any response to it.
76     pending_unlock_request_ = false;
77   }
78 
79   LockTarget* last_target = target_;
80   if (!succeeded)
81     target_ = NULL;
82 
83   // Callbacks made after all state modification to prevent reentrant errors
84   // such as OnLockMouseACK() synchronously calling LockMouse().
85 
86   if (last_target)
87     last_target->OnLockMouseACK(succeeded);
88 }
89 
OnMouseLockLost()90 void MouseLockDispatcher::OnMouseLockLost() {
91   DCHECK(mouse_locked_ && !pending_lock_request_);
92 
93   mouse_locked_ = false;
94   pending_unlock_request_ = false;
95 
96   LockTarget* last_target = target_;
97   target_ = NULL;
98 
99   // Callbacks made after all state modification to prevent reentrant errors
100   // such as OnMouseLockLost() synchronously calling LockMouse().
101 
102   if (last_target)
103     last_target->OnMouseLockLost();
104 }
105 
106 }  // namespace content
107