summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsriramsr <sriramsr@chromium.org>2015-01-26 14:45:04 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-26 22:46:28 +0000
commita41db560b2f4f86d1b8b05bfbad6b0684314662a (patch)
tree1d166d91dc00bfe65160b8aa59b0b4f51592ed5b
parent3a9f3a8b726c46f9907a9b1d1658f3e0c6169377 (diff)
downloadchromium_src-a41db560b2f4f86d1b8b05bfbad6b0684314662a.zip
chromium_src-a41db560b2f4f86d1b8b05bfbad6b0684314662a.tar.gz
chromium_src-a41db560b2f4f86d1b8b05bfbad6b0684314662a.tar.bz2
Refactor fullscreen_controller.
Split FullscreenController to MouseController (and leave fullscreen related parts in original class). ExclusiveAccessManager is responsible for coordinating the different exclusive access controllers. BUG=166928 TEST=Requires MANUAL testing of fullscreen and pointer/mouse lock is required as tests are disabled for being flaky Review URL: https://codereview.chromium.org/836933005 Cr-Commit-Position: refs/heads/master@{#313159}
-rw-r--r--chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc16
-rw-r--r--chrome/browser/ui/browser.cc40
-rw-r--r--chrome/browser/ui/browser.h8
-rw-r--r--chrome/browser/ui/browser_commands.cc4
-rw-r--r--chrome/browser/ui/browser_commands_mac.cc4
-rw-r--r--chrome/browser/ui/browser_win.cc2
-rw-r--r--chrome/browser/ui/cocoa/browser_window_cocoa.mm4
-rw-r--r--chrome/browser/ui/cocoa/browser_window_controller_private.mm9
-rw-r--r--chrome/browser/ui/cocoa/exclusive_access_bubble_window_controller.mm9
-rw-r--r--chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc9
-rw-r--r--chrome/browser/ui/exclusive_access/exclusive_access_controller_base.cc93
-rw-r--r--chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h101
-rw-r--r--chrome/browser/ui/exclusive_access/exclusive_access_manager.cc119
-rw-r--r--chrome/browser/ui/exclusive_access/exclusive_access_manager.h69
-rw-r--r--chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc13
-rw-r--r--chrome/browser/ui/exclusive_access/fullscreen_controller.cc454
-rw-r--r--chrome/browser/ui/exclusive_access/fullscreen_controller.h120
-rw-r--r--chrome/browser/ui/exclusive_access/fullscreen_controller_state_test.cc12
-rw-r--r--chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc19
-rw-r--r--chrome/browser/ui/exclusive_access/fullscreen_controller_test.cc39
-rw-r--r--chrome/browser/ui/exclusive_access/fullscreen_controller_test.h4
-rw-r--r--chrome/browser/ui/exclusive_access/mouse_lock_controller.cc234
-rw-r--r--chrome/browser/ui/exclusive_access/mouse_lock_controller.h61
-rw-r--r--chrome/browser/ui/views/exclusive_access_bubble_views.cc9
-rw-r--r--chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc17
-rw-r--r--chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc12
-rw-r--r--chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc13
-rw-r--r--chrome/browser/ui/views/location_bar/zoom_bubble_view.cc13
-rw-r--r--chrome/browser/ui/views/location_bar/zoom_bubble_view.h3
-rw-r--r--chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc6
-rw-r--r--chrome/browser/ui/views/managed_full_screen_bubble_delegate_view.cc7
-rw-r--r--chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc1
-rw-r--r--chrome/chrome_browser_ui.gypi6
33 files changed, 988 insertions, 542 deletions
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
index d5558b8..8de336e 100644
--- a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
+++ b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
@@ -185,7 +185,10 @@ IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestFullscreenExit) {
browser_window->GetNativeWindow());
{
Waiter waiter(browser());
- browser()->fullscreen_controller()->ToggleBrowserFullscreenMode();
+ browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->ToggleBrowserFullscreenMode();
waiter.Wait(false /* not locked */, true /* full screen */);
EXPECT_TRUE(browser_window->IsFullscreen());
EXPECT_FALSE(window_state->hide_shelf_when_fullscreen());
@@ -208,7 +211,10 @@ IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestFullscreenExit) {
EXPECT_FALSE(tester->IsLocked());
{
Waiter waiter(browser());
- browser()->fullscreen_controller()->ToggleBrowserFullscreenMode();
+ browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->ToggleBrowserFullscreenMode();
waiter.Wait(false /* not locked */, false /* fullscreen */);
EXPECT_FALSE(browser_window->IsFullscreen());
}
@@ -220,8 +226,10 @@ IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestFullscreenExit) {
Waiter waiter(browser());
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
- browser()->fullscreen_controller()->EnterFullscreenModeForTab(
- web_contents, GURL());
+ browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->EnterFullscreenModeForTab(web_contents, GURL());
waiter.Wait(false /* not locked */, true /* fullscreen */);
EXPECT_TRUE(browser_window->IsFullscreen());
EXPECT_TRUE(window_state->hide_shelf_when_fullscreen());
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 1745f71..76085e9 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -104,6 +104,7 @@
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/chrome_select_file_policy.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
+#include "chrome/browser/ui/exclusive_access/mouse_lock_controller.h"
#include "chrome/browser/ui/fast_unload_controller.h"
#include "chrome/browser/ui/find_bar/find_bar.h"
#include "chrome/browser/ui/find_bar/find_bar_controller.h"
@@ -444,7 +445,7 @@ Browser::Browser(const CreateParams& params)
#endif // defined(OS_WIN)
}
- fullscreen_controller_.reset(new FullscreenController(this));
+ exclusive_access_manager_.reset(new ExclusiveAccessManager(this));
// Must be initialized after window_.
// Also: surprise! a modal dialog host is not necessary to host modal dialogs
@@ -784,7 +785,8 @@ Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads(
// Browser, Tab adding/showing functions:
void Browser::WindowFullscreenStateChanged() {
- fullscreen_controller_->WindowFullscreenStateChanged();
+ exclusive_access_manager_->fullscreen_controller()
+ ->WindowFullscreenStateChanged();
command_controller_->FullscreenStateChanged();
UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
}
@@ -793,8 +795,8 @@ void Browser::WindowFullscreenStateChanged() {
// Browser, Assorted browser commands:
void Browser::ToggleFullscreenModeWithExtension(const GURL& extension_url) {
- fullscreen_controller_->
- ToggleBrowserFullscreenModeWithExtension(extension_url);
+ exclusive_access_manager_->fullscreen_controller()
+ ->ToggleBrowserFullscreenModeWithExtension(extension_url);
}
bool Browser::SupportsWindowFeature(WindowFeature feature) const {
@@ -944,7 +946,7 @@ void Browser::TabInsertedAt(WebContents* contents,
void Browser::TabClosingAt(TabStripModel* tab_strip_model,
WebContents* contents,
int index) {
- fullscreen_controller_->OnTabClosing(contents);
+ exclusive_access_manager_->OnTabClosing(contents);
SessionService* session_service =
SessionServiceFactory::GetForProfile(profile_);
if (session_service)
@@ -980,7 +982,7 @@ void Browser::TabDetachedAt(WebContents* contents, int index) {
}
void Browser::TabDeactivated(WebContents* contents) {
- fullscreen_controller_->OnTabDeactivated(contents);
+ exclusive_access_manager_->OnTabDeactivated(contents);
search_delegate_->OnTabDeactivated(contents);
SearchTabHelper::FromWebContents(contents)->OnTabDeactivated();
@@ -1008,7 +1010,7 @@ void Browser::ActiveTabChanged(WebContents* old_contents,
// is updated.
window_->OnActiveTabChanged(old_contents, new_contents, index, reason);
- fullscreen_controller_->OnTabDetachedFromView(old_contents);
+ exclusive_access_manager_->OnTabDetachedFromView(old_contents);
// Discarded tabs always get reloaded.
if (tab_strip_model_->IsTabDiscarded(index)) {
@@ -1080,7 +1082,7 @@ void Browser::TabReplacedAt(TabStripModel* tab_strip_model,
WebContents* new_contents,
int index) {
TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
- fullscreen_controller_->OnTabClosing(old_contents);
+ exclusive_access_manager_->OnTabClosing(old_contents);
SessionService* session_service =
SessionServiceFactory::GetForProfile(profile_);
if (session_service)
@@ -1180,10 +1182,10 @@ bool Browser::ShouldPreserveAbortedURLs(WebContents* source) {
bool Browser::PreHandleKeyboardEvent(content::WebContents* source,
const NativeWebKeyboardEvent& event,
bool* is_keyboard_shortcut) {
- // Escape exits tabbed fullscreen mode.
+ // Escape exits tabbed fullscreen mode and mouse lock, and possibly others.
// TODO(koz): Write a test for this http://crbug.com/100441.
if (event.windowsKeyCode == 27 &&
- fullscreen_controller_->HandleUserPressedEscape()) {
+ exclusive_access_manager_->HandleUserPressedEscape()) {
return true;
}
return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
@@ -1261,7 +1263,7 @@ bool Browser::CanDragEnter(content::WebContents* source,
}
bool Browser::IsMouseLocked() const {
- return fullscreen_controller_->IsMouseLocked();
+ return exclusive_access_manager_->mouse_lock_controller()->IsMouseLocked();
}
void Browser::OnWindowDidShow() {
@@ -1665,16 +1667,19 @@ bool Browser::EmbedsFullscreenWidget() const {
void Browser::EnterFullscreenModeForTab(WebContents* web_contents,
const GURL& origin) {
- fullscreen_controller_->EnterFullscreenModeForTab(web_contents, origin);
+ exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab(
+ web_contents, origin);
}
void Browser::ExitFullscreenModeForTab(WebContents* web_contents) {
- fullscreen_controller_->ExitFullscreenModeForTab(web_contents);
+ exclusive_access_manager_->fullscreen_controller()->ExitFullscreenModeForTab(
+ web_contents);
}
bool Browser::IsFullscreenForTabOrPending(
const WebContents* web_contents) const {
- return fullscreen_controller_->IsFullscreenForTabOrPending(web_contents);
+ return exclusive_access_manager_->fullscreen_controller()
+ ->IsFullscreenForTabOrPending(web_contents);
}
void Browser::RegisterProtocolHandler(WebContents* web_contents,
@@ -1770,13 +1775,12 @@ void Browser::FindReply(WebContents* web_contents,
void Browser::RequestToLockMouse(WebContents* web_contents,
bool user_gesture,
bool last_unlocked_by_target) {
- fullscreen_controller_->RequestToLockMouse(web_contents,
- user_gesture,
- last_unlocked_by_target);
+ exclusive_access_manager_->mouse_lock_controller()->RequestToLockMouse(
+ web_contents, user_gesture, last_unlocked_by_target);
}
void Browser::LostMouseLock() {
- fullscreen_controller_->LostMouseLock();
+ exclusive_access_manager_->mouse_lock_controller()->LostMouseLock();
}
void Browser::RequestMediaAccessPermission(
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index e7aff35..b4b3033 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -24,6 +24,7 @@
#include "chrome/browser/ui/bookmarks/bookmark_tab_helper_delegate.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/search/search_tab_helper_delegate.h"
#include "chrome/browser/ui/search_engines/search_engine_tab_helper_delegate.h"
@@ -57,7 +58,6 @@ class BrowserToolbarModelDelegate;
class BrowserTabRestoreServiceDelegate;
class BrowserWindow;
class FindBarController;
-class FullscreenController;
class PrefService;
class Profile;
class SearchDelegate;
@@ -475,8 +475,8 @@ class Browser : public TabStripModelObserver,
// Show a download on the download shelf.
void ShowDownload(content::DownloadItem* download);
- FullscreenController* fullscreen_controller() const {
- return fullscreen_controller_.get();
+ ExclusiveAccessManager* exclusive_access_manager() {
+ return exclusive_access_manager_.get();
}
extensions::WindowController* extension_window_controller() const {
@@ -954,7 +954,7 @@ class Browser : public TabStripModelObserver,
BookmarkBar::State bookmark_bar_state_;
- scoped_ptr<FullscreenController> fullscreen_controller_;
+ scoped_ptr<ExclusiveAccessManager> exclusive_access_manager_;
scoped_ptr<extensions::WindowController> extension_window_controller_;
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index a9f6f9b..b3f36a6 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -1130,7 +1130,9 @@ void ToggleRequestTabletSite(Browser* browser) {
void ToggleFullscreenMode(Browser* browser) {
DCHECK(browser);
- browser->fullscreen_controller()->ToggleBrowserFullscreenMode();
+ browser->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->ToggleBrowserFullscreenMode();
}
void ClearCache(Browser* browser) {
diff --git a/chrome/browser/ui/browser_commands_mac.cc b/chrome/browser/ui/browser_commands_mac.cc
index 4974524..1cf43c6 100644
--- a/chrome/browser/ui/browser_commands_mac.cc
+++ b/chrome/browser/ui/browser_commands_mac.cc
@@ -16,7 +16,9 @@ namespace chrome {
void ToggleFullscreenWithToolbarOrFallback(Browser* browser) {
DCHECK(browser);
if (chrome::mac::SupportsSystemFullscreen())
- browser->fullscreen_controller()->ToggleBrowserFullscreenWithToolbar();
+ browser->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->ToggleBrowserFullscreenWithToolbar();
else
ToggleFullscreenMode(browser);
}
diff --git a/chrome/browser/ui/browser_win.cc b/chrome/browser/ui/browser_win.cc
index d655621f..ad4bdab 100644
--- a/chrome/browser/ui/browser_win.cc
+++ b/chrome/browser/ui/browser_win.cc
@@ -7,5 +7,5 @@
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
void Browser::SetMetroSnapMode(bool enable) {
- fullscreen_controller_->SetMetroSnapMode(enable);
+ exclusive_access_manager_->fullscreen_controller()->SetMetroSnapMode(enable);
}
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index c03fc97..c20de41 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -361,7 +361,9 @@ void BrowserWindowCocoa::Restore() {
void BrowserWindowCocoa::EnterFullscreen(const GURL& url,
ExclusiveAccessBubbleType bubble_type,
bool with_toolbar) {
- if (browser_->fullscreen_controller()->IsWindowFullscreenForTabOrPending())
+ if (browser_->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsWindowFullscreenForTabOrPending())
[controller_ enterWebContentFullscreenForURL:url bubbleType:bubble_type];
else if (!url.is_empty())
[controller_ enterExtensionFullscreenForURL:url bubbleType:bubble_type];
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
index f2c086b..1ed775b 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -426,8 +426,9 @@ willPositionSheet:(NSWindow*)sheet
}
- (void)configurePresentationModeController {
- BOOL fullscreen_for_tab =
- browser_->fullscreen_controller()->IsWindowFullscreenForTabOrPending();
+ BOOL fullscreen_for_tab = browser_->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsWindowFullscreenForTabOrPending();
BOOL kiosk_mode =
base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode);
BOOL showDropdown =
@@ -670,7 +671,9 @@ willPositionSheet:(NSWindow*)sheet
NSWindow* window = [self window];
savedRegularWindowFrame_ = [window frame];
BOOL mode = enteringPresentationMode_ ||
- browser_->fullscreen_controller()->IsWindowFullscreenForTabOrPending();
+ browser_->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsWindowFullscreenForTabOrPending();
enteringAppKitFullscreen_ = YES;
enteringAppKitFullscreenOnPrimaryScreen_ =
[[[self window] screen] isEqual:[[NSScreen screens] objectAtIndex:0]];
diff --git a/chrome/browser/ui/cocoa/exclusive_access_bubble_window_controller.mm b/chrome/browser/ui/cocoa/exclusive_access_bubble_window_controller.mm
index d6c0de1..6274888 100644
--- a/chrome/browser/ui/cocoa/exclusive_access_bubble_window_controller.mm
+++ b/chrome/browser/ui/cocoa/exclusive_access_bubble_window_controller.mm
@@ -96,12 +96,12 @@ const float kHideDuration = 0.7;
[[self window] setIgnoresMouseEvents:YES];
DCHECK(exclusive_access_bubble::ShowButtonsForType(bubbleType_));
- browser_->fullscreen_controller()->OnAcceptFullscreenPermission();
+ browser_->exclusive_access_manager()->OnAcceptExclusiveAccessPermission();
}
- (void)deny:(id)sender {
DCHECK(exclusive_access_bubble::ShowButtonsForType(bubbleType_));
- browser_->fullscreen_controller()->OnDenyFullscreenPermission();
+ browser_->exclusive_access_manager()->OnDenyExclusiveAccessPermission();
}
- (void)showButtons:(BOOL)show {
@@ -151,8 +151,9 @@ const float kHideDuration = 0.7;
- (BOOL)textView:(NSTextView*)textView
clickedOnLink:(id)link
atIndex:(NSUInteger)charIndex {
- browser_->fullscreen_controller()
- ->ExitTabOrBrowserFullscreenToPreviousState();
+ browser_->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->ExitExclusiveAccessToPreviousState();
return YES;
}
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc b/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc
index 3583024..178e97d 100644
--- a/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc
@@ -115,16 +115,17 @@ void ExclusiveAccessBubble::CheckMousePosition() {
}
void ExclusiveAccessBubble::ToggleFullscreen() {
- browser_->fullscreen_controller()
- ->ExitTabOrBrowserFullscreenToPreviousState();
+ browser_->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->ExitExclusiveAccessToPreviousState();
}
void ExclusiveAccessBubble::Accept() {
- browser_->fullscreen_controller()->OnAcceptFullscreenPermission();
+ browser_->exclusive_access_manager()->OnAcceptExclusiveAccessPermission();
}
void ExclusiveAccessBubble::Cancel() {
- browser_->fullscreen_controller()->OnDenyFullscreenPermission();
+ browser_->exclusive_access_manager()->OnDenyExclusiveAccessPermission();
}
base::string16 ExclusiveAccessBubble::GetCurrentMessageText() const {
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_controller_base.cc b/chrome/browser/ui/exclusive_access/exclusive_access_controller_base.cc
new file mode 100644
index 0000000..db8a243
--- /dev/null
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_controller_base.cc
@@ -0,0 +1,93 @@
+// Copyright (c) 2015 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/exclusive_access/exclusive_access_controller_base.h"
+
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "content/public/browser/navigation_details.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/web_contents.h"
+
+using content::WebContents;
+
+ExclusiveAccessControllerBase::ExclusiveAccessControllerBase(
+ ExclusiveAccessManager* manager,
+ Browser* browser)
+ : manager_(manager),
+ browser_(browser),
+ profile_(browser->profile()),
+ tab_with_exclusive_access_(nullptr) {
+ DCHECK(profile_);
+}
+
+ExclusiveAccessControllerBase::~ExclusiveAccessControllerBase() {
+}
+
+GURL ExclusiveAccessControllerBase::GetExclusiveAccessBubbleURL() const {
+ return manager_->GetExclusiveAccessBubbleURL();
+}
+
+GURL ExclusiveAccessControllerBase::GetURLForExclusiveAccessBubble() const {
+ if (tab_with_exclusive_access_)
+ return tab_with_exclusive_access_->GetURL();
+ return GURL();
+}
+
+void ExclusiveAccessControllerBase::OnTabDeactivated(
+ WebContents* web_contents) {
+ if (web_contents == tab_with_exclusive_access_)
+ ExitExclusiveAccessIfNecessary();
+}
+
+void ExclusiveAccessControllerBase::OnTabDetachedFromView(
+ WebContents* old_contents) {
+ // Derived class will have to implement if necessary.
+}
+
+void ExclusiveAccessControllerBase::OnTabClosing(WebContents* web_contents) {
+ if (web_contents == tab_with_exclusive_access_) {
+ ExitExclusiveAccessIfNecessary();
+
+ // The call to exit exclusive access may result in asynchronous notification
+ // of state change (e.g. fullscreen change on Linux). We don't want to rely
+ // on it to call NotifyTabExclusiveAccessLost(), because at that point
+ // |tab_with_exclusive_access_| may not be valid. Instead, we call it here
+ // to clean up exclusive access tab related state.
+ NotifyTabExclusiveAccessLost();
+ }
+}
+
+void ExclusiveAccessControllerBase::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ DCHECK_EQ(content::NOTIFICATION_NAV_ENTRY_COMMITTED, type);
+ if (content::Details<content::LoadCommittedDetails>(details)
+ ->is_navigation_to_different_page())
+ ExitExclusiveAccessIfNecessary();
+}
+
+void ExclusiveAccessControllerBase::SetTabWithExclusiveAccess(
+ WebContents* tab) {
+ // Tab should never be replaced with another tab, or
+ // UpdateNotificationRegistrations would need updating.
+ DCHECK(tab_with_exclusive_access_ == tab ||
+ tab_with_exclusive_access_ == nullptr || tab == nullptr);
+ tab_with_exclusive_access_ = tab;
+ UpdateNotificationRegistrations();
+}
+
+void ExclusiveAccessControllerBase::UpdateNotificationRegistrations() {
+ if (tab_with_exclusive_access_ && registrar_.IsEmpty()) {
+ registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
+ content::Source<content::NavigationController>(
+ &tab_with_exclusive_access_->GetController()));
+ } else if (!tab_with_exclusive_access_ && !registrar_.IsEmpty()) {
+ registrar_.RemoveAll();
+ }
+}
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h b/chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h
new file mode 100644
index 0000000..99c5614
--- /dev/null
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2015 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.
+
+#ifndef CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_EXCLUSIVE_ACCESS_CONTROLLER_BASE_H_
+#define CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_EXCLUSIVE_ACCESS_CONTROLLER_BASE_H_
+
+#include "base/basictypes.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+
+class Browser;
+class BrowserWindow;
+class ExclusiveAccessManager;
+class GURL;
+class Profile;
+
+namespace content {
+class WebContents;
+}
+
+// The base class for the different exclusive access controllers like the
+// FullscreenController, and MouseLockController which controls lifetime for
+// which the resource (screen/mouse) is held exclusively.
+class ExclusiveAccessControllerBase : public content::NotificationObserver {
+ public:
+ explicit ExclusiveAccessControllerBase(ExclusiveAccessManager* manager,
+ Browser* browser);
+ ~ExclusiveAccessControllerBase() override;
+
+ GURL GetExclusiveAccessBubbleURL() const;
+ virtual GURL GetURLForExclusiveAccessBubble() const;
+
+ content::WebContents* exclusive_access_tab() const {
+ return tab_with_exclusive_access_;
+ }
+
+ // Functions implemented by derived classes:
+
+ // Control behavior when escape is pressed returning true if it was handled.
+ virtual bool HandleUserPressedEscape() = 0;
+
+ // Called by Browser in response to call from ExclusiveAccessBubble.
+ virtual void ExitExclusiveAccessToPreviousState() = 0;
+
+ // Called to indicate that the permission for this exclusive access has been
+ // granted if requested. Returns true if the exit bubble content should be
+ // updated.
+ virtual bool OnAcceptExclusiveAccessPermission() = 0;
+
+ // Called to indicate that the permission for the exclusive access has been
+ // denied if requested. Returns true if the exit bubble content should be
+ // updated.
+ virtual bool OnDenyExclusiveAccessPermission() = 0;
+
+ // Called by ExclusiveAccessManager in response to calls from Browser.
+ virtual void OnTabDeactivated(content::WebContents* web_contents);
+ virtual void OnTabDetachedFromView(content::WebContents* web_contents);
+ virtual void OnTabClosing(content::WebContents* web_contents);
+
+ // Callbacks ////////////////////////////////////////////////////////////////
+
+ // content::NotificationObserver to detect page navigation and exit exclusive
+ // access.
+ void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) override;
+
+ protected:
+ void SetTabWithExclusiveAccess(content::WebContents* tab);
+
+ ExclusiveAccessManager* exclusive_access_manager() const { return manager_; }
+
+ Browser* browser() const { return browser_; }
+
+ Profile* profile() const { return profile_; }
+
+ // Exits exclusive access mode for the tab if currently exclusive.
+ virtual void ExitExclusiveAccessIfNecessary() = 0;
+
+ // Notifies the tab that it has been forced out of exclusive access mode
+ // if necessary.
+ virtual void NotifyTabExclusiveAccessLost() = 0;
+
+ private:
+ void UpdateNotificationRegistrations();
+
+ ExclusiveAccessManager* const manager_;
+ Browser* const browser_;
+ Profile* const profile_;
+
+ content::NotificationRegistrar registrar_;
+
+ content::WebContents* tab_with_exclusive_access_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExclusiveAccessControllerBase);
+};
+
+#endif // CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_EXCLUSIVE_ACCESS_CONTROLLER_BASE_H_
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc b/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc
new file mode 100644
index 0000000..56a8cc6
--- /dev/null
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc
@@ -0,0 +1,119 @@
+// Copyright (c) 2015 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/exclusive_access/exclusive_access_manager.h"
+
+#include "chrome/browser/app_mode/app_mode_utils.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
+#include "chrome/browser/ui/exclusive_access/mouse_lock_controller.h"
+
+using content::WebContents;
+
+ExclusiveAccessManager::ExclusiveAccessManager(Browser* browser)
+ : browser_(browser),
+ fullscreen_controller_(this, browser),
+ mouse_lock_controller_(this, browser) {
+}
+
+ExclusiveAccessManager::~ExclusiveAccessManager() {
+}
+
+ExclusiveAccessBubbleType
+ExclusiveAccessManager::GetExclusiveAccessExitBubbleType() const {
+ // In kiosk and exclusive app mode we always want to be fullscreen and do not
+ // want to show exit instructions for browser mode fullscreen.
+ bool app_mode = false;
+#if !defined(OS_MACOSX) // App mode (kiosk) is not available on Mac yet.
+ app_mode = chrome::IsRunningInAppMode();
+#endif
+
+ if (mouse_lock_controller_.IsMouseLockSilentlyAccepted() &&
+ (!fullscreen_controller_.IsWindowFullscreenForTabOrPending() ||
+ fullscreen_controller_.IsUserAcceptedFullscreen()))
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE;
+
+ if (!fullscreen_controller_.IsWindowFullscreenForTabOrPending()) {
+ if (mouse_lock_controller_.IsMouseLocked())
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_MOUSELOCK_EXIT_INSTRUCTION;
+ if (mouse_lock_controller_.IsMouseLockRequested())
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_MOUSELOCK_BUTTONS;
+ if (fullscreen_controller_.IsExtensionFullscreenOrPending())
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION;
+ if (fullscreen_controller_.IsControllerInitiatedFullscreen() && !app_mode)
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION;
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE;
+ }
+
+ if (fullscreen_controller_.IsUserAcceptedFullscreen()) {
+ if (fullscreen_controller_.IsPrivilegedFullscreenForTab())
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE;
+ if (mouse_lock_controller_.IsMouseLocked())
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_MOUSELOCK_EXIT_INSTRUCTION;
+ if (mouse_lock_controller_.IsMouseLockRequested())
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_MOUSELOCK_BUTTONS;
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_EXIT_INSTRUCTION;
+ }
+
+ if (mouse_lock_controller_.IsMouseLockRequested())
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_MOUSELOCK_BUTTONS;
+ return EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_BUTTONS;
+}
+
+void ExclusiveAccessManager::UpdateExclusiveAccessExitBubbleContent() {
+ GURL url = GetExclusiveAccessBubbleURL();
+ ExclusiveAccessBubbleType bubble_type = GetExclusiveAccessExitBubbleType();
+
+ // If bubble displays buttons, unlock mouse to allow pressing them.
+ if (exclusive_access_bubble::ShowButtonsForType(bubble_type) &&
+ mouse_lock_controller_.IsMouseLocked())
+ mouse_lock_controller_.UnlockMouse();
+
+ browser_->window()->UpdateFullscreenExitBubbleContent(url, bubble_type);
+}
+
+GURL ExclusiveAccessManager::GetExclusiveAccessBubbleURL() const {
+ GURL result = fullscreen_controller_.GetURLForExclusiveAccessBubble();
+ if (!result.is_valid())
+ result = mouse_lock_controller_.GetURLForExclusiveAccessBubble();
+ return result;
+}
+
+void ExclusiveAccessManager::OnTabDeactivated(WebContents* web_contents) {
+ fullscreen_controller_.OnTabDeactivated(web_contents);
+ mouse_lock_controller_.OnTabDeactivated(web_contents);
+}
+
+void ExclusiveAccessManager::OnTabDetachedFromView(WebContents* web_contents) {
+ fullscreen_controller_.OnTabDetachedFromView(web_contents);
+ mouse_lock_controller_.OnTabDetachedFromView(web_contents);
+}
+
+void ExclusiveAccessManager::OnTabClosing(WebContents* web_contents) {
+ fullscreen_controller_.OnTabClosing(web_contents);
+ mouse_lock_controller_.OnTabClosing(web_contents);
+}
+
+bool ExclusiveAccessManager::HandleUserPressedEscape() {
+ bool handled = false;
+ handled = fullscreen_controller_.HandleUserPressedEscape();
+ handled |= mouse_lock_controller_.HandleUserPressedEscape();
+ return handled;
+}
+
+void ExclusiveAccessManager::OnAcceptExclusiveAccessPermission() {
+ bool updateBubble =
+ mouse_lock_controller_.OnAcceptExclusiveAccessPermission();
+ updateBubble |= fullscreen_controller_.OnAcceptExclusiveAccessPermission();
+ if (updateBubble)
+ UpdateExclusiveAccessExitBubbleContent();
+}
+
+void ExclusiveAccessManager::OnDenyExclusiveAccessPermission() {
+ bool updateBubble = mouse_lock_controller_.OnDenyExclusiveAccessPermission();
+ updateBubble |= fullscreen_controller_.OnDenyExclusiveAccessPermission();
+ if (updateBubble)
+ UpdateExclusiveAccessExitBubbleContent();
+}
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_manager.h b/chrome/browser/ui/exclusive_access/exclusive_access_manager.h
new file mode 100644
index 0000000..0c10fe5
--- /dev/null
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_manager.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2015 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.
+
+#ifndef CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_EXCLUSIVE_ACCESS_MANAGER_H_
+#define CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_EXCLUSIVE_ACCESS_MANAGER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h"
+#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
+#include "chrome/browser/ui/exclusive_access/mouse_lock_controller.h"
+
+class Browser;
+class FullscreenController;
+class GURL;
+class MouseLockController;
+
+namespace content {
+class WebContents;
+}
+
+// This class combines the different exclusive access modes (like fullscreen and
+// mouse lock) which are each handled by respective controller. It also updates
+// the exit bubble to reflect the combined state.
+class ExclusiveAccessManager {
+ public:
+ explicit ExclusiveAccessManager(Browser* browser);
+ ~ExclusiveAccessManager();
+
+ FullscreenController* fullscreen_controller() {
+ return &fullscreen_controller_;
+ }
+
+ MouseLockController* mouse_lock_controller() {
+ return &mouse_lock_controller_;
+ }
+
+ ExclusiveAccessBubbleType GetExclusiveAccessExitBubbleType() const;
+ void UpdateExclusiveAccessExitBubbleContent();
+
+ GURL GetExclusiveAccessBubbleURL() const;
+
+ // Callbacks ////////////////////////////////////////////////////////////////
+
+ // Called by Browser::TabDeactivated.
+ void OnTabDeactivated(content::WebContents* web_contents);
+
+ // Called by Browser::ActiveTabChanged.
+ void OnTabDetachedFromView(content::WebContents* web_contents);
+
+ // Called by Browser::TabClosingAt.
+ void OnTabClosing(content::WebContents* web_contents);
+
+ // Called by Browser::PreHandleKeyboardEvent
+ bool HandleUserPressedEscape();
+
+ // Called by platform ExclusiveAccessExitBubble.
+ void OnAcceptExclusiveAccessPermission();
+ void OnDenyExclusiveAccessPermission();
+
+ private:
+ Browser* const browser_;
+ FullscreenController fullscreen_controller_;
+ MouseLockController mouse_lock_controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExclusiveAccessManager);
+};
+
+#endif // CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_EXCLUSIVE_ACCESS_MANAGER_H_
diff --git a/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc
index 7102b0e..ef37aa5 100644
--- a/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc
@@ -147,8 +147,10 @@ class FlashFullscreenInteractiveBrowserTest : public OutOfProcessPPAPITest {
return false;
}
EXPECT_EQ(GetActiveWebContents()->GetCapturerCount() > 0,
- !browser()->fullscreen_controller()->
- IsWindowFullscreenForTabOrPending());
+ !browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsWindowFullscreenForTabOrPending());
}
return true;
@@ -187,8 +189,11 @@ class FlashFullscreenInteractiveBrowserTest : public OutOfProcessPPAPITest {
private:
bool IsObservingTabInFullscreen(content::WebContents* contents,
bool expected_in_fullscreen) const {
- return expected_in_fullscreen == browser()->fullscreen_controller()->
- IsFullscreenForTabOrPending(contents);
+ return expected_in_fullscreen ==
+ browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsFullscreenForTabOrPending(contents);
}
bool IsObservingFlashHasFocus(content::WebContents* contents,
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
index 39cdac29..b37d04c 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
@@ -37,28 +37,22 @@ using base::UserMetricsAction;
using content::RenderViewHost;
using content::WebContents;
-FullscreenController::FullscreenController(Browser* browser)
- : browser_(browser),
- window_(browser->window()),
- profile_(browser->profile()),
- fullscreened_tab_(NULL),
+FullscreenController::FullscreenController(ExclusiveAccessManager* manager,
+ Browser* browser)
+ : ExclusiveAccessControllerBase(manager, browser),
state_prior_to_tab_fullscreen_(STATE_INVALID),
tab_fullscreen_accepted_(false),
toggled_into_fullscreen_(false),
- mouse_lock_tab_(NULL),
- mouse_lock_state_(MOUSELOCK_NOT_REQUESTED),
reentrant_window_state_change_call_check_(false),
is_privileged_fullscreen_for_testing_(false),
ptr_factory_(this) {
- DCHECK(window_);
- DCHECK(profile_);
}
FullscreenController::~FullscreenController() {
}
bool FullscreenController::IsFullscreenForBrowser() const {
- return window_->IsFullscreen() && !IsFullscreenCausedByTab();
+ return browser()->window()->IsFullscreen() && !IsFullscreenCausedByTab();
}
void FullscreenController::ToggleBrowserFullscreenMode() {
@@ -79,13 +73,26 @@ void FullscreenController::ToggleBrowserFullscreenModeWithExtension(
}
bool FullscreenController::IsWindowFullscreenForTabOrPending() const {
- return fullscreened_tab_ != NULL;
+ return exclusive_access_tab() != nullptr;
+}
+
+bool FullscreenController::IsExtensionFullscreenOrPending() const {
+ return !extension_caused_fullscreen_.is_empty();
+}
+
+bool FullscreenController::IsControllerInitiatedFullscreen() const {
+ return toggled_into_fullscreen_;
+}
+
+bool FullscreenController::IsUserAcceptedFullscreen() const {
+ return tab_fullscreen_accepted_;
}
bool FullscreenController::IsFullscreenForTabOrPending(
const WebContents* web_contents) const {
- if (web_contents == fullscreened_tab_) {
- DCHECK(web_contents == browser_->tab_strip_model()->GetActiveWebContents());
+ if (web_contents == exclusive_access_tab()) {
+ DCHECK(web_contents ==
+ browser()->tab_strip_model()->GetActiveWebContents());
DCHECK(web_contents->GetCapturerCount() == 0);
return true;
}
@@ -106,7 +113,7 @@ void FullscreenController::EnterFullscreenModeForTab(WebContents* web_contents,
return;
}
- if (web_contents != browser_->tab_strip_model()->GetActiveWebContents() ||
+ if (web_contents != browser()->tab_strip_model()->GetActiveWebContents() ||
IsWindowFullscreenForTabOrPending()) {
return;
}
@@ -120,18 +127,21 @@ void FullscreenController::EnterFullscreenModeForTab(WebContents* web_contents,
return;
#endif
- SetFullscreenedTab(web_contents, origin);
+ SetTabWithExclusiveAccess(web_contents);
+ fullscreened_origin_ = origin;
+
+ BrowserWindow* window = browser()->window();
- if (!window_->IsFullscreen()) {
+ if (!window->IsFullscreen()) {
// Normal -> Tab Fullscreen.
state_prior_to_tab_fullscreen_ = STATE_NORMAL;
ToggleFullscreenModeInternal(TAB);
return;
}
- if (window_->IsFullscreenWithToolbar()) {
+ if (window->IsFullscreenWithToolbar()) {
// Browser Fullscreen with Toolbar -> Tab Fullscreen (no toolbar).
- window_->UpdateFullscreenWithToolbar(false);
+ window->UpdateFullscreenWithToolbar(false);
state_prior_to_tab_fullscreen_ = STATE_BROWSER_FULLSCREEN_WITH_TOOLBAR;
} else {
// Browser Fullscreen without Toolbar -> Tab Fullscreen.
@@ -143,7 +153,7 @@ void FullscreenController::EnterFullscreenModeForTab(WebContents* web_contents,
if (!tab_fullscreen_accepted_) {
tab_fullscreen_accepted_ = GetFullscreenSetting() == CONTENT_SETTING_ALLOW;
}
- UpdateFullscreenExitBubbleContent();
+ exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent();
// This is only a change between Browser and Tab fullscreen. We generate
// a fullscreen notification now because there is no window change.
@@ -158,7 +168,7 @@ void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents) {
}
if (!IsWindowFullscreenForTabOrPending() ||
- web_contents != fullscreened_tab_) {
+ web_contents != exclusive_access_tab()) {
return;
}
@@ -171,7 +181,8 @@ void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents) {
return;
#endif
- if (!window_->IsFullscreen())
+ BrowserWindow* window = browser()->window();
+ if (!window->IsFullscreen())
return;
if (IsFullscreenCausedByTab()) {
@@ -183,12 +194,12 @@ void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents) {
// Tab Fullscreen -> Browser Fullscreen (with or without toolbar).
if (state_prior_to_tab_fullscreen_ == STATE_BROWSER_FULLSCREEN_WITH_TOOLBAR) {
// Tab Fullscreen (no toolbar) -> Browser Fullscreen with Toolbar.
- window_->UpdateFullscreenWithToolbar(true);
+ window->UpdateFullscreenWithToolbar(true);
}
#if defined(OS_MACOSX)
// Clear the bubble URL, which forces the Mac UI to redraw.
- UpdateFullscreenExitBubbleContent();
+ exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent();
#endif // defined(OS_MACOSX)
// If currently there is a tab in "tab fullscreen" mode and fullscreen
@@ -196,7 +207,7 @@ void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents) {
// 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.
- NotifyTabOfExitIfNecessary();
+ NotifyTabExclusiveAccessLost();
// This is only a change between Browser and Tab fullscreen. We generate
// a fullscreen notification now because there is no window change.
@@ -205,7 +216,7 @@ void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents) {
bool FullscreenController::IsInMetroSnapMode() {
#if defined(OS_WIN)
- return window_->IsInMetroSnapMode();
+ return browser()->window()->IsInMetroSnapMode();
#else
return false;
#endif
@@ -216,7 +227,7 @@ void FullscreenController::SetMetroSnapMode(bool enable) {
reentrant_window_state_change_call_check_ = false;
toggled_into_fullscreen_ = false;
- window_->SetMetroSnapMode(enable);
+ browser()->window()->SetMetroSnapMode(enable);
// FullscreenController unit tests for metro snap assume that on Windows calls
// to WindowFullscreenStateChanged are reentrant. If that assumption is
@@ -225,73 +236,6 @@ void FullscreenController::SetMetroSnapMode(bool enable) {
}
#endif // defined(OS_WIN)
-bool FullscreenController::IsMouseLockRequested() const {
- return mouse_lock_state_ == MOUSELOCK_REQUESTED;
-}
-
-bool FullscreenController::IsMouseLocked() const {
- return mouse_lock_state_ == MOUSELOCK_ACCEPTED ||
- mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY;
-}
-
-void FullscreenController::RequestToLockMouse(WebContents* web_contents,
- bool user_gesture,
- bool last_unlocked_by_target) {
- DCHECK(!IsMouseLocked());
- NotifyMouseLockChange();
-
- // Must have a user gesture to prevent misbehaving sites from constantly
- // re-locking the mouse. Exceptions are when the page has unlocked
- // (i.e. not the user), or if we're in tab fullscreen (user gesture required
- // for that)
- if (!last_unlocked_by_target && !user_gesture &&
- !IsFullscreenForTabOrPending(web_contents)) {
- web_contents->GotResponseToLockMouseRequest(false);
- return;
- }
- SetMouseLockTab(web_contents);
- ExclusiveAccessBubbleType bubble_type = GetExclusiveAccessBubbleType();
-
- switch (GetMouseLockSetting(web_contents->GetURL())) {
- case CONTENT_SETTING_ALLOW:
- // If bubble already displaying buttons we must not lock the mouse yet,
- // or it would prevent pressing those buttons. Instead, merge the request.
- if (!IsPrivilegedFullscreenForTab() &&
- exclusive_access_bubble::ShowButtonsForType(bubble_type)) {
- mouse_lock_state_ = MOUSELOCK_REQUESTED;
- } else {
- // Lock mouse.
- if (web_contents->GotResponseToLockMouseRequest(true)) {
- if (last_unlocked_by_target) {
- mouse_lock_state_ = MOUSELOCK_ACCEPTED_SILENTLY;
- } else {
- mouse_lock_state_ = MOUSELOCK_ACCEPTED;
- }
- } else {
- SetMouseLockTab(NULL);
- mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
- }
- }
- break;
- case CONTENT_SETTING_BLOCK:
- web_contents->GotResponseToLockMouseRequest(false);
- SetMouseLockTab(NULL);
- mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
- break;
- case CONTENT_SETTING_ASK:
- mouse_lock_state_ = MOUSELOCK_REQUESTED;
- break;
- default:
- NOTREACHED();
- }
- UpdateFullscreenExitBubbleContent();
-}
-
-void FullscreenController::OnTabDeactivated(WebContents* web_contents) {
- if (web_contents == fullscreened_tab_ || web_contents == mouse_lock_tab_)
- ExitTabFullscreenOrMouseLockIfNecessary();
-}
-
void FullscreenController::OnTabDetachedFromView(WebContents* old_contents) {
if (!IsFullscreenForCapturedTab(old_contents))
return;
@@ -327,97 +271,63 @@ void FullscreenController::OnTabDetachedFromView(WebContents* old_contents) {
void FullscreenController::OnTabClosing(WebContents* web_contents) {
if (IsFullscreenForCapturedTab(web_contents)) {
web_contents->ExitFullscreen();
- } else if (web_contents == fullscreened_tab_ ||
- web_contents == mouse_lock_tab_) {
- ExitTabFullscreenOrMouseLockIfNecessary();
- // 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 NotifyTabOfExitIfNecessary(), because at that point
- // |fullscreened_tab_| may not be valid. Instead, we call it here to clean
- // up tab fullscreen related state.
- NotifyTabOfExitIfNecessary();
+ } else {
+ ExclusiveAccessControllerBase::OnTabClosing(web_contents);
}
}
void FullscreenController::WindowFullscreenStateChanged() {
reentrant_window_state_change_call_check_ = true;
- bool exiting_fullscreen = !window_->IsFullscreen();
+ BrowserWindow* const window = browser()->window();
+ bool exiting_fullscreen = !window->IsFullscreen();
PostFullscreenChangeNotification(!exiting_fullscreen);
if (exiting_fullscreen) {
toggled_into_fullscreen_ = false;
extension_caused_fullscreen_ = GURL();
- NotifyTabOfExitIfNecessary();
+ NotifyTabExclusiveAccessLost();
}
if (exiting_fullscreen) {
- window_->GetDownloadShelf()->Unhide();
+ window->GetDownloadShelf()->Unhide();
} else {
- window_->GetDownloadShelf()->Hide();
- if (window_->GetStatusBubble())
- window_->GetStatusBubble()->Hide();
+ window->GetDownloadShelf()->Hide();
+ if (window->GetStatusBubble())
+ window->GetStatusBubble()->Hide();
}
}
bool FullscreenController::HandleUserPressedEscape() {
WebContents* const active_web_contents =
- browser_->tab_strip_model()->GetActiveWebContents();
+ browser()->tab_strip_model()->GetActiveWebContents();
if (IsFullscreenForCapturedTab(active_web_contents)) {
active_web_contents->ExitFullscreen();
return true;
- } else if (IsWindowFullscreenForTabOrPending() ||
- IsMouseLocked() || IsMouseLockRequested()) {
- ExitTabFullscreenOrMouseLockIfNecessary();
+ } else if (IsWindowFullscreenForTabOrPending()) {
+ ExitExclusiveAccessIfNecessary();
return true;
}
return false;
}
-void FullscreenController::ExitTabOrBrowserFullscreenToPreviousState() {
+void FullscreenController::ExitExclusiveAccessToPreviousState() {
if (IsWindowFullscreenForTabOrPending())
- ExitTabFullscreenOrMouseLockIfNecessary();
+ ExitFullscreenModeForTab(exclusive_access_tab());
else if (IsFullscreenForBrowser())
ExitFullscreenModeInternal();
}
-void FullscreenController::OnAcceptFullscreenPermission() {
- ExclusiveAccessBubbleType bubble_type = GetExclusiveAccessBubbleType();
- bool mouse_lock = false;
+bool FullscreenController::OnAcceptExclusiveAccessPermission() {
+ ExclusiveAccessBubbleType bubble_type =
+ exclusive_access_manager()->GetExclusiveAccessExitBubbleType();
bool fullscreen = false;
exclusive_access_bubble::PermissionRequestedByType(bubble_type, &fullscreen,
- &mouse_lock);
+ nullptr);
DCHECK(!(fullscreen && tab_fullscreen_accepted_));
- DCHECK(!(mouse_lock && IsMouseLocked()));
-
- HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap();
-
- if (mouse_lock && !IsMouseLocked()) {
- DCHECK(IsMouseLockRequested());
-
- GURL url = GetFullscreenExitBubbleURL();
- ContentSettingsPattern pattern = ContentSettingsPattern::FromURL(url);
-
- // TODO(markusheintz): We should allow patterns for all possible URLs here.
- if (pattern.IsValid()) {
- settings_map->SetContentSetting(
- pattern, ContentSettingsPattern::Wildcard(),
- CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string(),
- CONTENT_SETTING_ALLOW);
- }
-
- if (mouse_lock_tab_ &&
- mouse_lock_tab_->GotResponseToLockMouseRequest(true)) {
- mouse_lock_state_ = MOUSELOCK_ACCEPTED;
- } else {
- mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
- SetMouseLockTab(NULL);
- }
- NotifyMouseLockChange();
- }
if (fullscreen && !tab_fullscreen_accepted_) {
- DCHECK(fullscreened_tab_);
+ DCHECK(exclusive_access_tab());
// Origins can enter fullscreen even when embedded in other origins.
// Permission is tracked based on the combinations of requester and
// embedder. Thus, even if a requesting origin has been previously approved
@@ -438,112 +348,39 @@ void FullscreenController::OnAcceptFullscreenPermission() {
// ContentSettings requires valid patterns and the patterns might be invalid
// in some edge cases like if the current frame is about:blank.
if (primary_pattern.IsValid() && secondary_pattern.IsValid()) {
+ HostContentSettingsMap* settings_map =
+ profile()->GetHostContentSettingsMap();
settings_map->SetContentSetting(
primary_pattern, secondary_pattern, CONTENT_SETTINGS_TYPE_FULLSCREEN,
std::string(), CONTENT_SETTING_ALLOW);
}
tab_fullscreen_accepted_ = true;
- }
- UpdateFullscreenExitBubbleContent();
-}
-
-void FullscreenController::OnDenyFullscreenPermission() {
- if (!fullscreened_tab_ && !mouse_lock_tab_)
- return;
-
- if (IsMouseLockRequested()) {
- mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
- if (mouse_lock_tab_)
- mouse_lock_tab_->GotResponseToLockMouseRequest(false);
- SetMouseLockTab(NULL);
- NotifyMouseLockChange();
-
- // UpdateFullscreenExitBubbleContent() must be called, but to avoid
- // duplicate calls we do so only if not adjusting the fullscreen state
- // below, which also calls UpdateFullscreenExitBubbleContent().
- if (!IsWindowFullscreenForTabOrPending())
- UpdateFullscreenExitBubbleContent();
+ return true;
}
- if (IsWindowFullscreenForTabOrPending())
- ExitTabFullscreenOrMouseLockIfNecessary();
+ return false;
}
-void FullscreenController::LostMouseLock() {
- mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
- SetMouseLockTab(NULL);
- NotifyMouseLockChange();
- UpdateFullscreenExitBubbleContent();
-}
+bool FullscreenController::OnDenyExclusiveAccessPermission() {
+ if (IsWindowFullscreenForTabOrPending()) {
+ ExitExclusiveAccessIfNecessary();
+ return true;
+ }
-void FullscreenController::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- DCHECK_EQ(content::NOTIFICATION_NAV_ENTRY_COMMITTED, type);
- if (content::Details<content::LoadCommittedDetails>(details)->
- is_navigation_to_different_page())
- ExitTabFullscreenOrMouseLockIfNecessary();
+ return false;
}
-GURL FullscreenController::GetFullscreenExitBubbleURL() const {
- if (fullscreened_tab_)
+GURL FullscreenController::GetURLForExclusiveAccessBubble() const {
+ if (exclusive_access_tab())
return GetRequestingOrigin();
- if (mouse_lock_tab_)
- return mouse_lock_tab_->GetURL();
return extension_caused_fullscreen_;
}
-ExclusiveAccessBubbleType FullscreenController::GetExclusiveAccessBubbleType()
- const {
- // In kiosk and exclusive app mode we always want to be fullscreen and do not
- // want to show exit instructions for browser mode fullscreen.
- bool app_mode = false;
-#if !defined(OS_MACOSX) // App mode (kiosk) is not available on Mac yet.
- app_mode = chrome::IsRunningInAppMode();
-#endif
-
- if (mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY)
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE;
-
- if (!fullscreened_tab_) {
- if (IsMouseLocked())
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_MOUSELOCK_EXIT_INSTRUCTION;
- if (IsMouseLockRequested())
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_MOUSELOCK_BUTTONS;
- if (!extension_caused_fullscreen_.is_empty())
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION;
- if (toggled_into_fullscreen_ && !app_mode)
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION;
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE;
- }
-
- if (tab_fullscreen_accepted_) {
- if (IsPrivilegedFullscreenForTab())
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE;
- if (IsMouseLocked())
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_MOUSELOCK_EXIT_INSTRUCTION;
- if (IsMouseLockRequested())
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_MOUSELOCK_BUTTONS;
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_EXIT_INSTRUCTION;
- }
-
- if (IsMouseLockRequested())
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_MOUSELOCK_BUTTONS;
- return EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_BUTTONS;
-}
-
-void FullscreenController::UpdateNotificationRegistrations() {
- if (fullscreened_tab_ && mouse_lock_tab_)
- DCHECK(fullscreened_tab_ == mouse_lock_tab_);
-
- WebContents* tab = fullscreened_tab_ ? fullscreened_tab_ : mouse_lock_tab_;
-
- if (tab && registrar_.IsEmpty()) {
- registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
- content::Source<content::NavigationController>(&tab->GetController()));
- } else if (!tab && !registrar_.IsEmpty()) {
- registrar_.RemoveAll();
- }
+void FullscreenController::ExitExclusiveAccessIfNecessary() {
+ if (IsWindowFullscreenForTabOrPending())
+ ExitFullscreenModeForTab(exclusive_access_tab());
+ else
+ NotifyTabExclusiveAccessLost();
}
void FullscreenController::PostFullscreenChangeNotification(
@@ -562,35 +399,16 @@ void FullscreenController::NotifyFullscreenChange(bool is_fullscreen) {
content::Details<bool>(&is_fullscreen));
}
-void FullscreenController::NotifyTabOfExitIfNecessary() {
- if (fullscreened_tab_) {
- WebContents* web_contents = fullscreened_tab_;
- // This call will set |fullscreened_tab_| to nullptr.
- SetFullscreenedTab(nullptr, GURL());
+void FullscreenController::NotifyTabExclusiveAccessLost() {
+ if (exclusive_access_tab()) {
+ WebContents* web_contents = exclusive_access_tab();
+ SetTabWithExclusiveAccess(nullptr);
+ fullscreened_origin_ = GURL();
state_prior_to_tab_fullscreen_ = STATE_INVALID;
tab_fullscreen_accepted_ = false;
web_contents->ExitFullscreen();
+ exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent();
}
-
- if (mouse_lock_tab_) {
- if (IsMouseLockRequested()) {
- mouse_lock_tab_->GotResponseToLockMouseRequest(false);
- NotifyMouseLockChange();
- } else {
- UnlockMouse();
- }
- SetMouseLockTab(NULL);
- mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
- }
-
- UpdateFullscreenExitBubbleContent();
-}
-
-void FullscreenController::NotifyMouseLockChange() {
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_MOUSE_LOCK_CHANGED,
- content::Source<FullscreenController>(this),
- content::NotificationService::NoDetails());
}
void FullscreenController::ToggleFullscreenModeInternal(
@@ -601,24 +419,23 @@ void FullscreenController::ToggleFullscreenModeInternal(
return;
#endif
- bool enter_fullscreen = !window_->IsFullscreen();
+ BrowserWindow* const window = browser()->window();
+ bool enter_fullscreen = !window->IsFullscreen();
// When a Mac user requests a toggle they may be toggling between
// FullscreenWithoutChrome and FullscreenWithToolbar.
- if (window_->IsFullscreen() &&
- !IsWindowFullscreenForTabOrPending() &&
- window_->SupportsFullscreenWithToolbar()) {
+ if (window->IsFullscreen() && !IsWindowFullscreenForTabOrPending() &&
+ window->SupportsFullscreenWithToolbar()) {
if (option == BROWSER_WITH_TOOLBAR) {
- enter_fullscreen =
- enter_fullscreen || !window_->IsFullscreenWithToolbar();
+ enter_fullscreen = enter_fullscreen || !window->IsFullscreenWithToolbar();
} else {
- enter_fullscreen = enter_fullscreen || window_->IsFullscreenWithToolbar();
+ enter_fullscreen = enter_fullscreen || window->IsFullscreenWithToolbar();
}
}
// 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 (chrome::IsRunningInAppMode() && window_->IsFullscreen())
+ if (chrome::IsRunningInAppMode() && window->IsFullscreen())
return;
#if !defined(OS_MACOSX)
@@ -626,7 +443,7 @@ void FullscreenController::ToggleFullscreenModeInternal(
// from manually entering fullscreen mode and also disables kiosk mode on
// desktop platforms.
if (enter_fullscreen &&
- !profile_->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed)) {
+ !profile()->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed)) {
return;
}
#endif
@@ -654,10 +471,11 @@ void FullscreenController::EnterFullscreenModeInternal(
// TODO(scheib): Record metrics for WITH_TOOLBAR, without counting transitions
// from tab fullscreen out to browser with toolbar.
- window_->EnterFullscreen(url, GetExclusiveAccessBubbleType(),
- option == BROWSER_WITH_TOOLBAR);
+ browser()->window()->EnterFullscreen(
+ url, exclusive_access_manager()->GetExclusiveAccessExitBubbleType(),
+ option == BROWSER_WITH_TOOLBAR);
- UpdateFullscreenExitBubbleContent();
+ exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent();
// Once the window has become fullscreen it'll call back to
// WindowFullscreenStateChanged(). We don't do this immediately as
@@ -671,47 +489,16 @@ void FullscreenController::ExitFullscreenModeInternal() {
// Mac windows report a state change instantly, and so we must also clear
// state_prior_to_tab_fullscreen_ to match them else other logic using
// state_prior_to_tab_fullscreen_ will be incorrect.
- NotifyTabOfExitIfNecessary();
+ NotifyTabExclusiveAccessLost();
#endif
- window_->ExitFullscreen();
+ browser()->window()->ExitFullscreen();
extension_caused_fullscreen_ = GURL();
- UpdateFullscreenExitBubbleContent();
-}
-
-void FullscreenController::SetFullscreenedTab(WebContents* tab,
- const GURL& origin) {
- fullscreened_tab_ = tab;
- fullscreened_origin_ = origin;
- UpdateNotificationRegistrations();
-}
-
-void FullscreenController::SetMouseLockTab(WebContents* tab) {
- mouse_lock_tab_ = tab;
- UpdateNotificationRegistrations();
-}
-
-void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() {
- if (IsWindowFullscreenForTabOrPending())
- ExitFullscreenModeForTab(fullscreened_tab_);
- else
- NotifyTabOfExitIfNecessary();
-}
-
-void FullscreenController::UpdateFullscreenExitBubbleContent() {
- GURL url = GetFullscreenExitBubbleURL();
- ExclusiveAccessBubbleType bubble_type = GetExclusiveAccessBubbleType();
-
- // If bubble displays buttons, unlock mouse to allow pressing them.
- if (exclusive_access_bubble::ShowButtonsForType(bubble_type) &&
- IsMouseLocked())
- UnlockMouse();
-
- window_->UpdateFullscreenExitBubbleContent(url, bubble_type);
+ exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent();
}
ContentSetting FullscreenController::GetFullscreenSetting() const {
- DCHECK(fullscreened_tab_);
+ DCHECK(exclusive_access_tab());
GURL url = GetRequestingOrigin();
@@ -720,7 +507,7 @@ ContentSetting FullscreenController::GetFullscreenSetting() const {
// If the permission was granted to the website with no embedder, it should
// always be allowed, even if embedded.
- if (profile_->GetHostContentSettingsMap()->GetContentSetting(
+ if (profile()->GetHostContentSettingsMap()->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string()) ==
CONTENT_SETTING_ALLOW) {
return CONTENT_SETTING_ALLOW;
@@ -728,25 +515,15 @@ ContentSetting FullscreenController::GetFullscreenSetting() const {
// See the comment above the call to |SetContentSetting()| for how the
// requesting and embedding origins interact with each other wrt permissions.
- return profile_->GetHostContentSettingsMap()->GetContentSetting(
+ return profile()->GetHostContentSettingsMap()->GetContentSetting(
url, GetEmbeddingOrigin(), CONTENT_SETTINGS_TYPE_FULLSCREEN,
std::string());
}
-ContentSetting
-FullscreenController::GetMouseLockSetting(const GURL& url) const {
- if (IsPrivilegedFullscreenForTab() || url.SchemeIsFile())
- return CONTENT_SETTING_ALLOW;
-
- HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap();
- return settings_map->GetContentSetting(url, url,
- CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string());
-}
-
bool FullscreenController::IsPrivilegedFullscreenForTab() const {
const bool embedded_widget_present =
- fullscreened_tab_ &&
- fullscreened_tab_->GetFullscreenRenderWidgetHostView();
+ exclusive_access_tab() &&
+ exclusive_access_tab()->GetFullscreenRenderWidgetHostView();
return embedded_widget_present || is_privileged_fullscreen_for_testing_;
}
@@ -776,43 +553,30 @@ bool FullscreenController::MaybeToggleFullscreenForCapturedTab(
bool FullscreenController::IsFullscreenForCapturedTab(
const WebContents* web_contents) const {
- // Note: On Mac, some of the OnTabXXX() methods get called with a NULL value
+ // Note: On Mac, some of the OnTabXXX() methods get called with a nullptr
+ // value
// for web_contents. Check for that here.
- const FullscreenWithinTabHelper* const helper = web_contents ?
- FullscreenWithinTabHelper::FromWebContents(web_contents) : NULL;
+ const FullscreenWithinTabHelper* const helper =
+ web_contents ? FullscreenWithinTabHelper::FromWebContents(web_contents)
+ : nullptr;
if (helper && helper->is_fullscreen_for_captured_tab()) {
- DCHECK_NE(fullscreened_tab_, web_contents);
+ DCHECK_NE(exclusive_access_tab(), web_contents);
return true;
}
return false;
}
-void FullscreenController::UnlockMouse() {
- if (!mouse_lock_tab_)
- return;
- content::RenderWidgetHostView* mouse_lock_view =
- (fullscreened_tab_ == mouse_lock_tab_ && IsPrivilegedFullscreenForTab()) ?
- mouse_lock_tab_->GetFullscreenRenderWidgetHostView() : NULL;
- if (!mouse_lock_view) {
- RenderViewHost* const rvh = mouse_lock_tab_->GetRenderViewHost();
- if (rvh)
- mouse_lock_view = rvh->GetView();
- }
- if (mouse_lock_view)
- mouse_lock_view->UnlockMouse();
-}
-
GURL FullscreenController::GetRequestingOrigin() const {
- DCHECK(fullscreened_tab_);
+ DCHECK(exclusive_access_tab());
if (!fullscreened_origin_.is_empty())
return fullscreened_origin_;
- return fullscreened_tab_->GetLastCommittedURL();
+ return exclusive_access_tab()->GetLastCommittedURL();
}
GURL FullscreenController::GetEmbeddingOrigin() const {
- DCHECK(fullscreened_tab_);
+ DCHECK(exclusive_access_tab());
- return fullscreened_tab_->GetLastCommittedURL();
+ return exclusive_access_tab()->GetLastCommittedURL();
}
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.h b/chrome/browser/ui/exclusive_access/fullscreen_controller.h
index d276678..763591f 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller.h
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.h
@@ -9,15 +9,12 @@
#include "base/basictypes.h"
#include "base/memory/weak_ptr.h"
-#include "chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h"
#include "components/content_settings/core/common/content_settings.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
-class Browser;
-class BrowserWindow;
class GURL;
-class Profile;
namespace content {
class WebContents;
@@ -34,8 +31,7 @@ class WebContents;
// tab so it can stop rendering in its fullscreen mode.
//
// For Flash, FullscreenController will auto-accept all permission requests for
-// fullscreen and/or mouse lock, since the assumption is that the plugin handles
-// this for us.
+// fullscreen, since the assumption is that the plugin handles this for us.
//
// FullscreenWithinTab Note:
// All fullscreen widgets are displayed within the tab contents area, and
@@ -50,10 +46,10 @@ class WebContents;
// quality improvement since scaling and letterboxing steps can be skipped in
// the capture pipeline.
-// This class implements fullscreen and mouselock behaviour.
-class FullscreenController : public content::NotificationObserver {
+// This class implements fullscreen behaviour.
+class FullscreenController : public ExclusiveAccessControllerBase {
public:
- explicit FullscreenController(Browser* browser);
+ FullscreenController(ExclusiveAccessManager* manager, Browser* browser);
~FullscreenController() override;
// Browser/User Fullscreen ///////////////////////////////////////////////////
@@ -63,6 +59,9 @@ class FullscreenController : public content::NotificationObserver {
// transition.
bool IsFullscreenForBrowser() const;
+ // Returns true if Flash is providing the "exit from fullscreen" message.
+ bool IsPrivilegedFullscreenForTab() const;
+
void ToggleBrowserFullscreenMode();
// Fullscreen mode with tab strip and toolbar shown.
@@ -81,6 +80,16 @@ class FullscreenController : public content::NotificationObserver {
// BrowserWindow::IsFullscreen() may still return false.
bool IsWindowFullscreenForTabOrPending() const;
+ // Returns true if the browser window is fullscreen because of extension
+ // initiated fullscreen.
+ bool IsExtensionFullscreenOrPending() const;
+
+ // Returns true if controller has entered fullscreen mode.
+ bool IsControllerInitiatedFullscreen() const;
+
+ // Returns true if the user has accepted fullscreen.
+ bool IsUserAcceptedFullscreen() const;
+
// Returns true if the tab is/will be in fullscreen mode. Note: This does NOT
// indicate whether the browser window is/will be fullscreened as well. See
// 'FullscreenWithinTab Note'.
@@ -116,95 +125,46 @@ class FullscreenController : public content::NotificationObserver {
void SetMetroSnapMode(bool enable);
#endif
- // Mouse Lock ////////////////////////////////////////////////////////////////
-
- bool IsMouseLockRequested() const;
- bool IsMouseLocked() const;
-
- void RequestToLockMouse(content::WebContents* web_contents,
- bool user_gesture,
- bool last_unlocked_by_target);
+ // Overrde from ExclusiveAccessControllerBase.
+ void OnTabDetachedFromView(content::WebContents* web_contents) override;
+ void OnTabClosing(content::WebContents* web_contents) override;
+ bool HandleUserPressedEscape() override;
+ void ExitExclusiveAccessToPreviousState() override;
+ bool OnAcceptExclusiveAccessPermission() override;
+ bool OnDenyExclusiveAccessPermission() override;
+ GURL GetURLForExclusiveAccessBubble() const override;
+ void ExitExclusiveAccessIfNecessary() override;
// Callbacks /////////////////////////////////////////////////////////////////
- // Called by Browser::TabDeactivated.
- void OnTabDeactivated(content::WebContents* web_contents);
-
- // Called by Browser::ActiveTabChanged.
- void OnTabDetachedFromView(content::WebContents* web_contents);
-
- // Called by Browser::TabClosingAt.
- void OnTabClosing(content::WebContents* web_contents);
-
// Called by Browser::WindowFullscreenStateChanged.
void WindowFullscreenStateChanged();
- // Called by Browser::PreHandleKeyboardEvent.
- bool HandleUserPressedEscape();
-
- // Called by platform FullscreenExitBubble.
- void ExitTabOrBrowserFullscreenToPreviousState();
- void OnAcceptFullscreenPermission();
- void OnDenyFullscreenPermission();
-
- // Called by Browser::LostMouseLock.
- void LostMouseLock();
-
- // content::NotificationObserver:
- void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) override;
-
- // Bubble Content ////////////////////////////////////////////////////////////
-
- GURL GetFullscreenExitBubbleURL() const;
- ExclusiveAccessBubbleType GetExclusiveAccessBubbleType() const;
-
private:
friend class FullscreenControllerTest;
- enum MouseLockState {
- MOUSELOCK_NOT_REQUESTED,
- // The page requests to lock the mouse and the user hasn't responded to the
- // request.
- MOUSELOCK_REQUESTED,
- // Mouse lock has been allowed by the user.
- MOUSELOCK_ACCEPTED,
- // Mouse lock has been silently accepted, no notification to user.
- MOUSELOCK_ACCEPTED_SILENTLY
- };
-
enum FullscreenInternalOption {
BROWSER,
BROWSER_WITH_TOOLBAR,
TAB
};
- void UpdateNotificationRegistrations();
-
// Posts a task to call NotifyFullscreenChange.
void PostFullscreenChangeNotification(bool is_fullscreen);
// Sends a NOTIFICATION_FULLSCREEN_CHANGED notification.
void NotifyFullscreenChange(bool is_fullscreen);
- // Notifies the tab that it has been forced out of fullscreen and mouse lock
- // mode if necessary.
- void NotifyTabOfExitIfNecessary();
- void NotifyMouseLockChange();
+
+ // Notifies the tab that it has been forced out of fullscreen mode if
+ // necessary.
+ void NotifyTabExclusiveAccessLost() override;
void ToggleFullscreenModeInternal(FullscreenInternalOption option);
void EnterFullscreenModeInternal(FullscreenInternalOption option);
void ExitFullscreenModeInternal();
void SetFullscreenedTab(content::WebContents* tab, const GURL& origin);
- void SetMouseLockTab(content::WebContents* tab);
-
- // Make the current tab exit fullscreen mode or mouse lock if it is in it.
- void ExitTabFullscreenOrMouseLockIfNecessary();
- void UpdateFullscreenExitBubbleContent();
ContentSetting GetFullscreenSetting() const;
- ContentSetting GetMouseLockSetting(const GURL& url) const;
- bool IsPrivilegedFullscreenForTab() const;
void SetPrivilegedFullscreenForTesting(bool is_privileged);
// Returns true if |web_contents| was toggled into/out of fullscreen mode as a
// screen-captured tab. See 'FullscreenWithinTab Note'.
@@ -214,21 +174,11 @@ class FullscreenController : public content::NotificationObserver {
// tab. See 'FullscreenWithinTab Note'.
bool IsFullscreenForCapturedTab(const content::WebContents* web_contents)
const;
- void UnlockMouse();
// Helper methods that should be used in a TAB context.
GURL GetRequestingOrigin() const;
GURL GetEmbeddingOrigin() const;
- Browser* const browser_;
- BrowserWindow* const window_;
- Profile* const profile_;
-
- // If there is currently a tab in fullscreen mode (entered via
- // webkitRequestFullScreen), this is its WebContents.
- // Assign using SetFullscreenedTab().
- content::WebContents* fullscreened_tab_;
-
// If a tab is fullscreen, the |fullscreen_origin_| should be used as the
// origin with regards to fullscreen. The |fullscreened_tab_| url should be
// used as the embedder url.
@@ -253,14 +203,6 @@ class FullscreenController : public content::NotificationObserver {
// True if this controller has toggled into tab OR browser fullscreen.
bool toggled_into_fullscreen_;
- // WebContents for current tab requesting or currently in mouse lock.
- // Assign using SetMouseLockTab().
- content::WebContents* mouse_lock_tab_;
-
- MouseLockState mouse_lock_state_;
-
- content::NotificationRegistrar registrar_;
-
// Used to verify that calls we expect to reenter by calling
// WindowFullscreenStateChanged do so.
bool reentrant_window_state_change_call_check_;
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_state_test.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_state_test.cc
index 189b654..0a6fbc5 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_state_test.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_state_test.cc
@@ -415,15 +415,19 @@ bool FullscreenControllerStateTest::InvokeEvent(Event event) {
break;
case BUBBLE_EXIT_LINK:
- GetFullscreenController()->ExitTabOrBrowserFullscreenToPreviousState();
+ GetFullscreenController()->ExitExclusiveAccessToPreviousState();
break;
case BUBBLE_ALLOW:
- GetFullscreenController()->OnAcceptFullscreenPermission();
+ GetBrowser()
+ ->exclusive_access_manager()
+ ->OnAcceptExclusiveAccessPermission();
break;
case BUBBLE_DENY:
- GetFullscreenController()->OnDenyFullscreenPermission();
+ GetBrowser()
+ ->exclusive_access_manager()
+ ->OnDenyExclusiveAccessPermission();
break;
case WINDOW_CHANGE:
@@ -756,7 +760,7 @@ void FullscreenControllerStateTest::VerifyWindowStateExpectations(
}
FullscreenController* FullscreenControllerStateTest::GetFullscreenController() {
- return GetBrowser()->fullscreen_controller();
+ return GetBrowser()->exclusive_access_manager()->fullscreen_controller();
}
std::string FullscreenControllerStateTest::GetTransitionTableAsString() const {
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc
index 541a8b5..31ef252 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc
@@ -428,7 +428,9 @@ TEST_F(FullscreenControllerStateUnitTest, ExitFullscreenViaBrowserWindow) {
browser()->window()->ExitFullscreen();
ChangeWindowFullscreenState();
EXPECT_EQ(EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE,
- browser()->fullscreen_controller()->GetExclusiveAccessBubbleType());
+ browser()
+ ->exclusive_access_manager()
+ ->GetExclusiveAccessExitBubbleType());
}
// Test that switching tabs takes the browser out of tab fullscreen.
@@ -763,8 +765,9 @@ TEST_F(FullscreenControllerStateUnitTest,
EXPECT_TRUE(wc_delegate->IsFullscreenForTabOrPending(tab));
EXPECT_TRUE(second_wc_delegate->IsFullscreenForTabOrPending(tab));
EXPECT_FALSE(GetFullscreenController()->IsWindowFullscreenForTabOrPending());
- EXPECT_FALSE(second_browser->fullscreen_controller()->
- IsWindowFullscreenForTabOrPending());
+ EXPECT_FALSE(second_browser->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsWindowFullscreenForTabOrPending());
// Now, detach and reattach it back to the first browser window. Again, the
// tab should remain in fullscreen mode and neither browser window should have
@@ -777,8 +780,9 @@ TEST_F(FullscreenControllerStateUnitTest,
EXPECT_TRUE(wc_delegate->IsFullscreenForTabOrPending(tab));
EXPECT_TRUE(second_wc_delegate->IsFullscreenForTabOrPending(tab));
EXPECT_FALSE(GetFullscreenController()->IsWindowFullscreenForTabOrPending());
- EXPECT_FALSE(second_browser->fullscreen_controller()->
- IsWindowFullscreenForTabOrPending());
+ EXPECT_FALSE(second_browser->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsWindowFullscreenForTabOrPending());
// Exit fullscreen.
ASSERT_TRUE(InvokeEvent(TAB_FULLSCREEN_FALSE));
@@ -786,8 +790,9 @@ TEST_F(FullscreenControllerStateUnitTest,
EXPECT_FALSE(wc_delegate->IsFullscreenForTabOrPending(tab));
EXPECT_FALSE(second_wc_delegate->IsFullscreenForTabOrPending(tab));
EXPECT_FALSE(GetFullscreenController()->IsWindowFullscreenForTabOrPending());
- EXPECT_FALSE(second_browser->fullscreen_controller()->
- IsWindowFullscreenForTabOrPending());
+ EXPECT_FALSE(second_browser->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsWindowFullscreenForTabOrPending());
// Required tear-down specific to this test.
second_browser->tab_strip_model()->CloseAllTabs();
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_test.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_test.cc
index bf1925f..335892b 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_test.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_test.cc
@@ -27,34 +27,39 @@ void FullscreenControllerTest::RequestToLockMouse(
last_unlocked_by_target);
}
+FullscreenController* FullscreenControllerTest::GetFullscreenController() {
+ return GetExclusiveAccessManager()->fullscreen_controller();
+}
+
+ExclusiveAccessManager* FullscreenControllerTest::GetExclusiveAccessManager() {
+ return browser()->exclusive_access_manager();
+}
+
void FullscreenControllerTest::LostMouseLock() {
browser()->LostMouseLock();
}
bool FullscreenControllerTest::SendEscapeToFullscreenController() {
- return browser()->fullscreen_controller()->HandleUserPressedEscape();
+ return GetExclusiveAccessManager()->HandleUserPressedEscape();
}
bool FullscreenControllerTest::IsFullscreenForBrowser() {
- return browser()->fullscreen_controller()->IsFullscreenForBrowser();
+ return GetFullscreenController()->IsFullscreenForBrowser();
}
bool FullscreenControllerTest::IsWindowFullscreenForTabOrPending() {
- return browser()->fullscreen_controller()->
- IsWindowFullscreenForTabOrPending();
+ return GetFullscreenController()->IsWindowFullscreenForTabOrPending();
}
bool FullscreenControllerTest::IsMouseLockPermissionRequested() {
- ExclusiveAccessBubbleType type =
- browser()->fullscreen_controller()->GetExclusiveAccessBubbleType();
+ ExclusiveAccessBubbleType type = GetExclusiveAccessBubbleType();
bool mouse_lock = false;
exclusive_access_bubble::PermissionRequestedByType(type, NULL, &mouse_lock);
return mouse_lock;
}
bool FullscreenControllerTest::IsFullscreenPermissionRequested() {
- ExclusiveAccessBubbleType type =
- browser()->fullscreen_controller()->GetExclusiveAccessBubbleType();
+ ExclusiveAccessBubbleType type = GetExclusiveAccessBubbleType();
bool fullscreen = false;
exclusive_access_bubble::PermissionRequestedByType(type, &fullscreen, NULL);
return fullscreen;
@@ -62,27 +67,24 @@ bool FullscreenControllerTest::IsFullscreenPermissionRequested() {
ExclusiveAccessBubbleType
FullscreenControllerTest::GetExclusiveAccessBubbleType() {
- return browser()->fullscreen_controller()->GetExclusiveAccessBubbleType();
+ return GetExclusiveAccessManager()->GetExclusiveAccessExitBubbleType();
}
bool FullscreenControllerTest::IsFullscreenBubbleDisplayed() {
- ExclusiveAccessBubbleType type =
- browser()->fullscreen_controller()->GetExclusiveAccessBubbleType();
- return type != EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE;
+ return GetExclusiveAccessBubbleType() != EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE;
}
bool FullscreenControllerTest::IsFullscreenBubbleDisplayingButtons() {
- ExclusiveAccessBubbleType type =
- browser()->fullscreen_controller()->GetExclusiveAccessBubbleType();
- return exclusive_access_bubble::ShowButtonsForType(type);
+ return exclusive_access_bubble::ShowButtonsForType(
+ GetExclusiveAccessBubbleType());
}
void FullscreenControllerTest::AcceptCurrentFullscreenOrMouseLockRequest() {
- browser()->fullscreen_controller()->OnAcceptFullscreenPermission();
+ GetExclusiveAccessManager()->OnAcceptExclusiveAccessPermission();
}
void FullscreenControllerTest::DenyCurrentFullscreenOrMouseLockRequest() {
- browser()->fullscreen_controller()->OnDenyFullscreenPermission();
+ GetExclusiveAccessManager()->OnDenyExclusiveAccessPermission();
}
void FullscreenControllerTest::GoBack() {
@@ -100,6 +102,5 @@ void FullscreenControllerTest::Reload() {
}
void FullscreenControllerTest::SetPrivilegedFullscreen(bool is_privileged) {
- browser()->fullscreen_controller()->
- SetPrivilegedFullscreenForTesting(is_privileged);
+ GetFullscreenController()->SetPrivilegedFullscreenForTesting(is_privileged);
}
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h b/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h
index 59928b2..039a016 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h
@@ -7,6 +7,7 @@
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h"
+#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/browser/notification_service.h"
#include "content/public/test/test_utils.h"
@@ -55,6 +56,9 @@ class FullscreenControllerTest : public InProcessBrowserTest {
void Reload();
void SetPrivilegedFullscreen(bool is_privileged);
static const char kFullscreenMouseLockHTML[];
+ FullscreenController* GetFullscreenController();
+ ExclusiveAccessManager* GetExclusiveAccessManager();
+
private:
void ToggleTabFullscreen_Internal(bool enter_fullscreen,
bool retry_until_success);
diff --git a/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc b/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc
new file mode 100644
index 0000000..a053b85
--- /dev/null
+++ b/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc
@@ -0,0 +1,234 @@
+// Copyright (c) 2015 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/exclusive_access/mouse_lock_controller.h"
+
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "content/public/browser/web_contents.h"
+
+using content::RenderViewHost;
+using content::WebContents;
+
+MouseLockController::MouseLockController(ExclusiveAccessManager* manager,
+ Browser* browser)
+ : ExclusiveAccessControllerBase(manager, browser),
+ mouse_lock_state_(MOUSELOCK_NOT_REQUESTED) {
+}
+
+MouseLockController::~MouseLockController() {
+}
+
+bool MouseLockController::IsMouseLocked() const {
+ return mouse_lock_state_ == MOUSELOCK_ACCEPTED ||
+ mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY;
+}
+
+bool MouseLockController::IsMouseLockSilentlyAccepted() const {
+ return mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY;
+}
+
+void MouseLockController::RequestToLockMouse(WebContents* web_contents,
+ bool user_gesture,
+ bool last_unlocked_by_target) {
+ DCHECK(!IsMouseLocked());
+ NotifyMouseLockChange();
+
+ // Must have a user gesture to prevent misbehaving sites from constantly
+ // re-locking the mouse. Exceptions are when the page has unlocked
+ // (i.e. not the user), or if we're in tab fullscreen (user gesture required
+ // for that)
+ if (!last_unlocked_by_target && !user_gesture &&
+ !exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsFullscreenForTabOrPending(web_contents)) {
+ web_contents->GotResponseToLockMouseRequest(false);
+ return;
+ }
+ SetTabWithExclusiveAccess(web_contents);
+ ExclusiveAccessBubbleType bubble_type =
+ exclusive_access_manager()->GetExclusiveAccessExitBubbleType();
+
+ switch (GetMouseLockSetting(web_contents->GetURL())) {
+ case CONTENT_SETTING_ALLOW:
+ // If bubble already displaying buttons we must not lock the mouse yet,
+ // or it would prevent pressing those buttons. Instead, merge the request.
+ if (!exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsPrivilegedFullscreenForTab() &&
+ exclusive_access_bubble::ShowButtonsForType(bubble_type)) {
+ mouse_lock_state_ = MOUSELOCK_REQUESTED;
+ } else {
+ // Lock mouse.
+ if (web_contents->GotResponseToLockMouseRequest(true)) {
+ if (last_unlocked_by_target) {
+ mouse_lock_state_ = MOUSELOCK_ACCEPTED_SILENTLY;
+ } else {
+ mouse_lock_state_ = MOUSELOCK_ACCEPTED;
+ }
+ } else {
+ SetTabWithExclusiveAccess(nullptr);
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ }
+ }
+ break;
+ case CONTENT_SETTING_BLOCK:
+ web_contents->GotResponseToLockMouseRequest(false);
+ SetTabWithExclusiveAccess(nullptr);
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ break;
+ case CONTENT_SETTING_ASK:
+ mouse_lock_state_ = MOUSELOCK_REQUESTED;
+ break;
+ default:
+ NOTREACHED();
+ }
+ exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent();
+}
+
+void MouseLockController::ExitExclusiveAccessIfNecessary() {
+ NotifyTabExclusiveAccessLost();
+}
+
+void MouseLockController::NotifyTabExclusiveAccessLost() {
+ WebContents* tab = exclusive_access_tab();
+ if (tab) {
+ if (IsMouseLockRequested()) {
+ tab->GotResponseToLockMouseRequest(false);
+ NotifyMouseLockChange();
+ } else {
+ UnlockMouse();
+ }
+ SetTabWithExclusiveAccess(nullptr);
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent();
+ }
+}
+
+bool MouseLockController::HandleUserPressedEscape() {
+ if (IsMouseLocked() || IsMouseLockRequested()) {
+ ExitExclusiveAccessIfNecessary();
+ return true;
+ }
+
+ return false;
+}
+
+void MouseLockController::ExitExclusiveAccessToPreviousState() {
+ // Nothing to do for mouse lock.
+}
+
+bool MouseLockController::OnAcceptExclusiveAccessPermission() {
+ ExclusiveAccessBubbleType bubble_type =
+ exclusive_access_manager()->GetExclusiveAccessExitBubbleType();
+ bool mouse_lock = false;
+ exclusive_access_bubble::PermissionRequestedByType(bubble_type, nullptr,
+ &mouse_lock);
+ DCHECK(!(mouse_lock && IsMouseLocked()));
+
+ if (mouse_lock && !IsMouseLocked()) {
+ DCHECK(IsMouseLockRequested());
+
+ HostContentSettingsMap* settings_map =
+ profile()->GetHostContentSettingsMap();
+
+ GURL url = GetExclusiveAccessBubbleURL();
+ ContentSettingsPattern pattern = ContentSettingsPattern::FromURL(url);
+
+ // TODO(markusheintz): We should allow patterns for all possible URLs here.
+ if (pattern.IsValid()) {
+ settings_map->SetContentSetting(pattern,
+ ContentSettingsPattern::Wildcard(),
+ CONTENT_SETTINGS_TYPE_MOUSELOCK,
+ std::string(), CONTENT_SETTING_ALLOW);
+ }
+
+ WebContents* tab = exclusive_access_tab();
+ if (tab && tab->GotResponseToLockMouseRequest(true)) {
+ mouse_lock_state_ = MOUSELOCK_ACCEPTED;
+ } else {
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ SetTabWithExclusiveAccess(nullptr);
+ }
+ NotifyMouseLockChange();
+ return true;
+ }
+
+ return false;
+}
+
+bool MouseLockController::OnDenyExclusiveAccessPermission() {
+ WebContents* tab = exclusive_access_tab();
+
+ if (tab && IsMouseLockRequested()) {
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ tab->GotResponseToLockMouseRequest(false);
+ SetTabWithExclusiveAccess(nullptr);
+ NotifyMouseLockChange();
+ return true;
+ }
+
+ return false;
+}
+
+void MouseLockController::LostMouseLock() {
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ SetTabWithExclusiveAccess(nullptr);
+ NotifyMouseLockChange();
+ exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent();
+}
+
+bool MouseLockController::IsMouseLockRequested() const {
+ return mouse_lock_state_ == MOUSELOCK_REQUESTED;
+}
+
+void MouseLockController::NotifyMouseLockChange() {
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_MOUSE_LOCK_CHANGED,
+ content::Source<MouseLockController>(this),
+ content::NotificationService::NoDetails());
+}
+
+void MouseLockController::UnlockMouse() {
+ WebContents* tab = exclusive_access_tab();
+
+ if (!tab)
+ return;
+
+ content::RenderWidgetHostView* mouse_lock_view = nullptr;
+ FullscreenController* fullscreen_controller =
+ exclusive_access_manager()->fullscreen_controller();
+ if ((fullscreen_controller->exclusive_access_tab() == tab) &&
+ fullscreen_controller->IsPrivilegedFullscreenForTab()) {
+ mouse_lock_view =
+ exclusive_access_tab()->GetFullscreenRenderWidgetHostView();
+ }
+
+ if (!mouse_lock_view) {
+ RenderViewHost* const rvh = exclusive_access_tab()->GetRenderViewHost();
+ if (rvh)
+ mouse_lock_view = rvh->GetView();
+ }
+
+ if (mouse_lock_view)
+ mouse_lock_view->UnlockMouse();
+}
+
+ContentSetting MouseLockController::GetMouseLockSetting(const GURL& url) const {
+ if (exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsPrivilegedFullscreenForTab() ||
+ url.SchemeIsFile())
+ return CONTENT_SETTING_ALLOW;
+
+ HostContentSettingsMap* settings_map = profile()->GetHostContentSettingsMap();
+ return settings_map->GetContentSetting(
+ url, url, CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string());
+}
diff --git a/chrome/browser/ui/exclusive_access/mouse_lock_controller.h b/chrome/browser/ui/exclusive_access/mouse_lock_controller.h
new file mode 100644
index 0000000..27cede2
--- /dev/null
+++ b/chrome/browser/ui/exclusive_access/mouse_lock_controller.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2015 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.
+
+#ifndef CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_MOUSE_LOCK_CONTROLLER_H_
+#define CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_MOUSE_LOCK_CONTROLLER_H_
+
+#include "chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h"
+#include "components/content_settings/core/common/content_settings.h"
+
+// This class implements mouselock behavior.
+class MouseLockController : public ExclusiveAccessControllerBase {
+ public:
+ MouseLockController(ExclusiveAccessManager* manager, Browser* browser);
+ ~MouseLockController() override;
+
+ bool IsMouseLocked() const;
+ bool IsMouseLockSilentlyAccepted() const;
+ bool IsMouseLockRequested() const;
+
+ void RequestToLockMouse(content::WebContents* web_contents,
+ bool user_gesture,
+ bool last_unlocked_by_target);
+
+ // Override from ExclusiveAccessControllerBase
+ bool HandleUserPressedEscape() override;
+
+ void ExitExclusiveAccessToPreviousState() override;
+ bool OnAcceptExclusiveAccessPermission() override;
+ bool OnDenyExclusiveAccessPermission() override;
+
+ // Called by Browser::LostMouseLock.
+ void LostMouseLock();
+
+ void UnlockMouse();
+
+ private:
+ enum MouseLockState {
+ MOUSELOCK_NOT_REQUESTED,
+ // The page requests to lock the mouse and the user hasn't responded to the
+ // request.
+ MOUSELOCK_REQUESTED,
+ // Mouse lock has been allowed by the user.
+ MOUSELOCK_ACCEPTED,
+ // Mouse lock has been silently accepted, no notification to user.
+ MOUSELOCK_ACCEPTED_SILENTLY
+ };
+
+ void NotifyMouseLockChange();
+
+ void ExitExclusiveAccessIfNecessary() override;
+ void NotifyTabExclusiveAccessLost() override;
+
+ ContentSetting GetMouseLockSetting(const GURL& url) const;
+
+ MouseLockState mouse_lock_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(MouseLockController);
+};
+
+#endif // CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_MOUSE_LOCK_CONTROLLER_H_
diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views.cc b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
index 94fa862..902bdc2 100644
--- a/chrome/browser/ui/views/exclusive_access_bubble_views.cc
+++ b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
@@ -8,6 +8,7 @@
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
@@ -295,9 +296,11 @@ ExclusiveAccessBubbleViews::ExclusiveAccessBubbleViews(
popup_->AddObserver(this);
- registrar_.Add(this, chrome::NOTIFICATION_FULLSCREEN_CHANGED,
- content::Source<FullscreenController>(
- browser_view_->browser()->fullscreen_controller()));
+ registrar_.Add(
+ this, chrome::NOTIFICATION_FULLSCREEN_CHANGED,
+ content::Source<FullscreenController>(browser_view_->browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()));
UpdateForImmersiveState();
}
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
index 958dce5..ec64e54 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -80,8 +80,10 @@ IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest,
// NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
scoped_ptr<FullscreenNotificationObserver> waiter(
new FullscreenNotificationObserver());
- browser()->fullscreen_controller()->EnterFullscreenModeForTab(
- web_contents, GURL());
+ browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->EnterFullscreenModeForTab(web_contents, GURL());
waiter->Wait();
}
EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
@@ -138,8 +140,10 @@ IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, ImmersiveFullscreen) {
{
scoped_ptr<FullscreenNotificationObserver> waiter(
new FullscreenNotificationObserver());
- browser()->fullscreen_controller()->EnterFullscreenModeForTab(
- web_contents, GURL());
+ browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->EnterFullscreenModeForTab(web_contents, GURL());
waiter->Wait();
}
EXPECT_TRUE(immersive_mode_controller->IsEnabled());
@@ -165,7 +169,10 @@ IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, ImmersiveFullscreen) {
{
scoped_ptr<FullscreenNotificationObserver> waiter(
new FullscreenNotificationObserver());
- browser()->fullscreen_controller()->ExitFullscreenModeForTab(web_contents);
+ browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->ExitFullscreenModeForTab(web_contents);
waiter->Wait();
}
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
index 664a4d2..31fda80 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -8,6 +8,7 @@
#include "ash/wm/immersive_revealed_lock.h"
#include "ash/wm/window_state.h"
#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/top_container_view.h"
@@ -138,8 +139,9 @@ void ImmersiveModeControllerAsh::EnableWindowObservers(bool enable) {
return;
observers_enabled_ = enable;
- content::Source<FullscreenController> source(
- browser_view_->browser()->fullscreen_controller());
+ content::Source<FullscreenController> source(browser_view_->browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller());
if (enable) {
ash::wm::GetWindowState(native_window_)->AddObserver(this);
registrar_.Add(this, chrome::NOTIFICATION_FULLSCREEN_CHANGED, source);
@@ -163,8 +165,10 @@ bool ImmersiveModeControllerAsh::UpdateTabIndicators() {
if (!IsEnabled() || !has_tabstrip) {
use_tab_indicators_ = false;
} else {
- bool in_tab_fullscreen = browser_view_->browser()->fullscreen_controller()->
- IsWindowFullscreenForTabOrPending();
+ bool in_tab_fullscreen = browser_view_->browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->IsWindowFullscreenForTabOrPending();
use_tab_indicators_ = !in_tab_fullscreen;
}
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
index 85d8a0d..2a27679 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
@@ -74,13 +74,16 @@ class ImmersiveModeControllerAshTest : public TestWithBrowserView {
scoped_ptr<FullscreenNotificationObserver> waiter(
new FullscreenNotificationObserver());
if (tab_fullscreen) {
- browser()->fullscreen_controller()->EnterFullscreenModeForTab(
- web_contents, GURL());
+ browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->EnterFullscreenModeForTab(web_contents, GURL());
} else {
- browser()->fullscreen_controller()->ExitFullscreenModeForTab(
- web_contents);
+ browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->ExitFullscreenModeForTab(web_contents);
}
-
waiter->Wait();
}
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
index 416de50..eff898a 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -39,7 +39,8 @@ ZoomBubbleView* ZoomBubbleView::zoom_bubble_ = NULL;
void ZoomBubbleView::ShowBubble(content::WebContents* web_contents,
bool auto_close) {
Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
- DCHECK(browser && browser->window() && browser->fullscreen_controller());
+ DCHECK(browser && browser->window() &&
+ browser->exclusive_access_manager()->fullscreen_controller());
BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
bool is_fullscreen = browser_view->IsFullscreen();
@@ -66,11 +67,8 @@ void ZoomBubbleView::ShowBubble(content::WebContents* web_contents,
// bubble must be closed and a new one created.
CloseBubble();
- zoom_bubble_ = new ZoomBubbleView(anchor_view,
- web_contents,
- auto_close,
- browser_view->immersive_mode_controller(),
- browser->fullscreen_controller());
+ zoom_bubble_ = new ZoomBubbleView(anchor_view, web_contents, auto_close,
+ browser_view->immersive_mode_controller());
// If the zoom change was initiated by an extension, capture the relevent
// information from it.
@@ -118,8 +116,7 @@ ZoomBubbleView::ZoomBubbleView(
views::View* anchor_view,
content::WebContents* web_contents,
bool auto_close,
- ImmersiveModeController* immersive_mode_controller,
- FullscreenController* fullscreen_controller)
+ ImmersiveModeController* immersive_mode_controller)
: ManagedFullScreenBubbleDelegateView(anchor_view, web_contents),
image_button_(NULL),
label_(NULL),
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
index 13afb64..b8039e6 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
@@ -75,8 +75,7 @@ class ZoomBubbleView : public ManagedFullScreenBubbleDelegateView,
ZoomBubbleView(views::View* anchor_view,
content::WebContents* web_contents,
bool auto_close,
- ImmersiveModeController* immersive_mode_controller,
- FullscreenController* fullscreen_controller);
+ ImmersiveModeController* immersive_mode_controller);
~ZoomBubbleView() override;
// ManagedFullScreenBubbleDelegateView:
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
index eaa6571..207c029 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
@@ -38,8 +38,10 @@ IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, MAYBE_NonImmersiveFullscreen) {
// notification before testing the zoom bubble visibility.
scoped_ptr<FullscreenNotificationObserver> waiter(
new FullscreenNotificationObserver());
- browser()->fullscreen_controller()->EnterFullscreenModeForTab(
- web_contents, GURL());
+ browser()
+ ->exclusive_access_manager()
+ ->fullscreen_controller()
+ ->EnterFullscreenModeForTab(web_contents, GURL());
waiter->Wait();
}
ASSERT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
diff --git a/chrome/browser/ui/views/managed_full_screen_bubble_delegate_view.cc b/chrome/browser/ui/views/managed_full_screen_bubble_delegate_view.cc
index 4642cb3..9a867d2 100644
--- a/chrome/browser/ui/views/managed_full_screen_bubble_delegate_view.cc
+++ b/chrome/browser/ui/views/managed_full_screen_bubble_delegate_view.cc
@@ -21,9 +21,10 @@ ManagedFullScreenBubbleDelegateView::ManagedFullScreenBubbleDelegateView(
// Add observer to close the bubble if the fullscreen state changes.
if (web_contents) {
Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
- registrar_.Add(this, chrome::NOTIFICATION_FULLSCREEN_CHANGED,
- content::Source<FullscreenController>(
- browser->fullscreen_controller()));
+ registrar_.Add(
+ this, chrome::NOTIFICATION_FULLSCREEN_CHANGED,
+ content::Source<FullscreenController>(
+ browser->exclusive_access_manager()->fullscreen_controller()));
}
}
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
index e269bf5..a158ec2 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
@@ -861,7 +861,6 @@ void ManagePasswordsBubbleView::ShowBubble(content::WebContents* web_contents,
Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
DCHECK(browser);
DCHECK(browser->window());
- DCHECK(browser->fullscreen_controller());
if (IsShowing())
return;
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index 7c16457..00703f1 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -1435,10 +1435,16 @@
'browser/ui/exclusive_access/exclusive_access_bubble.h',
'browser/ui/exclusive_access/exclusive_access_bubble_type.cc',
'browser/ui/exclusive_access/exclusive_access_bubble_type.h',
+ 'browser/ui/exclusive_access/exclusive_access_controller_base.cc',
+ 'browser/ui/exclusive_access/exclusive_access_controller_base.h',
+ 'browser/ui/exclusive_access/exclusive_access_manager.cc',
+ 'browser/ui/exclusive_access/exclusive_access_manager.h',
'browser/ui/exclusive_access/fullscreen_controller.cc',
'browser/ui/exclusive_access/fullscreen_controller.h',
'browser/ui/exclusive_access/fullscreen_within_tab_helper.cc',
'browser/ui/exclusive_access/fullscreen_within_tab_helper.h',
+ 'browser/ui/exclusive_access/mouse_lock_controller.cc',
+ 'browser/ui/exclusive_access/mouse_lock_controller.h',
'browser/ui/fast_unload_controller.cc',
'browser/ui/fast_unload_controller.h',
'browser/ui/find_bar/find_bar_controller.cc',