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

Side by Side Diff: chrome/browser/ui/fullscreen/fullscreen_controller.cc

Issue 158253002: Tabs being screen-captured will fullscreen within their tab contents area. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h" 5 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "chrome/browser/app_mode/app_mode_utils.h" 10 #include "chrome/browser/app_mode/app_mode_utils.h"
11 #include "chrome/browser/chrome_notification_types.h" 11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/content_settings/host_content_settings_map.h" 12 #include "chrome/browser/content_settings/host_content_settings_map.h"
13 #include "chrome/browser/download/download_shelf.h" 13 #include "chrome/browser/download/download_shelf.h"
14 #include "chrome/browser/fullscreen.h" 14 #include "chrome/browser/fullscreen.h"
15 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser.h" 16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_window.h" 17 #include "chrome/browser/ui/browser_window.h"
18 #include "chrome/browser/ui/status_bubble.h" 18 #include "chrome/browser/ui/status_bubble.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h" 19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/common/chrome_switches.h" 20 #include "chrome/common/chrome_switches.h"
21 #include "content/public/browser/navigation_details.h" 21 #include "content/public/browser/navigation_details.h"
22 #include "content/public/browser/navigation_entry.h" 22 #include "content/public/browser/navigation_entry.h"
23 #include "content/public/browser/notification_service.h" 23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/render_view_host.h" 24 #include "content/public/browser/render_view_host.h"
25 #include "content/public/browser/render_widget_host_view.h" 25 #include "content/public/browser/render_widget_host_view.h"
26 #include "content/public/browser/user_metrics.h" 26 #include "content/public/browser/user_metrics.h"
27 #include "content/public/browser/web_contents.h" 27 #include "content/public/browser/web_contents.h"
28 #include "content/public/browser/web_contents_view.h"
28 #include "extensions/common/extension.h" 29 #include "extensions/common/extension.h"
29 30
30 #if defined(OS_MACOSX) 31 #if defined(OS_MACOSX)
31 #include "base/mac/mac_util.h" 32 #include "base/mac/mac_util.h"
32 #else 33 #else
33 #include "base/prefs/pref_service.h" 34 #include "base/prefs/pref_service.h"
34 #include "chrome/common/pref_names.h" 35 #include "chrome/common/pref_names.h"
35 #endif 36 #endif
36 37
37 using base::UserMetricsAction; 38 using base::UserMetricsAction;
(...skipping 28 matching lines...) Expand all
66 extension_caused_fullscreen_ = GURL(); 67 extension_caused_fullscreen_ = GURL();
67 ToggleFullscreenModeInternal(BROWSER); 68 ToggleFullscreenModeInternal(BROWSER);
68 } 69 }
69 70
70 bool FullscreenController::IsFullscreenForTabOrPending() const { 71 bool FullscreenController::IsFullscreenForTabOrPending() const {
71 return fullscreened_tab_ != NULL; 72 return fullscreened_tab_ != NULL;
72 } 73 }
73 74
74 bool FullscreenController::IsFullscreenForTabOrPending( 75 bool FullscreenController::IsFullscreenForTabOrPending(
75 const WebContents* web_contents) const { 76 const WebContents* web_contents) const {
76 if (web_contents != fullscreened_tab_) 77 return web_contents == fullscreened_tab_ ||
scheib 2014/02/12 01:41:16 Why drop the DCHECK when !IsCapturedFullscreenTab?
miu 2014/02/12 08:25:19 Good point. I rearranged this to put it back.
77 return false; 78 IsCapturedFullscreenTab(web_contents);
78 DCHECK(web_contents == browser_->tab_strip_model()->GetActiveWebContents());
79 return true;
80 } 79 }
81 80
82 bool FullscreenController::IsFullscreenCausedByTab() const { 81 bool FullscreenController::IsFullscreenCausedByTab() const {
83 return state_prior_to_tab_fullscreen_ == STATE_NORMAL; 82 return state_prior_to_tab_fullscreen_ == STATE_NORMAL;
84 } 83 }
85 84
86 void FullscreenController::ToggleFullscreenModeForTab(WebContents* web_contents, 85 void FullscreenController::ToggleFullscreenModeForTab(WebContents* web_contents,
87 bool enter_fullscreen) { 86 bool enter_fullscreen) {
87 if (MaybeToggleAsFullscreenWithinTab(web_contents, enter_fullscreen)) {
88 // During tab capture of embedded fullscreen views, browser window
89 // fullscreen state is unchanged, so return now.
90 return;
91 }
88 if (fullscreened_tab_) { 92 if (fullscreened_tab_) {
89 if (web_contents != fullscreened_tab_) 93 if (web_contents != fullscreened_tab_)
90 return; 94 return;
91 } else if ( 95 } else if (
92 web_contents != browser_->tab_strip_model()->GetActiveWebContents()) { 96 web_contents != browser_->tab_strip_model()->GetActiveWebContents()) {
93 return; 97 return;
94 } 98 }
95 if (IsFullscreenForTabOrPending() == enter_fullscreen) 99 if (IsFullscreenForTabOrPending() == enter_fullscreen)
96 return; 100 return;
97 101
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 } 215 }
212 216
213 bool FullscreenController::IsMouseLocked() const { 217 bool FullscreenController::IsMouseLocked() const {
214 return mouse_lock_state_ == MOUSELOCK_ACCEPTED || 218 return mouse_lock_state_ == MOUSELOCK_ACCEPTED ||
215 mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY; 219 mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY;
216 } 220 }
217 221
218 void FullscreenController::RequestToLockMouse(WebContents* web_contents, 222 void FullscreenController::RequestToLockMouse(WebContents* web_contents,
219 bool user_gesture, 223 bool user_gesture,
220 bool last_unlocked_by_target) { 224 bool last_unlocked_by_target) {
225 if (IsCapturedFullscreenTab(web_contents)) {
scheib 2014/02/12 01:41:16 Won't this break the use case of casting play of f
miu 2014/02/12 08:25:19 Resolved. I took this code out and mouse lock wor
226 web_contents->GotResponseToLockMouseRequest(false);
227 return;
228 }
229
221 DCHECK(!IsMouseLocked()); 230 DCHECK(!IsMouseLocked());
222 NotifyMouseLockChange(); 231 NotifyMouseLockChange();
223 232
224 // Must have a user gesture to prevent misbehaving sites from constantly 233 // Must have a user gesture to prevent misbehaving sites from constantly
225 // re-locking the mouse. Exceptions are when the page has unlocked 234 // re-locking the mouse. Exceptions are when the page has unlocked
226 // (i.e. not the user), or if we're in tab fullscreen (user gesture required 235 // (i.e. not the user), or if we're in tab fullscreen (user gesture required
227 // for that) 236 // for that)
228 if (!last_unlocked_by_target && !user_gesture && 237 if (!last_unlocked_by_target && !user_gesture &&
229 !IsFullscreenForTabOrPending(web_contents)) { 238 !IsFullscreenForTabOrPending(web_contents)) {
230 web_contents->GotResponseToLockMouseRequest(false); 239 web_contents->GotResponseToLockMouseRequest(false);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 NOTREACHED(); 275 NOTREACHED();
267 } 276 }
268 UpdateFullscreenExitBubbleContent(); 277 UpdateFullscreenExitBubbleContent();
269 } 278 }
270 279
271 void FullscreenController::OnTabDeactivated(WebContents* web_contents) { 280 void FullscreenController::OnTabDeactivated(WebContents* web_contents) {
272 if (web_contents == fullscreened_tab_ || web_contents == mouse_lock_tab_) 281 if (web_contents == fullscreened_tab_ || web_contents == mouse_lock_tab_)
273 ExitTabFullscreenOrMouseLockIfNecessary(); 282 ExitTabFullscreenOrMouseLockIfNecessary();
274 } 283 }
275 284
285 void FullscreenController::OnTabDetachedFromView(WebContents* old_contents) {
scheib 2014/02/12 01:41:16 So far I haven't noticed when we resize content ba
miu 2014/02/12 08:25:19 Done. (Reworked this into the comment a few lines
286 if (!IsCapturedFullscreenTab(old_contents))
287 return;
288
289 // After detaching an embedded fullscreen view undergoing screen capture, set
290 // it to exactly the WebContents' preferred size. This will allow it to be
291 // rendered and captured at the ideal resolution while the tab is being
292 // backgroundend by the user.
293 if (old_contents->GetCapturerCount() == 0 ||
294 old_contents->GetPreferredSize().IsEmpty()) {
295 // Do nothing if tab capture ended after toggling fullscreen, or a preferred
296 // size was never specified by the capturer.
297 return;
298 }
299 content::RenderWidgetHostView* const current_fs_view =
300 old_contents->GetFullscreenRenderWidgetHostView();
301 if (current_fs_view)
302 current_fs_view->SetSize(old_contents->GetPreferredSize());
303 old_contents->GetView()->SizeContents(old_contents->GetPreferredSize());
304 }
305
276 void FullscreenController::OnTabClosing(WebContents* web_contents) { 306 void FullscreenController::OnTabClosing(WebContents* web_contents) {
277 if (web_contents == fullscreened_tab_ || web_contents == mouse_lock_tab_) { 307 if (IsCapturedFullscreenTab(web_contents)) {
308 RenderViewHost* const rvh = web_contents->GetRenderViewHost();
309 if (rvh)
310 rvh->ExitFullscreen();
311 } else if (web_contents == fullscreened_tab_ ||
312 web_contents == mouse_lock_tab_) {
278 ExitTabFullscreenOrMouseLockIfNecessary(); 313 ExitTabFullscreenOrMouseLockIfNecessary();
279 // The call to exit fullscreen may result in asynchronous notification of 314 // The call to exit fullscreen may result in asynchronous notification of
280 // fullscreen state change (e.g., on Linux). We don't want to rely on it 315 // fullscreen state change (e.g., on Linux). We don't want to rely on it
281 // to call NotifyTabOfExitIfNecessary(), because at that point 316 // to call NotifyTabOfExitIfNecessary(), because at that point
282 // |fullscreened_tab_| may not be valid. Instead, we call it here to clean 317 // |fullscreened_tab_| may not be valid. Instead, we call it here to clean
283 // up tab fullscreen related state. 318 // up tab fullscreen related state.
284 NotifyTabOfExitIfNecessary(); 319 NotifyTabOfExitIfNecessary();
285 } 320 }
286 } 321 }
287 322
(...skipping 11 matching lines...) Expand all
299 if (exiting_fullscreen) { 334 if (exiting_fullscreen) {
300 window_->GetDownloadShelf()->Unhide(); 335 window_->GetDownloadShelf()->Unhide();
301 } else { 336 } else {
302 window_->GetDownloadShelf()->Hide(); 337 window_->GetDownloadShelf()->Hide();
303 if (window_->GetStatusBubble()) 338 if (window_->GetStatusBubble())
304 window_->GetStatusBubble()->Hide(); 339 window_->GetStatusBubble()->Hide();
305 } 340 }
306 } 341 }
307 342
308 bool FullscreenController::HandleUserPressedEscape() { 343 bool FullscreenController::HandleUserPressedEscape() {
309 if (IsFullscreenForTabOrPending() || 344 WebContents* const active_web_contents =
310 IsMouseLocked() || IsMouseLockRequested()) { 345 browser_->tab_strip_model()->GetActiveWebContents();
346 if (IsCapturedFullscreenTab(active_web_contents)) {
347 RenderViewHost* const rvh = active_web_contents->GetRenderViewHost();
348 if (rvh)
349 rvh->ExitFullscreen();
350 return true;
351 } else if (IsFullscreenForTabOrPending() ||
352 IsMouseLocked() || IsMouseLockRequested()) {
311 ExitTabFullscreenOrMouseLockIfNecessary(); 353 ExitTabFullscreenOrMouseLockIfNecessary();
312 return true; 354 return true;
313 } 355 }
314 356
315 return false; 357 return false;
316 } 358 }
317 359
318 void FullscreenController::ExitTabOrBrowserFullscreenToPreviousState() { 360 void FullscreenController::ExitTabOrBrowserFullscreenToPreviousState() {
319 if (IsFullscreenForTabOrPending()) 361 if (IsFullscreenForTabOrPending())
320 ExitTabFullscreenOrMouseLockIfNecessary(); 362 ExitTabFullscreenOrMouseLockIfNecessary();
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 714
673 HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap(); 715 HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap();
674 return settings_map->GetContentSetting(url, url, 716 return settings_map->GetContentSetting(url, url,
675 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string()); 717 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string());
676 } 718 }
677 719
678 bool FullscreenController::IsPrivilegedFullscreenForTab() const { 720 bool FullscreenController::IsPrivilegedFullscreenForTab() const {
679 const bool embedded_widget_present = 721 const bool embedded_widget_present =
680 fullscreened_tab_ && 722 fullscreened_tab_ &&
681 fullscreened_tab_->GetFullscreenRenderWidgetHostView() && 723 fullscreened_tab_->GetFullscreenRenderWidgetHostView() &&
682 implicit_cast<const content::WebContentsDelegate*>(browser_)-> 724 IsEmbeddedFullscreenEnabled();
683 EmbedsFullscreenWidget();
684 return embedded_widget_present || is_privileged_fullscreen_for_testing_; 725 return embedded_widget_present || is_privileged_fullscreen_for_testing_;
685 } 726 }
686 727
687 void FullscreenController::SetPrivilegedFullscreenForTesting( 728 void FullscreenController::SetPrivilegedFullscreenForTesting(
688 bool is_privileged) { 729 bool is_privileged) {
689 is_privileged_fullscreen_for_testing_ = is_privileged; 730 is_privileged_fullscreen_for_testing_ = is_privileged;
690 } 731 }
691 732
733 bool FullscreenController::IsEmbeddedFullscreenEnabled() const {
734 return implicit_cast<const content::WebContentsDelegate*>(browser_)->
735 EmbedsFullscreenWidget();
736 }
737
738 bool FullscreenController::MaybeToggleAsFullscreenWithinTab(
739 WebContents* web_contents, bool enter_fullscreen) {
740 if (!IsEmbeddedFullscreenEnabled())
741 return false;
742
743 if (enter_fullscreen) {
744 if (web_contents->GetCapturerCount() > 0) {
745 if (std::find(captured_tabs_.begin(), captured_tabs_.end(),
scheib 2014/02/12 01:41:16 why not just std::set::insert()?
miu 2014/02/12 08:25:19 Done.
746 web_contents) == captured_tabs_.end()) {
747 captured_tabs_.push_back(web_contents);
748 }
749 return true;
750 }
751 } else {
752 const std::vector<const WebContents*>::iterator it =
753 std::find(captured_tabs_.begin(), captured_tabs_.end(), web_contents);
754 if (it != captured_tabs_.end()) {
scheib 2014/02/12 01:41:16 captured_tabs_.find(web_contents) != captured_tabs
miu 2014/02/12 08:25:19 Done.
755 captured_tabs_.erase(it);
756 return true;
757 }
758 }
759
760 return false;
761 }
762
763 bool FullscreenController::IsCapturedFullscreenTab(
764 const WebContents* web_contents) const {
765 if (std::find(captured_tabs_.begin(), captured_tabs_.end(), web_contents) !=
766 captured_tabs_.end()) {
767 DCHECK(IsEmbeddedFullscreenEnabled());
768 DCHECK_NE(fullscreened_tab_, web_contents);
769 DCHECK_NE(mouse_lock_tab_, web_contents);
miu 2014/02/12 08:25:19 I removed this since it was wrong (i.e., mouse loc
770 return true;
771 }
772 return false;
773 }
774
692 void FullscreenController::UnlockMouse() { 775 void FullscreenController::UnlockMouse() {
693 if (!mouse_lock_tab_) 776 if (!mouse_lock_tab_)
694 return; 777 return;
695 content::RenderWidgetHostView* mouse_lock_view = 778 content::RenderWidgetHostView* mouse_lock_view =
696 (fullscreened_tab_ == mouse_lock_tab_ && IsPrivilegedFullscreenForTab()) ? 779 (fullscreened_tab_ == mouse_lock_tab_ && IsPrivilegedFullscreenForTab()) ?
697 mouse_lock_tab_->GetFullscreenRenderWidgetHostView() : NULL; 780 mouse_lock_tab_->GetFullscreenRenderWidgetHostView() : NULL;
698 if (!mouse_lock_view) { 781 if (!mouse_lock_view) {
699 RenderViewHost* const rvh = mouse_lock_tab_->GetRenderViewHost(); 782 RenderViewHost* const rvh = mouse_lock_tab_->GetRenderViewHost();
700 if (rvh) 783 if (rvh)
701 mouse_lock_view = rvh->GetView(); 784 mouse_lock_view = rvh->GetView();
702 } 785 }
703 if (mouse_lock_view) 786 if (mouse_lock_view)
704 mouse_lock_view->UnlockMouse(); 787 mouse_lock_view->UnlockMouse();
705 } 788 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698