Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3043)

Unified Diff: chrome/browser/ui/fullscreen_controller.cc

Issue 8423035: Split out fullscreen logic from Browser into FullscreenController. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/fullscreen_controller.cc
diff --git a/chrome/browser/ui/fullscreen_controller.cc b/chrome/browser/ui/fullscreen_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..06747586826d9c6ac49f001a2e23ad34bf114b16
--- /dev/null
+++ b/chrome/browser/ui/fullscreen_controller.cc
@@ -0,0 +1,347 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/fullscreen_controller.h"
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/chrome_switches.h"
+#include "content/browser/user_metrics.h"
+#include "content/public/browser/notification_service.h"
+
+FullscreenController::FullscreenController(BrowserWindow* window,
+ Profile* profile,
+ Browser* browser)
+ : window_(window),
+ profile_(profile),
+ browser_(browser),
+ fullscreened_tab_(NULL),
+ tab_caused_fullscreen_(false),
+ tab_fullscreen_accepted_(false),
+ mouse_lock_state_(MOUSELOCK_NOT_REQUESTED) {
+}
+
+FullscreenController::~FullscreenController() {}
+
+bool FullscreenController::IsFullscreenForTab() const {
+ return fullscreened_tab_ != NULL;
+}
+
+bool FullscreenController::IsFullscreenForTab(const TabContents* tab) const {
+ const TabContentsWrapper* wrapper =
+ TabContentsWrapper::GetCurrentWrapperForContents(tab);
+ if (!wrapper || (wrapper != fullscreened_tab_))
+ return false;
+ DCHECK(tab == browser_->GetSelectedTabContents());
+ DCHECK(window_->IsFullscreen());
+ return true;
+}
+
+void FullscreenController::RequestToLockMouse(TabContents* tab) {
+ // Mouse Lock is only permitted when browser is in tab fullscreen.
+ if (!IsFullscreenForTab(tab)) {
+ tab->GotResponseToLockMouseRequest(false);
+ return;
+ }
+
+ if (mouse_lock_state_ == MOUSELOCK_ACCEPTED) {
+ tab->GotResponseToLockMouseRequest(true);
+ return;
+ }
+
+ switch (GetMouseLockSetting(tab->GetURL())) {
+ case CONTENT_SETTING_ALLOW:
+ mouse_lock_state_ = MOUSELOCK_ACCEPTED;
+ tab->GotResponseToLockMouseRequest(true);
+ break;
+ case CONTENT_SETTING_BLOCK:
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ tab->GotResponseToLockMouseRequest(false);
+ break;
+ case CONTENT_SETTING_ASK:
+ mouse_lock_state_ = MOUSELOCK_REQUESTED;
+ break;
+ default:
+ NOTREACHED();
+ }
+ UpdateFullscreenExitBubbleContent();
+}
+
+void FullscreenController::ToggleFullscreenModeForTab(TabContents* tab,
+ bool enter_fullscreen) {
+ if (tab != browser_->GetSelectedTabContents())
+ return;
+
+ bool in_browser_or_tab_fullscreen_mode;
+#if defined(OS_MACOSX)
+ in_browser_or_tab_fullscreen_mode = window_->InPresentationMode();
+#else
+ in_browser_or_tab_fullscreen_mode = window_->IsFullscreen();
+#endif
+
+ if (enter_fullscreen) {
+ fullscreened_tab_ = TabContentsWrapper::GetCurrentWrapperForContents(tab);
+ if (!in_browser_or_tab_fullscreen_mode) {
+ tab_caused_fullscreen_ = true;
+#if defined(OS_MACOSX)
+ TogglePresentationMode(true);
+#else
+ ToggleFullscreenMode(true);
+#endif
+ } else {
+ // We need to update the fullscreen exit bubble, e.g., going from browser
+ // fullscreen to tab fullscreen will need to show different content.
+ const GURL& url = tab->GetURL();
+ if (!tab_fullscreen_accepted_) {
+ tab_fullscreen_accepted_ =
+ GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
+ }
+ UpdateFullscreenExitBubbleContent();
+ }
+ } else {
+ if (in_browser_or_tab_fullscreen_mode) {
+ if (tab_caused_fullscreen_) {
+#if defined(OS_MACOSX)
+ TogglePresentationMode(true);
+#else
+ ToggleFullscreenMode(true);
+#endif
+ } else {
+ // If currently there is a tab in "tab fullscreen" mode and fullscreen
+ // was not caused by it (i.e., previously it was in "browser fullscreen"
+ // mode), we need to switch back to "browser fullscreen" mode. In this
+ // case, all we have to do is notifying the tab that it has exited "tab
+ // fullscreen" mode.
+ NotifyTabOfFullscreenExitIfNecessary();
+ }
+ }
+ }
+}
+
+#if defined(OS_MACOSX)
+void FullscreenController::TogglePresentationMode(bool for_tab) {
+ bool entering_fullscreen = !window_->InPresentationMode();
+ GURL url;
+ if (for_tab) {
+ url = browser_->GetSelectedTabContents()->GetURL();
+ tab_fullscreen_accepted_ = entering_fullscreen &&
+ GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
+ }
+ if (entering_fullscreen)
+ window_->EnterPresentationMode(url, GetFullscreenExitBubbleType());
+ else
+ window_->ExitPresentationMode();
+ WindowFullscreenStateChanged();
+}
+#endif
+
+// TODO(koz): Change |for_tab| to an enum.
+void FullscreenController::ToggleFullscreenMode(bool for_tab) {
+ bool entering_fullscreen = !window_->IsFullscreen();
+
+#if !defined(OS_MACOSX)
+ // In kiosk mode, we always want to be fullscreen. When the browser first
+ // starts we're not yet fullscreen, so let the initial toggle go through.
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) &&
+ window_->IsFullscreen())
+ return;
+#endif
+
+ GURL url;
+ if (for_tab) {
+ url = browser_->GetSelectedTabContents()->GetURL();
+ tab_fullscreen_accepted_ = entering_fullscreen &&
+ GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
+ } else {
+ UserMetrics::RecordAction(UserMetricsAction("ToggleFullscreen"));
+ }
+ if (entering_fullscreen)
+ window_->EnterFullscreen(url, GetFullscreenExitBubbleType());
+ else
+ window_->ExitFullscreen();
+
+ // Once the window has become fullscreen it'll call back to
+ // WindowFullscreenStateChanged(). We don't do this immediately as
+ // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let
+ // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate.
+
+ // TODO: convert mac to invoke WindowFullscreenStateChanged once it updates
+ // the necessary state of the frame.
+#if defined(OS_MACOSX)
+ WindowFullscreenStateChanged();
+#endif
+}
+
+void FullscreenController::LostMouseLock() {
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ UpdateFullscreenExitBubbleContent();
+}
+
+void FullscreenController::OnTabClosing(TabContents* tab_contents) {
+ if (IsFullscreenForTab(tab_contents)) {
+ ExitTabbedFullscreenModeIfNecessary();
+ // The call to exit fullscreen may result in asynchronous notification of
+ // fullscreen state change (e.g., on Linux). We don't want to rely on it
+ // to call NotifyTabOfFullscreenExitIfNecessary(), because at that point
+ // |fullscreen_tab_| may not be valid. Instead, we call it here to clean up
+ // tab fullscreen related state.
+ NotifyTabOfFullscreenExitIfNecessary();
+ }
+}
+
+void FullscreenController::OnTabDeactivated(TabContentsWrapper* contents) {
+ if (contents == fullscreened_tab_)
+ ExitTabbedFullscreenModeIfNecessary();
+}
+
+void FullscreenController::OnAcceptFullscreenPermission(
+ const GURL& url,
+ FullscreenExitBubbleType bubble_type) {
+ bool mouse_lock = false;
+ bool fullscreen = false;
+ fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen,
+ &mouse_lock);
+ DCHECK(fullscreened_tab_);
+ DCHECK_NE(tab_fullscreen_accepted_, fullscreen);
+
+ HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap();
+ if (mouse_lock) {
+ DCHECK_EQ(mouse_lock_state_, MOUSELOCK_REQUESTED);
+ settings_map->SetContentSetting(ContentSettingsPattern::FromURL(url),
+ ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_MOUSELOCK,
+ std::string(), CONTENT_SETTING_ALLOW);
+ mouse_lock_state_ =
+ fullscreened_tab_->tab_contents()->GotResponseToLockMouseRequest(true) ?
+ MOUSELOCK_ACCEPTED : MOUSELOCK_NOT_REQUESTED;
+ }
+ if (!tab_fullscreen_accepted_) {
+ settings_map->SetContentSetting(ContentSettingsPattern::FromURL(url),
+ ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_FULLSCREEN,
+ std::string(), CONTENT_SETTING_ALLOW);
+ tab_fullscreen_accepted_ = true;
+ }
+ UpdateFullscreenExitBubbleContent();
+}
+
+void FullscreenController::OnDenyFullscreenPermission(
+ FullscreenExitBubbleType bubble_type) {
+ bool mouse_lock = false;
+ bool fullscreen = false;
+ fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen,
+ &mouse_lock);
+ DCHECK(fullscreened_tab_);
+ DCHECK_NE(tab_fullscreen_accepted_, fullscreen);
+
+ if (mouse_lock) {
+ DCHECK_EQ(mouse_lock_state_, MOUSELOCK_REQUESTED);
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ fullscreened_tab_->tab_contents()->GotResponseToLockMouseRequest(false);
+ if (!fullscreen)
+ UpdateFullscreenExitBubbleContent();
+ }
+
+ if (fullscreen)
+ ExitTabbedFullscreenModeIfNecessary();
+}
+
+void FullscreenController::WindowFullscreenStateChanged() {
+ MessageLoop::current()->PostTask(FROM_HERE,
+ base::Bind(&FullscreenController::NotifyFullscreenChange, this));
sky 2011/12/08 23:34:13 I just came across this in tracking down a regress
koz (OOO until 15th September) 2011/12/08 23:45:39 This notification has always been async (see the d
+ bool notify_tab_of_exit;
+#if defined(OS_MACOSX)
+ notify_tab_of_exit = !window_->InPresentationMode();
+#else
+ notify_tab_of_exit = !window_->IsFullscreen();
+#endif
+ if (notify_tab_of_exit)
+ NotifyTabOfFullscreenExitIfNecessary();
+}
+
+bool FullscreenController::HandleUserPressedEscape() {
+ if (!IsFullscreenForTab())
+ return false;
+ ExitTabbedFullscreenModeIfNecessary();
+ return true;
+}
+
+void FullscreenController::NotifyTabOfFullscreenExitIfNecessary() {
+ if (fullscreened_tab_)
+ fullscreened_tab_->ExitFullscreenMode();
+ else
+ DCHECK_EQ(mouse_lock_state_, MOUSELOCK_NOT_REQUESTED);
+
+ fullscreened_tab_ = NULL;
+ tab_caused_fullscreen_ = false;
+ tab_fullscreen_accepted_ = false;
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+
+ UpdateFullscreenExitBubbleContent();
+}
+
+void FullscreenController::ExitTabbedFullscreenModeIfNecessary() {
+ if (tab_caused_fullscreen_)
+ ToggleFullscreenMode(false);
+ else
+ NotifyTabOfFullscreenExitIfNecessary();
+}
+
+void FullscreenController::UpdateFullscreenExitBubbleContent() {
+ GURL url;
+ if (fullscreened_tab_)
+ url = fullscreened_tab_->tab_contents()->GetURL();
+
+ window_->UpdateFullscreenExitBubbleContent(url,
+ GetFullscreenExitBubbleType());
+}
+
+void FullscreenController::NotifyFullscreenChange() {
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_FULLSCREEN_CHANGED,
+ content::Source<FullscreenController>(this),
+ content::NotificationService::NoDetails());
+}
+
+FullscreenExitBubbleType
+ FullscreenController::GetFullscreenExitBubbleType() const {
+ if (!fullscreened_tab_) {
+ DCHECK_EQ(MOUSELOCK_NOT_REQUESTED, mouse_lock_state_);
+ return FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION;
+ }
+ if (fullscreened_tab_ && !tab_fullscreen_accepted_) {
+ DCHECK_NE(MOUSELOCK_ACCEPTED, mouse_lock_state_);
+ return mouse_lock_state_ == MOUSELOCK_REQUESTED ?
+ FEB_TYPE_FULLSCREEN_MOUSELOCK_BUTTONS : FEB_TYPE_FULLSCREEN_BUTTONS;
+ }
+ if (mouse_lock_state_ == MOUSELOCK_REQUESTED)
+ return FEB_TYPE_MOUSELOCK_BUTTONS;
+ return mouse_lock_state_ == MOUSELOCK_ACCEPTED ?
+ FEB_TYPE_FULLSCREEN_MOUSELOCK_EXIT_INSTRUCTION :
+ FEB_TYPE_FULLSCREEN_EXIT_INSTRUCTION;
+}
+
+ContentSetting
Peter Kasting 2011/11/21 19:17:46 Nit: Prefer to wrap these next two functions like:
+ FullscreenController::GetFullscreenSetting(const GURL& url) const {
+ if (url.SchemeIsFile())
+ return CONTENT_SETTING_ALLOW;
+
+ return profile_->GetHostContentSettingsMap()->GetContentSetting(url, url,
+ CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string());
+
Peter Kasting 2011/11/21 19:17:46 Nit: Extra blank line
+}
+
+ContentSetting
+ FullscreenController::GetMouseLockSetting(const GURL& url) const {
+ if (url.SchemeIsFile())
+ return CONTENT_SETTING_ALLOW;
+
+ HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap();
+ return settings_map->GetContentSetting(url, url,
+ CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string());
+}

Powered by Google App Engine
This is Rietveld 408576698