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 #ifndef CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_H_ 6 #define CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_H_ 7 8 #include "base/basictypes.h" 9 #include "base/memory/weak_ptr.h" 10 #include "chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.h" 11 #include "chrome/common/content_settings.h" 12 #include "content/public/browser/notification_observer.h" 13 #include "content/public/browser/notification_registrar.h" 14 15 class Browser; 16 class BrowserWindow; 17 class GURL; 18 class Profile; 19 20 namespace content { 21 class WebContents; 22 } 23 24 // There are two different kinds of fullscreen mode - "tab fullscreen" and 25 // "browser fullscreen". "Tab fullscreen" refers to when a tab enters 26 // fullscreen mode via the JS fullscreen API, and "browser fullscreen" refers 27 // to the user putting the browser itself into fullscreen mode from the UI. The 28 // difference is that tab fullscreen has implications for how the contents of 29 // the tab render (eg: a video element may grow to consume the whole tab), 30 // whereas browser fullscreen mode doesn't. Therefore if a user forces an exit 31 // from tab fullscreen, we need to notify the tab so it can stop rendering in 32 // its fullscreen mode. 33 34 // This class implements fullscreen and mouselock behaviour. 35 class FullscreenController : public content::NotificationObserver { 36 public: 37 explicit FullscreenController(Browser* browser); 38 virtual ~FullscreenController(); 39 40 // Browser/User Fullscreen /////////////////////////////////////////////////// 41 42 // Returns true if the window is currently fullscreen and was initially 43 // transitioned to fullscreen by a browser (vs tab) mode transition. 44 bool IsFullscreenForBrowser() const; 45 46 void ToggleFullscreenMode(); 47 48 // Tab/HTML Fullscreen /////////////////////////////////////////////////////// 49 50 // Returns true if fullscreen has been caused by a tab. 51 // The window may still be transitioning, and window_->IsFullscreen() 52 // may still return false. 53 bool IsFullscreenForTabOrPending() const; 54 bool IsFullscreenForTabOrPending( 55 const content::WebContents* web_contents) const; 56 // True if fullscreen was entered because of tab fullscreen (was not 57 // previously in browser fullscreen). 58 bool IsFullscreenCausedByTab() const; 59 60 void ToggleFullscreenModeForTab(content::WebContents* web_contents, 61 bool enter_fullscreen); 62 63 // Extension API implementation uses this method to toggle fullscreen mode. 64 // The extension's name is displayed in the full screen bubble UI to attribute 65 // the cause of the full screen state change. 66 void ToggleFullscreenModeWithExtension(const GURL& extension_url); 67 68 // Platform Fullscreen /////////////////////////////////////////////////////// 69 70 // Returns whether we are currently in a Metro snap view. 71 bool IsInMetroSnapMode(); 72 73 #if defined(OS_WIN) 74 // API that puts the window into a mode suitable for rendering when Chrome 75 // is rendered in a 20% screen-width Metro snap view on Windows 8. 76 void SetMetroSnapMode(bool enable); 77 #endif 78 79 #if defined(OS_MACOSX) 80 void ToggleFullscreenWithChrome(); 81 #endif 82 83 // Mouse Lock //////////////////////////////////////////////////////////////// 84 85 bool IsMouseLockRequested() const; 86 bool IsMouseLocked() const; 87 88 void RequestToLockMouse(content::WebContents* web_contents, 89 bool user_gesture, 90 bool last_unlocked_by_target); 91 92 // Callbacks ///////////////////////////////////////////////////////////////// 93 94 // Called by Browser::TabDeactivated. 95 void OnTabDeactivated(content::WebContents* web_contents); 96 97 // Called by Browser::TabClosingAt. 98 void OnTabClosing(content::WebContents* web_contents); 99 100 // Called by Browser::WindowFullscreenStateChanged. 101 void WindowFullscreenStateChanged(); 102 103 // Called by Browser::PreHandleKeyboardEvent. 104 bool HandleUserPressedEscape(); 105 106 // Called by platform FullscreenExitBubble. 107 void ExitTabOrBrowserFullscreenToPreviousState(); 108 void OnAcceptFullscreenPermission(); 109 void OnDenyFullscreenPermission(); 110 111 // Called by Browser::LostMouseLock. 112 void LostMouseLock(); 113 114 // content::NotificationObserver: 115 virtual void Observe(int type, 116 const content::NotificationSource& source, 117 const content::NotificationDetails& details) OVERRIDE; 118 119 // Bubble Content //////////////////////////////////////////////////////////// 120 121 GURL GetFullscreenExitBubbleURL() const; 122 FullscreenExitBubbleType GetFullscreenExitBubbleType() const; 123 124 private: 125 enum MouseLockState { 126 MOUSELOCK_NOT_REQUESTED, 127 // The page requests to lock the mouse and the user hasn't responded to the 128 // request. 129 MOUSELOCK_REQUESTED, 130 // Mouse lock has been allowed by the user. 131 MOUSELOCK_ACCEPTED, 132 // Mouse lock has been silently accepted, no notification to user. 133 MOUSELOCK_ACCEPTED_SILENTLY 134 }; 135 136 enum FullscreenInternalOption { 137 BROWSER, 138 #if defined(OS_MACOSX) 139 BROWSER_WITH_CHROME, 140 #endif 141 TAB 142 }; 143 144 void UpdateNotificationRegistrations(); 145 146 // Posts a task to call NotifyFullscreenChange. 147 void PostFullscreenChangeNotification(bool is_fullscreen); 148 // Sends a NOTIFICATION_FULLSCREEN_CHANGED notification. 149 void NotifyFullscreenChange(bool is_fullscreen); 150 // Notifies the tab that it has been forced out of fullscreen and mouse lock 151 // mode if necessary. 152 void NotifyTabOfExitIfNecessary(); 153 void NotifyMouseLockChange(); 154 155 void ToggleFullscreenModeInternal(FullscreenInternalOption option); 156 void EnterFullscreenModeInternal(FullscreenInternalOption option); 157 void ExitFullscreenModeInternal(); 158 void SetFullscreenedTab(content::WebContents* tab); 159 void SetMouseLockTab(content::WebContents* tab); 160 161 // Make the current tab exit fullscreen mode or mouse lock if it is in it. 162 void ExitTabFullscreenOrMouseLockIfNecessary(); 163 void UpdateFullscreenExitBubbleContent(); 164 165 ContentSetting GetFullscreenSetting(const GURL& url) const; 166 ContentSetting GetMouseLockSetting(const GURL& url) const; 167 168 base::WeakPtrFactory<FullscreenController> ptr_factory_; 169 170 Browser* browser_; 171 BrowserWindow* window_; 172 Profile* profile_; 173 174 // If there is currently a tab in fullscreen mode (entered via 175 // webkitRequestFullScreen), this is its WebContents. 176 // Assign using SetFullscreenedTab(). 177 content::WebContents* fullscreened_tab_; 178 179 // The URL of the extension which trigerred "browser fullscreen" mode. 180 GURL extension_caused_fullscreen_; 181 182 enum PriorFullscreenState { 183 STATE_INVALID, 184 STATE_NORMAL, 185 STATE_BROWSER_FULLSCREEN_NO_CHROME, 186 #if defined(OS_MACOSX) 187 STATE_BROWSER_FULLSCREEN_WITH_CHROME, 188 #endif 189 }; 190 // The state before entering tab fullscreen mode via webkitRequestFullScreen. 191 // When not in tab fullscreen, it is STATE_INVALID. 192 PriorFullscreenState state_prior_to_tab_fullscreen_; 193 // True if tab fullscreen has been allowed, either by settings or by user 194 // clicking the allow button on the fullscreen infobar. 195 bool tab_fullscreen_accepted_; 196 197 // True if this controller has toggled into tab OR browser fullscreen. 198 bool toggled_into_fullscreen_; 199 200 // WebContents for current tab requesting or currently in mouse lock. 201 // Assign using SetMouseLockTab(). 202 content::WebContents* mouse_lock_tab_; 203 204 MouseLockState mouse_lock_state_; 205 206 content::NotificationRegistrar registrar_; 207 208 // Used to verify that calls we expect to reenter by calling 209 // WindowFullscreenStateChanged do so. 210 bool reentrant_window_state_change_call_check_; 211 212 DISALLOW_COPY_AND_ASSIGN(FullscreenController); 213 }; 214 215 #endif // CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_H_ 216