• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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