Home | History | Annotate | Download | only in renderer
      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 
     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 
     19 MouseLockDispatcher::~MouseLockDispatcher() {
     20 }
     21 
     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 
     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 
     49 void MouseLockDispatcher::OnLockTargetDestroyed(LockTarget* target) {
     50   if (target == target_) {
     51     UnlockMouse(target);
     52     target_ = NULL;
     53   }
     54 }
     55 
     56 bool MouseLockDispatcher::IsMouseLockedTo(LockTarget* target) {
     57   return mouse_locked_ && target_ == target;
     58 }
     59 
     60 bool MouseLockDispatcher::WillHandleMouseEvent(
     61     const blink::WebMouseEvent& event) {
     62   if (mouse_locked_ && target_)
     63     return target_->HandleMouseLockedInputEvent(event);
     64   return false;
     65 }
     66 
     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 
     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