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.
5 #ifndef CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_H_
6 #define CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_H_
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 "chrome/common/content_settings.h"
14 #include "content/public/browser/notification_observer.h"
15 #include "content/public/browser/notification_registrar.h"
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.
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
40 // FullscreenWithinTab Note:
41 // When the browser is configured as such, all fullscreen widgets are displayed
42 // within the tab contents area, and FullscreenController will expand the
43 // browser window so that the tab contents area fills the entire
44 // screen. However, special behavior applies when a tab is being
45 // screen-captured. First, the browser window will not be fullscreened. This
46 // allows the user to retain control of their desktop to work in other browser
47 // tabs or applications while the fullscreen view is displayed on a remote
48 // screen. Second, FullscreenController will auto-resize fullscreen widgets to
49 // that of the capture video resolution when they are hidden (e.g., when a user
50 // has switched to another tab). This is both a performance and quality
51 // improvement since scaling and letterboxing steps can be skipped in the
54 // This class implements fullscreen and mouselock behaviour.
55 class FullscreenController
: public content::NotificationObserver
{
57 explicit FullscreenController(Browser
* browser
);
58 virtual ~FullscreenController();
60 // Browser/User Fullscreen ///////////////////////////////////////////////////
62 // Returns true if the window is currently fullscreen and was initially
63 // transitioned to fullscreen by a browser (vs tab) mode transition.
64 bool IsFullscreenForBrowser() const;
66 void ToggleFullscreenMode();
68 // Tab/HTML/Flash Fullscreen /////////////////////////////////////////////////
70 // Returns true if fullscreen has been caused by a tab.
71 // The window may still be transitioning, and window_->IsFullscreen()
72 // may still return false.
74 // NOTE: The zero-argument version returns true iff a fullscreen tab and its
75 // browser window is/will be fullscreen. On the other hand, the one-argument
76 // version will return true while the renderer is/will be in fullscreen mode,
77 // but not necessarily the browser window. See 'FullscreenWithinTab Note'.
78 bool IsFullscreenForTabOrPending() const;
79 bool IsFullscreenForTabOrPending(
80 const content::WebContents
* web_contents
) const;
81 // True if fullscreen was entered because of tab fullscreen (was not
82 // previously in browser fullscreen).
83 bool IsFullscreenCausedByTab() const;
85 void ToggleFullscreenModeForTab(content::WebContents
* web_contents
,
86 bool enter_fullscreen
);
88 // Extension API implementation uses this method to toggle fullscreen mode.
89 // The extension's name is displayed in the full screen bubble UI to attribute
90 // the cause of the full screen state change.
91 void ToggleFullscreenModeWithExtension(const GURL
& extension_url
);
93 // Platform Fullscreen ///////////////////////////////////////////////////////
95 // Returns whether we are currently in a Metro snap view.
96 bool IsInMetroSnapMode();
99 // API that puts the window into a mode suitable for rendering when Chrome
100 // is rendered in a 20% screen-width Metro snap view on Windows 8.
101 void SetMetroSnapMode(bool enable
);
104 #if defined(OS_MACOSX)
105 void ToggleFullscreenWithChrome();
108 // Mouse Lock ////////////////////////////////////////////////////////////////
110 bool IsMouseLockRequested() const;
111 bool IsMouseLocked() const;
113 void RequestToLockMouse(content::WebContents
* web_contents
,
115 bool last_unlocked_by_target
);
117 // Callbacks /////////////////////////////////////////////////////////////////
119 // Called by Browser::TabDeactivated.
120 void OnTabDeactivated(content::WebContents
* web_contents
);
122 // Called by Browser::ActiveTabChanged.
123 void OnTabDetachedFromView(content::WebContents
* web_contents
);
125 // Called by Browser::TabClosingAt.
126 void OnTabClosing(content::WebContents
* web_contents
);
128 // Called by Browser::WindowFullscreenStateChanged.
129 void WindowFullscreenStateChanged();
131 // Called by Browser::PreHandleKeyboardEvent.
132 bool HandleUserPressedEscape();
134 // Called by platform FullscreenExitBubble.
135 void ExitTabOrBrowserFullscreenToPreviousState();
136 void OnAcceptFullscreenPermission();
137 void OnDenyFullscreenPermission();
139 // Called by Browser::LostMouseLock.
140 void LostMouseLock();
142 // content::NotificationObserver:
143 virtual void Observe(int type
,
144 const content::NotificationSource
& source
,
145 const content::NotificationDetails
& details
) OVERRIDE
;
147 // Bubble Content ////////////////////////////////////////////////////////////
149 GURL
GetFullscreenExitBubbleURL() const;
150 FullscreenExitBubbleType
GetFullscreenExitBubbleType() const;
153 friend class FullscreenControllerTest
;
155 enum MouseLockState
{
156 MOUSELOCK_NOT_REQUESTED
,
157 // The page requests to lock the mouse and the user hasn't responded to the
160 // Mouse lock has been allowed by the user.
162 // Mouse lock has been silently accepted, no notification to user.
163 MOUSELOCK_ACCEPTED_SILENTLY
166 enum FullscreenInternalOption
{
168 #if defined(OS_MACOSX)
174 void UpdateNotificationRegistrations();
176 // Posts a task to call NotifyFullscreenChange.
177 void PostFullscreenChangeNotification(bool is_fullscreen
);
178 // Sends a NOTIFICATION_FULLSCREEN_CHANGED notification.
179 void NotifyFullscreenChange(bool is_fullscreen
);
180 // Notifies the tab that it has been forced out of fullscreen and mouse lock
181 // mode if necessary.
182 void NotifyTabOfExitIfNecessary();
183 void NotifyMouseLockChange();
185 void ToggleFullscreenModeInternal(FullscreenInternalOption option
);
186 void EnterFullscreenModeInternal(FullscreenInternalOption option
);
187 void ExitFullscreenModeInternal();
188 void SetFullscreenedTab(content::WebContents
* tab
);
189 void SetMouseLockTab(content::WebContents
* tab
);
191 // Make the current tab exit fullscreen mode or mouse lock if it is in it.
192 void ExitTabFullscreenOrMouseLockIfNecessary();
193 void UpdateFullscreenExitBubbleContent();
195 ContentSetting
GetFullscreenSetting(const GURL
& url
) const;
196 ContentSetting
GetMouseLockSetting(const GURL
& url
) const;
198 bool IsPrivilegedFullscreenForTab() const;
199 void SetPrivilegedFullscreenForTesting(bool is_privileged
);
200 // Returns true if fullscreen-within-tab has been enabled for the
201 // |browser_|. See 'FullscreenWithinTab Note'.
202 bool IsFullscreenWithinTabPossible() const;
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
)
213 Browser
* const browser_
;
214 BrowserWindow
* const window_
;
215 Profile
* const profile_
;
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_
;
222 // The URL of the extension which trigerred "browser fullscreen" mode.
223 GURL extension_caused_fullscreen_
;
225 enum PriorFullscreenState
{
228 STATE_BROWSER_FULLSCREEN_NO_CHROME
,
229 #if defined(OS_MACOSX)
230 STATE_BROWSER_FULLSCREEN_WITH_CHROME
,
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_
;
240 // True if this controller has toggled into tab OR browser fullscreen.
241 bool toggled_into_fullscreen_
;
243 // WebContents for current tab requesting or currently in mouse lock.
244 // Assign using SetMouseLockTab().
245 content::WebContents
* mouse_lock_tab_
;
247 MouseLockState mouse_lock_state_
;
249 content::NotificationRegistrar registrar_
;
251 // Used to verify that calls we expect to reenter by calling
252 // WindowFullscreenStateChanged do so.
253 bool reentrant_window_state_change_call_check_
;
255 // A WebContents pointer is in this set if it entered fullscreen mode during
256 // screen capture. In other words, this tracks those WebContentses that are in
257 // fullscreen mode, but the browser window is not. See 'FullscreenWithinTab
259 std::set
<const content::WebContents
*> captured_tabs_
;
261 // Used in testing to confirm proper behavior for specific, privileged
263 bool is_privileged_fullscreen_for_testing_
;
265 base::WeakPtrFactory
<FullscreenController
> ptr_factory_
;
267 DISALLOW_COPY_AND_ASSIGN(FullscreenController
);
270 #endif // CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_H_