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

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

Issue 789533002: Fullscreen: make fullscreen requests come from RenderFrame (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: make try happy Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/exclusive_access/fullscreen_controller.cc
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
index 66554695eb72c1e0aeca33cddb3bf88a3a19321f..39cdac291b40e1c8742417a9f746f47fec312aa6 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
@@ -96,22 +96,71 @@ bool FullscreenController::IsFullscreenCausedByTab() const {
return state_prior_to_tab_fullscreen_ == STATE_NORMAL;
}
-void FullscreenController::ToggleFullscreenModeForTab(WebContents* web_contents,
- bool enter_fullscreen) {
- if (MaybeToggleFullscreenForCapturedTab(web_contents, enter_fullscreen)) {
+void FullscreenController::EnterFullscreenModeForTab(WebContents* web_contents,
+ const GURL& origin) {
+ DCHECK(web_contents);
+
+ if (MaybeToggleFullscreenForCapturedTab(web_contents, true)) {
// During tab capture of fullscreen-within-tab views, the browser window
// fullscreen state is unchanged, so return now.
return;
}
- if (fullscreened_tab_) {
- if (web_contents != fullscreened_tab_)
+
+ if (web_contents != browser_->tab_strip_model()->GetActiveWebContents() ||
+ IsWindowFullscreenForTabOrPending()) {
return;
- } else if (
- web_contents != browser_->tab_strip_model()->GetActiveWebContents()) {
+ }
+
+#if defined(OS_WIN)
+ // For now, avoid breaking when initiating full screen tab mode while in
+ // a metro snap.
+ // TODO(robertshield): Find a way to reconcile tab-initiated fullscreen
+ // modes with metro snap.
+ if (IsInMetroSnapMode())
+ return;
+#endif
+
+ SetFullscreenedTab(web_contents, origin);
+
+ if (!window_->IsFullscreen()) {
+ // Normal -> Tab Fullscreen.
+ state_prior_to_tab_fullscreen_ = STATE_NORMAL;
+ ToggleFullscreenModeInternal(TAB);
return;
}
- if (IsWindowFullscreenForTabOrPending() == enter_fullscreen)
+
+ if (window_->IsFullscreenWithToolbar()) {
+ // Browser Fullscreen with Toolbar -> Tab Fullscreen (no toolbar).
+ window_->UpdateFullscreenWithToolbar(false);
+ state_prior_to_tab_fullscreen_ = STATE_BROWSER_FULLSCREEN_WITH_TOOLBAR;
+ } else {
+ // Browser Fullscreen without Toolbar -> Tab Fullscreen.
+ state_prior_to_tab_fullscreen_ = STATE_BROWSER_FULLSCREEN_NO_TOOLBAR;
+ }
+
+ // We need to update the fullscreen exit bubble, e.g., going from browser
+ // fullscreen to tab fullscreen will need to show different content.
+ if (!tab_fullscreen_accepted_) {
+ tab_fullscreen_accepted_ = GetFullscreenSetting() == CONTENT_SETTING_ALLOW;
+ }
+ UpdateFullscreenExitBubbleContent();
+
+ // This is only a change between Browser and Tab fullscreen. We generate
+ // a fullscreen notification now because there is no window change.
+ PostFullscreenChangeNotification(true);
+}
+
+void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents) {
+ if (MaybeToggleFullscreenForCapturedTab(web_contents, false)) {
+ // During tab capture of fullscreen-within-tab views, the browser window
+ // fullscreen state is unchanged, so return now.
+ return;
+ }
+
+ if (!IsWindowFullscreenForTabOrPending() ||
+ web_contents != fullscreened_tab_) {
return;
+ }
#if defined(OS_WIN)
// For now, avoid breaking when initiating full screen tab mode while in
@@ -122,68 +171,36 @@ void FullscreenController::ToggleFullscreenModeForTab(WebContents* web_contents,
return;
#endif
- bool in_browser_or_tab_fullscreen_mode = window_->IsFullscreen();
-
- if (enter_fullscreen) {
- SetFullscreenedTab(web_contents);
- if (!in_browser_or_tab_fullscreen_mode) {
- // Normal -> Tab Fullscreen.
- state_prior_to_tab_fullscreen_ = STATE_NORMAL;
- ToggleFullscreenModeInternal(TAB);
- } else {
- if (window_->IsFullscreenWithToolbar()) {
- // Browser Fullscreen with Toolbar -> Tab Fullscreen (no toolbar).
- window_->UpdateFullscreenWithToolbar(false);
- state_prior_to_tab_fullscreen_ = STATE_BROWSER_FULLSCREEN_WITH_TOOLBAR;
- } else {
- // Browser Fullscreen without Toolbar -> Tab Fullscreen.
- state_prior_to_tab_fullscreen_ = STATE_BROWSER_FULLSCREEN_NO_TOOLBAR;
- }
+ if (!window_->IsFullscreen())
+ return;
- // We need to update the fullscreen exit bubble, e.g., going from browser
- // fullscreen to tab fullscreen will need to show different content.
- const GURL& url = web_contents->GetURL();
- if (!tab_fullscreen_accepted_) {
- tab_fullscreen_accepted_ =
- GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
- }
- UpdateFullscreenExitBubbleContent();
+ if (IsFullscreenCausedByTab()) {
+ // Tab Fullscreen -> Normal.
+ ToggleFullscreenModeInternal(TAB);
+ return;
+ }
- // This is only a change between Browser and Tab fullscreen. We generate
- // a fullscreen notification now because there is no window change.
- PostFullscreenChangeNotification(true);
- }
- } else {
- if (in_browser_or_tab_fullscreen_mode) {
- if (IsFullscreenCausedByTab()) {
- // Tab Fullscreen -> Normal.
- ToggleFullscreenModeInternal(TAB);
- } else {
- // 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);
- }
+ // 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);
+ }
#if defined(OS_MACOSX)
- // Clear the bubble URL, which forces the Mac UI to redraw.
- UpdateFullscreenExitBubbleContent();
+ // Clear the bubble URL, which forces the Mac UI to redraw.
+ UpdateFullscreenExitBubbleContent();
#endif // defined(OS_MACOSX)
- // If currently there is a tab in "tab fullscreen" mode and fullscreen
- // was not caused by it (i.e., previously it was in "browser fullscreen"
- // mode), we need to switch back to "browser fullscreen" mode. In this
- // case, all we have to do is notifying the tab that it has exited "tab
- // fullscreen" mode.
- NotifyTabOfExitIfNecessary();
+ // If currently there is a tab in "tab fullscreen" mode and fullscreen
+ // was not caused by it (i.e., previously it was in "browser fullscreen"
+ // mode), we need to switch back to "browser fullscreen" mode. In this
+ // case, all we have to do is notifying the tab that it has exited "tab
+ // fullscreen" mode.
+ NotifyTabOfExitIfNecessary();
- // This is only a change between Browser and Tab fullscreen. We generate
- // a fullscreen notification now because there is no window change.
- PostFullscreenChangeNotification(true);
- }
- }
- }
+ // This is only a change between Browser and Tab fullscreen. We generate
+ // a fullscreen notification now because there is no window change.
+ PostFullscreenChangeNotification(true);
}
bool FullscreenController::IsInMetroSnapMode() {
@@ -309,9 +326,7 @@ void FullscreenController::OnTabDetachedFromView(WebContents* old_contents) {
void FullscreenController::OnTabClosing(WebContents* web_contents) {
if (IsFullscreenForCapturedTab(web_contents)) {
- RenderViewHost* const rvh = web_contents->GetRenderViewHost();
- if (rvh)
- rvh->ExitFullscreen();
+ web_contents->ExitFullscreen();
} else if (web_contents == fullscreened_tab_ ||
web_contents == mouse_lock_tab_) {
ExitTabFullscreenOrMouseLockIfNecessary();
@@ -348,9 +363,7 @@ bool FullscreenController::HandleUserPressedEscape() {
WebContents* const active_web_contents =
browser_->tab_strip_model()->GetActiveWebContents();
if (IsFullscreenForCapturedTab(active_web_contents)) {
- RenderViewHost* const rvh = active_web_contents->GetRenderViewHost();
- if (rvh)
- rvh->ExitFullscreen();
+ active_web_contents->ExitFullscreen();
return true;
} else if (IsWindowFullscreenForTabOrPending() ||
IsMouseLocked() || IsMouseLockRequested()) {
@@ -379,11 +392,12 @@ void FullscreenController::OnAcceptFullscreenPermission() {
HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap();
- GURL url = GetFullscreenExitBubbleURL();
- ContentSettingsPattern pattern = ContentSettingsPattern::FromURL(url);
-
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(
@@ -404,11 +418,29 @@ void FullscreenController::OnAcceptFullscreenPermission() {
if (fullscreen && !tab_fullscreen_accepted_) {
DCHECK(fullscreened_tab_);
- if (pattern.IsValid()) {
+ // 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
+ // for embedder A, it will not be approved when embedded in a different
+ // origin B.
+ //
+ // However, an exception is made when a requester and an embedder are the
+ // same origin. In other words, if the requester is the top-level frame. If
+ // that combination is ALLOWED, then future requests from that origin will
+ // succeed no matter what the embedder is. For example, if youtube.com
+ // is visited and user selects ALLOW. Later user visits example.com which
+ // embeds youtube.com in an iframe, which is then ALLOWED to go fullscreen.
+ ContentSettingsPattern primary_pattern =
+ ContentSettingsPattern::FromURLNoWildcard(GetRequestingOrigin());
+ ContentSettingsPattern secondary_pattern =
+ ContentSettingsPattern::FromURLNoWildcard(GetEmbeddingOrigin());
+
+ // 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()) {
settings_map->SetContentSetting(
- pattern, ContentSettingsPattern::Wildcard(),
- CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string(),
- CONTENT_SETTING_ALLOW);
+ primary_pattern, secondary_pattern, CONTENT_SETTINGS_TYPE_FULLSCREEN,
+ std::string(), CONTENT_SETTING_ALLOW);
}
tab_fullscreen_accepted_ = true;
}
@@ -455,7 +487,7 @@ void FullscreenController::Observe(int type,
GURL FullscreenController::GetFullscreenExitBubbleURL() const {
if (fullscreened_tab_)
- return fullscreened_tab_->GetURL();
+ return GetRequestingOrigin();
if (mouse_lock_tab_)
return mouse_lock_tab_->GetURL();
return extension_caused_fullscreen_;
@@ -532,12 +564,12 @@ void FullscreenController::NotifyFullscreenChange(bool is_fullscreen) {
void FullscreenController::NotifyTabOfExitIfNecessary() {
if (fullscreened_tab_) {
- RenderViewHost* rvh = fullscreened_tab_->GetRenderViewHost();
- SetFullscreenedTab(NULL);
+ WebContents* web_contents = fullscreened_tab_;
+ // This call will set |fullscreened_tab_| to nullptr.
+ SetFullscreenedTab(nullptr, GURL());
state_prior_to_tab_fullscreen_ = STATE_INVALID;
tab_fullscreen_accepted_ = false;
- if (rvh)
- rvh->ExitFullscreen();
+ web_contents->ExitFullscreen();
}
if (mouse_lock_tab_) {
@@ -610,9 +642,8 @@ void FullscreenController::EnterFullscreenModeInternal(
toggled_into_fullscreen_ = true;
GURL url;
if (option == TAB) {
- url = browser_->tab_strip_model()->GetActiveWebContents()->GetURL();
- tab_fullscreen_accepted_ =
- GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
+ url = GetRequestingOrigin();
+ tab_fullscreen_accepted_ = GetFullscreenSetting() == CONTENT_SETTING_ALLOW;
} else {
if (!extension_caused_fullscreen_.is_empty())
url = extension_caused_fullscreen_;
@@ -648,8 +679,10 @@ void FullscreenController::ExitFullscreenModeInternal() {
UpdateFullscreenExitBubbleContent();
}
-void FullscreenController::SetFullscreenedTab(WebContents* tab) {
+void FullscreenController::SetFullscreenedTab(WebContents* tab,
+ const GURL& origin) {
fullscreened_tab_ = tab;
+ fullscreened_origin_ = origin;
UpdateNotificationRegistrations();
}
@@ -660,7 +693,7 @@ void FullscreenController::SetMouseLockTab(WebContents* tab) {
void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() {
if (IsWindowFullscreenForTabOrPending())
- ToggleFullscreenModeForTab(fullscreened_tab_, false);
+ ExitFullscreenModeForTab(fullscreened_tab_);
else
NotifyTabOfExitIfNecessary();
}
@@ -677,13 +710,27 @@ void FullscreenController::UpdateFullscreenExitBubbleContent() {
window_->UpdateFullscreenExitBubbleContent(url, bubble_type);
}
-ContentSetting
-FullscreenController::GetFullscreenSetting(const GURL& url) const {
+ContentSetting FullscreenController::GetFullscreenSetting() const {
+ DCHECK(fullscreened_tab_);
+
+ GURL url = GetRequestingOrigin();
+
if (IsPrivilegedFullscreenForTab() || url.SchemeIsFile())
return CONTENT_SETTING_ALLOW;
- return profile_->GetHostContentSettingsMap()->GetContentSetting(url, url,
- CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string());
+ // If the permission was granted to the website with no embedder, it should
+ // always be allowed, even if embedded.
+ if (profile_->GetHostContentSettingsMap()->GetContentSetting(
+ url, url, CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string()) ==
+ CONTENT_SETTING_ALLOW) {
+ return CONTENT_SETTING_ALLOW;
+ }
+
+ // 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(
+ url, GetEmbeddingOrigin(), CONTENT_SETTINGS_TYPE_FULLSCREEN,
+ std::string());
}
ContentSetting
@@ -754,3 +801,18 @@ void FullscreenController::UnlockMouse() {
if (mouse_lock_view)
mouse_lock_view->UnlockMouse();
}
+
+GURL FullscreenController::GetRequestingOrigin() const {
+ DCHECK(fullscreened_tab_);
+
+ if (!fullscreened_origin_.is_empty())
+ return fullscreened_origin_;
+
+ return fullscreened_tab_->GetLastCommittedURL();
+}
+
+GURL FullscreenController::GetEmbeddingOrigin() const {
+ DCHECK(fullscreened_tab_);
+
+ return fullscreened_tab_->GetLastCommittedURL();
+}

Powered by Google App Engine
This is Rietveld 408576698