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