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