Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / fullscreen / fullscreen_controller.h
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 "chrome/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 // 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
52 // capture pipeline.
53
54 // This class implements fullscreen and mouselock behaviour.
55 class FullscreenController : public content::NotificationObserver {
56  public:
57   explicit FullscreenController(Browser* browser);
58   virtual ~FullscreenController();
59
60   // Browser/User Fullscreen ///////////////////////////////////////////////////
61
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;
65
66   void ToggleFullscreenMode();
67
68   // Tab/HTML/Flash Fullscreen /////////////////////////////////////////////////
69
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.
73   //
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;
84
85   void ToggleFullscreenModeForTab(content::WebContents* web_contents,
86                                   bool enter_fullscreen);
87
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);
92
93   // Platform Fullscreen ///////////////////////////////////////////////////////
94
95   // Returns whether we are currently in a Metro snap view.
96   bool IsInMetroSnapMode();
97
98 #if defined(OS_WIN)
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);
102 #endif
103
104 #if defined(OS_MACOSX)
105   void ToggleFullscreenWithChrome();
106 #endif
107
108   // Mouse Lock ////////////////////////////////////////////////////////////////
109
110   bool IsMouseLockRequested() const;
111   bool IsMouseLocked() const;
112
113   void RequestToLockMouse(content::WebContents* web_contents,
114                           bool user_gesture,
115                           bool last_unlocked_by_target);
116
117   // Callbacks /////////////////////////////////////////////////////////////////
118
119   // Called by Browser::TabDeactivated.
120   void OnTabDeactivated(content::WebContents* web_contents);
121
122   // Called by Browser::ActiveTabChanged.
123   void OnTabDetachedFromView(content::WebContents* web_contents);
124
125   // Called by Browser::TabClosingAt.
126   void OnTabClosing(content::WebContents* web_contents);
127
128   // Called by Browser::WindowFullscreenStateChanged.
129   void WindowFullscreenStateChanged();
130
131   // Called by Browser::PreHandleKeyboardEvent.
132   bool HandleUserPressedEscape();
133
134   // Called by platform FullscreenExitBubble.
135   void ExitTabOrBrowserFullscreenToPreviousState();
136   void OnAcceptFullscreenPermission();
137   void OnDenyFullscreenPermission();
138
139   // Called by Browser::LostMouseLock.
140   void LostMouseLock();
141
142   // content::NotificationObserver:
143   virtual void Observe(int type,
144                        const content::NotificationSource& source,
145                        const content::NotificationDetails& details) OVERRIDE;
146
147   // Bubble Content ////////////////////////////////////////////////////////////
148
149   GURL GetFullscreenExitBubbleURL() const;
150   FullscreenExitBubbleType GetFullscreenExitBubbleType() const;
151
152  private:
153   friend class FullscreenControllerTest;
154
155   enum MouseLockState {
156     MOUSELOCK_NOT_REQUESTED,
157     // The page requests to lock the mouse and the user hasn't responded to the
158     // request.
159     MOUSELOCK_REQUESTED,
160     // Mouse lock has been allowed by the user.
161     MOUSELOCK_ACCEPTED,
162     // Mouse lock has been silently accepted, no notification to user.
163     MOUSELOCK_ACCEPTED_SILENTLY
164   };
165
166   enum FullscreenInternalOption {
167     BROWSER,
168 #if defined(OS_MACOSX)
169     BROWSER_WITH_CHROME,
170 #endif
171     TAB
172   };
173
174   void UpdateNotificationRegistrations();
175
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();
184
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);
190
191   // Make the current tab exit fullscreen mode or mouse lock if it is in it.
192   void ExitTabFullscreenOrMouseLockIfNecessary();
193   void UpdateFullscreenExitBubbleContent();
194
195   ContentSetting GetFullscreenSetting(const GURL& url) const;
196   ContentSetting GetMouseLockSetting(const GURL& url) const;
197
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)
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   // 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
258   // Note'.
259   std::set<const content::WebContents*> captured_tabs_;
260
261   // Used in testing to confirm proper behavior for specific, privileged
262   // fullscreen cases.
263   bool is_privileged_fullscreen_for_testing_;
264
265   base::WeakPtrFactory<FullscreenController> ptr_factory_;
266
267   DISALLOW_COPY_AND_ASSIGN(FullscreenController);
268 };
269
270 #endif  // CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_H_