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 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