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 17class Browser; 18class BrowserWindow; 19class GURL; 20class Profile; 21 22namespace content { 23class 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. 54class 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