1 // Copyright (c) 2015 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 #ifndef CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_MOUSE_LOCK_CONTROLLER_H_ 6 #define CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_MOUSE_LOCK_CONTROLLER_H_ 7 8 #include <utility> 9 10 #include "base/callback.h" 11 #include "base/macros.h" 12 #include "base/memory/weak_ptr.h" 13 #include "base/time/time.h" 14 #include "chrome/browser/ui/exclusive_access/exclusive_access_bubble_hide_callback.h" 15 #include "chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h" 16 #include "components/content_settings/core/common/content_settings.h" 17 18 // This class implements mouselock behavior. 19 class MouseLockController : public ExclusiveAccessControllerBase { 20 public: 21 explicit MouseLockController(ExclusiveAccessManager* manager); 22 ~MouseLockController() override; 23 24 // Returns true if the mouse is locked. 25 bool IsMouseLocked() const; 26 27 // Returns true if the mouse was locked and no notification should be 28 // displayed to the user. This is the case when a notice has already been 29 // displayed to the user, and the application voluntarily unlocks, then 30 // re-locks the mouse (a duplicate notification should not be given). See 31 // content::MouseLockDispatcher::LockMouse. 32 bool IsMouseLockedSilently() const; 33 34 void RequestToLockMouse(content::WebContents* web_contents, 35 bool user_gesture, 36 bool last_unlocked_by_target); 37 38 // Override from ExclusiveAccessControllerBase 39 bool HandleUserPressedEscape() override; 40 41 void ExitExclusiveAccessToPreviousState() override; 42 43 // Called by Browser::LostMouseLock. 44 void LostMouseLock(); 45 46 void UnlockMouse(); 47 set_lock_state_callback_for_test(base::OnceClosure callback)48 void set_lock_state_callback_for_test(base::OnceClosure callback) { 49 lock_state_callback_for_test_ = std::move(callback); 50 } 51 52 private: 53 friend class ExclusiveAccessTest; 54 55 enum MouseLockState { 56 MOUSELOCK_UNLOCKED, 57 // Mouse has been locked. 58 MOUSELOCK_LOCKED, 59 // Mouse has been locked silently, with no notification to user. 60 MOUSELOCK_LOCKED_SILENTLY 61 }; 62 63 void ExitExclusiveAccessIfNecessary() override; 64 void NotifyTabExclusiveAccessLost() override; 65 void RecordBubbleReshowsHistogram(int bubble_reshow_count) override; 66 67 void OnBubbleHidden(content::WebContents*, ExclusiveAccessBubbleHideReason); 68 69 MouseLockState mouse_lock_state_; 70 71 // Optionally a WebContents instance that is granted permission to silently 72 // lock the mouse. This is granted only if the WebContents instance has 73 // previously locked and displayed the permission bubble until the bubble 74 // time out has expired. https://crbug.com/725370 75 content::WebContents* web_contents_granted_silent_mouse_lock_permission_ = 76 nullptr; 77 78 // If true, does not call into the WebContents to lock the mouse. Just assumes 79 // that it works. This may be necessary when calling 80 // Browser::RequestToLockMouse in tests, because the proper signal will not 81 // have been passed to the RenderViewHost. 82 bool fake_mouse_lock_for_test_; 83 84 // If set, |bubble_hide_callback_for_test_| will be called during 85 // |OnBubbleHidden()|. 86 ExclusiveAccessBubbleHideCallbackForTest bubble_hide_callback_for_test_; 87 88 // Called when the page requests (successfully or not) or loses mouse lock. 89 base::OnceClosure lock_state_callback_for_test_; 90 91 // Timestamp when the user last successfully escaped from a lock request. 92 base::TimeTicks last_user_escape_time_; 93 94 base::WeakPtrFactory<MouseLockController> weak_ptr_factory_{this}; 95 96 DISALLOW_COPY_AND_ASSIGN(MouseLockController); 97 }; 98 99 #endif // CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_MOUSE_LOCK_CONTROLLER_H_ 100