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 <set> 9 10 #include "base/basictypes.h" 11 #include "base/memory/weak_ptr.h" 12 #include "chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.h" 13 #include "components/content_settings/core/common/content_settings.h" 14 #include "content/public/browser/notification_observer.h" 15 #include "content/public/browser/notification_registrar.h" 16 17 class Browser; 18 class BrowserWindow; 19 class GURL; 20 class Profile; 21 22 namespace content { 23 class WebContents; 24 } 25 26 // There are two different kinds of fullscreen mode - "tab fullscreen" and 27 // "browser fullscreen". "Tab fullscreen" refers to a renderer-initiated 28 // fullscreen mode (eg: from a Flash plugin or via the JS fullscreen API), 29 // whereas "browser fullscreen" refers to the user putting the browser itself 30 // into fullscreen mode from the UI. The difference is that tab fullscreen has 31 // implications for how the contents of the tab render (eg: a video element may 32 // grow to consume the whole tab), whereas browser fullscreen mode doesn't. 33 // Therefore if a user forces an exit from tab fullscreen, we need to notify the 34 // tab so it can stop rendering in its fullscreen mode. 35 // 36 // For Flash, FullscreenController will auto-accept all permission requests for 37 // fullscreen and/or mouse lock, since the assumption is that the plugin handles 38 // this for us. 39 // 40 // FullscreenWithinTab Note: 41 // All fullscreen widgets are displayed within the tab contents area, and 42 // FullscreenController will expand the browser window so that the tab contents 43 // area fills the entire screen. However, special behavior applies when a tab is 44 // being screen-captured. First, the browser window will not be 45 // fullscreened. This allows the user to retain control of their desktop to work 46 // in other browser tabs or applications while the fullscreen view is displayed 47 // on a remote screen. Second, FullscreenController will auto-resize fullscreen 48 // widgets to that of the capture video resolution when they are hidden (e.g., 49 // when a user has switched to another tab). This is both a performance and 50 // quality improvement since scaling and letterboxing steps can be skipped in 51 // the capture pipeline. 52 53 // This class implements fullscreen and mouselock behaviour. 54 class FullscreenController : public content::NotificationObserver { 55 public: 56 explicit FullscreenController(Browser* browser); 57 virtual ~FullscreenController(); 58 59 // Browser/User Fullscreen /////////////////////////////////////////////////// 60 61 // Returns true if the window is currently fullscreen and was initially 62 // transitioned to fullscreen by a browser (i.e., not tab-initiated) mode 63 // transition. 64 bool IsFullscreenForBrowser() const; 65 66 void ToggleBrowserFullscreenMode(); 67 68 // Extension API implementation uses this method to toggle fullscreen mode. 69 // The extension's name is displayed in the full screen bubble UI to attribute 70 // the cause of the full screen state change. 71 void ToggleBrowserFullscreenModeWithExtension(const GURL& extension_url); 72 73 // Tab/HTML/Flash Fullscreen ///////////////////////////////////////////////// 74 75 // Returns true if the browser window has/will fullscreen because of 76 // tab-initiated fullscreen. The window may still be transitioning, and 77 // BrowserWindow::IsFullscreen() may still return false. 78 bool IsWindowFullscreenForTabOrPending() const; 79 80 // Returns true if the tab is/will be in fullscreen mode. Note: This does NOT 81 // indicate whether the browser window is/will be fullscreened as well. See 82 // 'FullscreenWithinTab Note'. 83 bool IsFullscreenForTabOrPending( 84 const content::WebContents* web_contents) const; 85 86 // True if fullscreen was entered because of tab fullscreen (was not 87 // previously in user-initiated fullscreen). 88 bool IsFullscreenCausedByTab() const; 89 90 // Enter or leave tab-initiated fullscreen mode. FullscreenController will 91 // decide whether to also fullscreen the browser window. See 92 // 'FullscreenWithinTab Note'. 93 void ToggleFullscreenModeForTab(content::WebContents* web_contents, 94 bool enter_fullscreen); 95 96 // Platform Fullscreen /////////////////////////////////////////////////////// 97 98 // Returns whether we are currently in a Metro snap view. 99 bool IsInMetroSnapMode(); 100 101 #if defined(OS_WIN) 102 // API that puts the window into a mode suitable for rendering when Chrome 103 // is rendered in a 20% screen-width Metro snap view on Windows 8. 104 void SetMetroSnapMode(bool enable); 105 #endif 106 107 #if defined(OS_MACOSX) 108 void ToggleBrowserFullscreenWithChrome(); 109 #endif 110 111 // Mouse Lock //////////////////////////////////////////////////////////////// 112 113 bool IsMouseLockRequested() const; 114 bool IsMouseLocked() const; 115 116 void RequestToLockMouse(content::WebContents* web_contents, 117 bool user_gesture, 118 bool last_unlocked_by_target); 119 120 // Callbacks ///////////////////////////////////////////////////////////////// 121 122 // Called by Browser::TabDeactivated. 123 void OnTabDeactivated(content::WebContents* web_contents); 124 125 // Called by Browser::ActiveTabChanged. 126 void OnTabDetachedFromView(content::WebContents* web_contents); 127 128 // Called by Browser::TabClosingAt. 129 void OnTabClosing(content::WebContents* web_contents); 130 131 // Called by Browser::WindowFullscreenStateChanged. 132 void WindowFullscreenStateChanged(); 133 134 // Called by Browser::PreHandleKeyboardEvent. 135 bool HandleUserPressedEscape(); 136 137 // Called by platform FullscreenExitBubble. 138 void ExitTabOrBrowserFullscreenToPreviousState(); 139 void OnAcceptFullscreenPermission(); 140 void OnDenyFullscreenPermission(); 141 142 // Called by Browser::LostMouseLock. 143 void LostMouseLock(); 144 145 // content::NotificationObserver: 146 virtual void Observe(int type, 147 const content::NotificationSource& source, 148 const content::NotificationDetails& details) OVERRIDE; 149 150 // Bubble Content //////////////////////////////////////////////////////////// 151 152 GURL GetFullscreenExitBubbleURL() const; 153 FullscreenExitBubbleType GetFullscreenExitBubbleType() const; 154 155 private: 156 friend class FullscreenControllerTest; 157 158 enum MouseLockState { 159 MOUSELOCK_NOT_REQUESTED, 160 // The page requests to lock the mouse and the user hasn't responded to the 161 // request. 162 MOUSELOCK_REQUESTED, 163 // Mouse lock has been allowed by the user. 164 MOUSELOCK_ACCEPTED, 165 // Mouse lock has been silently accepted, no notification to user. 166 MOUSELOCK_ACCEPTED_SILENTLY 167 }; 168 169 enum FullscreenInternalOption { 170 BROWSER, 171 #if defined(OS_MACOSX) 172 BROWSER_WITH_CHROME, 173 #endif 174 TAB 175 }; 176 177 void UpdateNotificationRegistrations(); 178 179 // Posts a task to call NotifyFullscreenChange. 180 void PostFullscreenChangeNotification(bool is_fullscreen); 181 // Sends a NOTIFICATION_FULLSCREEN_CHANGED notification. 182 void NotifyFullscreenChange(bool is_fullscreen); 183 // Notifies the tab that it has been forced out of fullscreen and mouse lock 184 // mode if necessary. 185 void NotifyTabOfExitIfNecessary(); 186 void NotifyMouseLockChange(); 187 188 void ToggleFullscreenModeInternal(FullscreenInternalOption option); 189 void EnterFullscreenModeInternal(FullscreenInternalOption option); 190 void ExitFullscreenModeInternal(); 191 void SetFullscreenedTab(content::WebContents* tab); 192 void SetMouseLockTab(content::WebContents* tab); 193 194 // Make the current tab exit fullscreen mode or mouse lock if it is in it. 195 void ExitTabFullscreenOrMouseLockIfNecessary(); 196 void UpdateFullscreenExitBubbleContent(); 197 198 ContentSetting GetFullscreenSetting(const GURL& url) const; 199 ContentSetting GetMouseLockSetting(const GURL& url) const; 200 201 bool IsPrivilegedFullscreenForTab() const; 202 void SetPrivilegedFullscreenForTesting(bool is_privileged); 203 // Returns true if |web_contents| was toggled into/out of fullscreen mode as a 204 // screen-captured tab. See 'FullscreenWithinTab Note'. 205 bool MaybeToggleFullscreenForCapturedTab(content::WebContents* web_contents, 206 bool enter_fullscreen); 207 // Returns true if |web_contents| is in fullscreen mode as a screen-captured 208 // tab. See 'FullscreenWithinTab Note'. 209 bool IsFullscreenForCapturedTab(const content::WebContents* web_contents) 210 const; 211 void UnlockMouse(); 212 213 Browser* const browser_; 214 BrowserWindow* const window_; 215 Profile* const profile_; 216 217 // If there is currently a tab in fullscreen mode (entered via 218 // webkitRequestFullScreen), this is its WebContents. 219 // Assign using SetFullscreenedTab(). 220 content::WebContents* fullscreened_tab_; 221 222 // The URL of the extension which trigerred "browser fullscreen" mode. 223 GURL extension_caused_fullscreen_; 224 225 enum PriorFullscreenState { 226 STATE_INVALID, 227 STATE_NORMAL, 228 STATE_BROWSER_FULLSCREEN_NO_CHROME, 229 #if defined(OS_MACOSX) 230 STATE_BROWSER_FULLSCREEN_WITH_CHROME, 231 #endif 232 }; 233 // The state before entering tab fullscreen mode via webkitRequestFullScreen. 234 // When not in tab fullscreen, it is STATE_INVALID. 235 PriorFullscreenState state_prior_to_tab_fullscreen_; 236 // True if tab fullscreen has been allowed, either by settings or by user 237 // clicking the allow button on the fullscreen infobar. 238 bool tab_fullscreen_accepted_; 239 240 // True if this controller has toggled into tab OR browser fullscreen. 241 bool toggled_into_fullscreen_; 242 243 // WebContents for current tab requesting or currently in mouse lock. 244 // Assign using SetMouseLockTab(). 245 content::WebContents* mouse_lock_tab_; 246 247 MouseLockState mouse_lock_state_; 248 249 content::NotificationRegistrar registrar_; 250 251 // Used to verify that calls we expect to reenter by calling 252 // WindowFullscreenStateChanged do so. 253 bool reentrant_window_state_change_call_check_; 254 255 // Used in testing to confirm proper behavior for specific, privileged 256 // fullscreen cases. 257 bool is_privileged_fullscreen_for_testing_; 258 259 base::WeakPtrFactory<FullscreenController> ptr_factory_; 260 261 DISALLOW_COPY_AND_ASSIGN(FullscreenController); 262 }; 263 264 #endif // CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_H_ 265