OLD | NEW |
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.h" | 9 #include "base/message_loop.h" |
10 #include "chrome/browser/content_settings/host_content_settings_map.h" | 10 #include "chrome/browser/content_settings/host_content_settings_map.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 | 50 |
51 FullscreenController::~FullscreenController() { | 51 FullscreenController::~FullscreenController() { |
52 } | 52 } |
53 | 53 |
54 bool FullscreenController::IsFullscreenForBrowser() const { | 54 bool FullscreenController::IsFullscreenForBrowser() const { |
55 return window_->IsFullscreen() && !tab_caused_fullscreen_; | 55 return window_->IsFullscreen() && !tab_caused_fullscreen_; |
56 } | 56 } |
57 | 57 |
58 void FullscreenController::ToggleFullscreenMode() { | 58 void FullscreenController::ToggleFullscreenMode() { |
59 extension_caused_fullscreen_ = GURL(); | 59 extension_caused_fullscreen_ = GURL(); |
60 ToggleFullscreenModeInternal(false); | 60 ToggleFullscreenModeInternal(false, false); |
61 } | 61 } |
62 | 62 |
63 bool FullscreenController::IsFullscreenForTabOrPending() const { | 63 bool FullscreenController::IsFullscreenForTabOrPending() const { |
64 return fullscreened_tab_ != NULL; | 64 return fullscreened_tab_ != NULL; |
65 } | 65 } |
66 | 66 |
67 bool FullscreenController::IsFullscreenForTabOrPending( | 67 bool FullscreenController::IsFullscreenForTabOrPending( |
68 const WebContents* web_contents) const { | 68 const WebContents* web_contents) const { |
69 if (web_contents != fullscreened_tab_) | 69 if (web_contents != fullscreened_tab_) |
70 return false; | 70 return false; |
(...skipping 14 matching lines...) Expand all Loading... |
85 if (IsInMetroSnapMode()) | 85 if (IsInMetroSnapMode()) |
86 return; | 86 return; |
87 #endif | 87 #endif |
88 | 88 |
89 bool in_browser_or_tab_fullscreen_mode = window_->IsFullscreen(); | 89 bool in_browser_or_tab_fullscreen_mode = window_->IsFullscreen(); |
90 | 90 |
91 if (enter_fullscreen) { | 91 if (enter_fullscreen) { |
92 SetFullscreenedTab(web_contents); | 92 SetFullscreenedTab(web_contents); |
93 if (!in_browser_or_tab_fullscreen_mode) { | 93 if (!in_browser_or_tab_fullscreen_mode) { |
94 tab_caused_fullscreen_ = true; | 94 tab_caused_fullscreen_ = true; |
95 #if defined(OS_MACOSX) | 95 ToggleFullscreenModeInternal(true, false); |
96 TogglePresentationModeInternal(true); | |
97 #else | |
98 ToggleFullscreenModeInternal(true); | |
99 #endif | |
100 } else { | 96 } else { |
101 // We need to update the fullscreen exit bubble, e.g., going from browser | 97 // We need to update the fullscreen exit bubble, e.g., going from browser |
102 // fullscreen to tab fullscreen will need to show different content. | 98 // fullscreen to tab fullscreen will need to show different content. |
103 const GURL& url = web_contents->GetURL(); | 99 const GURL& url = web_contents->GetURL(); |
104 if (!tab_fullscreen_accepted_) { | 100 if (!tab_fullscreen_accepted_) { |
105 tab_fullscreen_accepted_ = | 101 tab_fullscreen_accepted_ = |
106 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; | 102 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; |
107 } | 103 } |
108 UpdateFullscreenExitBubbleContent(); | 104 UpdateFullscreenExitBubbleContent(); |
109 | 105 |
110 // This is only a change between Browser and Tab fullscreen. We generate | 106 // This is only a change between Browser and Tab fullscreen. We generate |
111 // a fullscreen notification now because there is no window change. | 107 // a fullscreen notification now because there is no window change. |
112 PostFullscreenChangeNotification(true); | 108 PostFullscreenChangeNotification(true); |
113 } | 109 } |
114 } else { | 110 } else { |
115 if (in_browser_or_tab_fullscreen_mode) { | 111 if (in_browser_or_tab_fullscreen_mode) { |
116 if (tab_caused_fullscreen_) { | 112 if (tab_caused_fullscreen_) { |
117 #if defined(OS_MACOSX) | 113 ToggleFullscreenModeInternal(true, false); |
118 TogglePresentationModeInternal(true); | |
119 #else | |
120 ToggleFullscreenModeInternal(true); | |
121 #endif | |
122 } else { | 114 } else { |
123 // If currently there is a tab in "tab fullscreen" mode and fullscreen | 115 // If currently there is a tab in "tab fullscreen" mode and fullscreen |
124 // was not caused by it (i.e., previously it was in "browser fullscreen" | 116 // was not caused by it (i.e., previously it was in "browser fullscreen" |
125 // mode), we need to switch back to "browser fullscreen" mode. In this | 117 // mode), we need to switch back to "browser fullscreen" mode. In this |
126 // case, all we have to do is notifying the tab that it has exited "tab | 118 // case, all we have to do is notifying the tab that it has exited "tab |
127 // fullscreen" mode. | 119 // fullscreen" mode. |
128 NotifyTabOfExitIfNecessary(); | 120 NotifyTabOfExitIfNecessary(); |
129 | 121 |
130 // This is only a change between Browser and Tab fullscreen. We generate | 122 // This is only a change between Browser and Tab fullscreen. We generate |
131 // a fullscreen notification now because there is no window change. | 123 // a fullscreen notification now because there is no window change. |
132 PostFullscreenChangeNotification(true); | 124 PostFullscreenChangeNotification(true); |
133 } | 125 } |
134 } | 126 } |
135 } | 127 } |
136 } | 128 } |
137 | 129 |
138 void FullscreenController::ToggleFullscreenModeWithExtension( | 130 void FullscreenController::ToggleFullscreenModeWithExtension( |
139 const GURL& extension_url) { | 131 const GURL& extension_url) { |
140 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to | 132 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to |
141 // exit. | 133 // exit. |
142 extension_caused_fullscreen_ = extension_url; | 134 extension_caused_fullscreen_ = extension_url; |
143 ToggleFullscreenModeInternal(false); | 135 ToggleFullscreenModeInternal(false, false); |
144 } | 136 } |
145 | 137 |
146 bool FullscreenController::IsInMetroSnapMode() { | 138 bool FullscreenController::IsInMetroSnapMode() { |
147 #if defined(OS_WIN) | 139 #if defined(OS_WIN) |
148 return window_->IsInMetroSnapMode(); | 140 return window_->IsInMetroSnapMode(); |
149 #else | 141 #else |
150 return false; | 142 return false; |
151 #endif | 143 #endif |
152 } | 144 } |
153 | 145 |
154 #if defined(OS_WIN) | 146 #if defined(OS_WIN) |
155 void FullscreenController::SetMetroSnapMode(bool enable) { | 147 void FullscreenController::SetMetroSnapMode(bool enable) { |
156 reentrant_window_state_change_call_check_ = false; | 148 reentrant_window_state_change_call_check_ = false; |
157 | 149 |
158 toggled_into_fullscreen_ = false; | 150 toggled_into_fullscreen_ = false; |
159 window_->SetMetroSnapMode(enable); | 151 window_->SetMetroSnapMode(enable); |
160 | 152 |
161 // FullscreenController unit tests for metro snap assume that on Windows calls | 153 // FullscreenController unit tests for metro snap assume that on Windows calls |
162 // to WindowFullscreenStateChanged are reentrant. If that assumption is | 154 // to WindowFullscreenStateChanged are reentrant. If that assumption is |
163 // invalidated, the tests must be updated to maintain coverage. | 155 // invalidated, the tests must be updated to maintain coverage. |
164 CHECK(reentrant_window_state_change_call_check_); | 156 CHECK(reentrant_window_state_change_call_check_); |
165 } | 157 } |
166 #endif // defined(OS_WIN) | 158 #endif // defined(OS_WIN) |
167 | 159 |
168 #if defined(OS_MACOSX) | 160 #if defined(OS_MACOSX) |
169 void FullscreenController::TogglePresentationMode() { | 161 void FullscreenController::ToggleFullscreenWithChrome() { |
170 TogglePresentationModeInternal(false); | 162 ToggleFullscreenModeInternal(false, true); |
171 } | 163 } |
172 #endif | 164 #endif |
173 | 165 |
174 bool FullscreenController::IsMouseLockRequested() const { | 166 bool FullscreenController::IsMouseLockRequested() const { |
175 return mouse_lock_state_ == MOUSELOCK_REQUESTED; | 167 return mouse_lock_state_ == MOUSELOCK_REQUESTED; |
176 } | 168 } |
177 | 169 |
178 bool FullscreenController::IsMouseLocked() const { | 170 bool FullscreenController::IsMouseLocked() const { |
179 return mouse_lock_state_ == MOUSELOCK_ACCEPTED || | 171 return mouse_lock_state_ == MOUSELOCK_ACCEPTED || |
180 mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY; | 172 mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 return true; | 262 return true; |
271 } | 263 } |
272 | 264 |
273 return false; | 265 return false; |
274 } | 266 } |
275 | 267 |
276 void FullscreenController::ExitTabOrBrowserFullscreenToPreviousState() { | 268 void FullscreenController::ExitTabOrBrowserFullscreenToPreviousState() { |
277 if (IsFullscreenForTabOrPending()) | 269 if (IsFullscreenForTabOrPending()) |
278 ExitTabFullscreenOrMouseLockIfNecessary(); | 270 ExitTabFullscreenOrMouseLockIfNecessary(); |
279 else if (IsFullscreenForBrowser()) | 271 else if (IsFullscreenForBrowser()) |
280 #if defined(OS_MACOSX) | 272 ExitFullscreenModeInternal(); |
281 TogglePresentationMode(); | |
282 #else | |
283 ToggleFullscreenMode(); | |
284 #endif | |
285 } | 273 } |
286 | 274 |
287 void FullscreenController::OnAcceptFullscreenPermission() { | 275 void FullscreenController::OnAcceptFullscreenPermission() { |
288 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); | 276 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); |
289 bool mouse_lock = false; | 277 bool mouse_lock = false; |
290 bool fullscreen = false; | 278 bool fullscreen = false; |
291 fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen, | 279 fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen, |
292 &mouse_lock); | 280 &mouse_lock); |
293 DCHECK(!(fullscreen && tab_fullscreen_accepted_)); | 281 DCHECK(!(fullscreen && tab_fullscreen_accepted_)); |
294 DCHECK(!(mouse_lock && IsMouseLocked())); | 282 DCHECK(!(mouse_lock && IsMouseLocked())); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 } | 477 } |
490 | 478 |
491 void FullscreenController::NotifyMouseLockChange() { | 479 void FullscreenController::NotifyMouseLockChange() { |
492 content::NotificationService::current()->Notify( | 480 content::NotificationService::current()->Notify( |
493 chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, | 481 chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, |
494 content::Source<FullscreenController>(this), | 482 content::Source<FullscreenController>(this), |
495 content::NotificationService::NoDetails()); | 483 content::NotificationService::NoDetails()); |
496 } | 484 } |
497 | 485 |
498 // TODO(koz): Change |for_tab| to an enum. | 486 // TODO(koz): Change |for_tab| to an enum. |
499 void FullscreenController::ToggleFullscreenModeInternal(bool for_tab) { | 487 void FullscreenController::ToggleFullscreenModeInternal(bool for_tab, |
| 488 bool with_chrome) { |
500 #if defined(OS_WIN) | 489 #if defined(OS_WIN) |
501 // When in Metro snap mode, toggling in and out of fullscreen is prevented. | 490 // When in Metro snap mode, toggling in and out of fullscreen is prevented. |
502 if (IsInMetroSnapMode()) | 491 if (IsInMetroSnapMode()) |
503 return; | 492 return; |
504 #endif | 493 #endif |
505 | 494 |
506 toggled_into_fullscreen_ = !window_->IsFullscreen(); | 495 bool enter_fullscreen = !window_->IsFullscreen(); |
507 #if defined(OS_MACOSX) | 496 #if defined(OS_MACOSX) |
508 // When a Mac user requests a toggle they may be transitioning from | 497 // When a Mac user requests a toggle they may be toggling between |
509 // FullscreenWithoutChrome to FullscreenWithChrome. | 498 // FullscreenWithoutChrome and FullscreenWithChrome. |
510 if (!IsFullscreenForTabOrPending()) | 499 if (!IsFullscreenForTabOrPending()) { |
511 toggled_into_fullscreen_ |= window_->IsFullscreenWithoutChrome(); | 500 enter_fullscreen |= with_chrome && window_->IsFullscreenWithoutChrome(); |
| 501 enter_fullscreen |= !with_chrome && window_->IsFullscreenWithChrome(); |
| 502 } |
512 #endif | 503 #endif |
513 | 504 |
514 // In kiosk mode, we always want to be fullscreen. When the browser first | 505 // In kiosk mode, we always want to be fullscreen. When the browser first |
515 // starts we're not yet fullscreen, so let the initial toggle go through. | 506 // starts we're not yet fullscreen, so let the initial toggle go through. |
516 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) && | 507 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) && |
517 !toggled_into_fullscreen_) | 508 window_->IsFullscreen()) |
518 return; | 509 return; |
519 | 510 |
| 511 if (enter_fullscreen) |
| 512 EnterFullscreenModeInternal(for_tab, with_chrome); |
| 513 else |
| 514 ExitFullscreenModeInternal(); |
| 515 } |
| 516 |
| 517 void FullscreenController::EnterFullscreenModeInternal(bool for_tab, |
| 518 bool with_chrome) { |
| 519 toggled_into_fullscreen_ = true; |
520 GURL url; | 520 GURL url; |
521 if (for_tab) { | 521 if (for_tab) { |
522 url = chrome::GetActiveWebContents(browser_)->GetURL(); | 522 url = chrome::GetActiveWebContents(browser_)->GetURL(); |
523 tab_fullscreen_accepted_ = toggled_into_fullscreen_ && | 523 tab_fullscreen_accepted_ = |
524 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; | 524 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; |
525 } else { | 525 } else { |
526 if (!extension_caused_fullscreen_.is_empty()) | 526 if (!extension_caused_fullscreen_.is_empty()) |
527 url = extension_caused_fullscreen_; | 527 url = extension_caused_fullscreen_; |
528 content::RecordAction(UserMetricsAction("ToggleFullscreen")); | 528 content::RecordAction(UserMetricsAction("ToggleFullscreen")); |
529 } | 529 } |
530 if (toggled_into_fullscreen_) { | 530 if (with_chrome) { |
531 #if defined(OS_MACOSX) | 531 #if defined(OS_MACOSX) |
532 CHECK(!for_tab); // EnterFullscreenWithChrome invalid for tab fullscreen. | 532 CHECK(!for_tab); // EnterFullscreenWithChrome invalid for tab fullscreen. |
533 CHECK(base::mac::IsOSLionOrLater()); | 533 CHECK(base::mac::IsOSLionOrLater()); |
534 window_->EnterFullscreenWithChrome(); | 534 window_->EnterFullscreenWithChrome(); |
535 #else | 535 #else |
536 window_->EnterFullscreen(url, GetFullscreenExitBubbleType()); | 536 NOTREACHED(); |
537 #endif | 537 #endif |
538 } else { | 538 } else { |
539 #if defined(OS_MACOSX) | 539 window_->EnterFullscreen(url, GetFullscreenExitBubbleType()); |
540 // Mac windows report a state change instantly, and so we must also clear | |
541 // tab_caused_fullscreen_ to match them else other logic using | |
542 // tab_caused_fullscreen_ will be incorrect. | |
543 NotifyTabOfExitIfNecessary(); | |
544 #endif | |
545 window_->ExitFullscreen(); | |
546 extension_caused_fullscreen_ = GURL(); | |
547 } | 540 } |
| 541 |
548 UpdateFullscreenExitBubbleContent(); | 542 UpdateFullscreenExitBubbleContent(); |
549 | 543 |
550 // Once the window has become fullscreen it'll call back to | 544 // Once the window has become fullscreen it'll call back to |
551 // WindowFullscreenStateChanged(). We don't do this immediately as | 545 // WindowFullscreenStateChanged(). We don't do this immediately as |
552 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let | 546 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let |
553 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate. | 547 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate. |
554 } | 548 } |
555 | 549 |
| 550 void FullscreenController::ExitFullscreenModeInternal() { |
| 551 toggled_into_fullscreen_ = false; |
556 #if defined(OS_MACOSX) | 552 #if defined(OS_MACOSX) |
557 void FullscreenController::TogglePresentationModeInternal(bool for_tab) { | 553 // Mac windows report a state change instantly, and so we must also clear |
558 toggled_into_fullscreen_ = !window_->IsFullscreenWithoutChrome(); | 554 // tab_caused_fullscreen_ to match them else other logic using |
559 GURL url; | 555 // tab_caused_fullscreen_ will be incorrect. |
560 if (for_tab) { | 556 NotifyTabOfExitIfNecessary(); |
561 url = chrome::GetActiveWebContents(browser_)->GetURL(); | 557 #endif |
562 tab_fullscreen_accepted_ = toggled_into_fullscreen_ && | 558 window_->ExitFullscreen(); |
563 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; | 559 extension_caused_fullscreen_ = GURL(); |
564 } | |
565 if (!window_->IsFullscreenWithoutChrome()) { | |
566 window_->EnterFullscreen(url, GetFullscreenExitBubbleType()); | |
567 } else { | |
568 window_->ExitFullscreen(); | |
569 | 560 |
570 // Mac windows report a state change instantly, and so we must also clear | |
571 // tab_caused_fullscreen_ to match them else other logic using | |
572 // tab_caused_fullscreen_ will be incorrect. | |
573 NotifyTabOfExitIfNecessary(); | |
574 } | |
575 UpdateFullscreenExitBubbleContent(); | 561 UpdateFullscreenExitBubbleContent(); |
576 | |
577 // WindowFullscreenStateChanged will be called by BrowserWindowController | |
578 // when the transition completes. | |
579 } | 562 } |
580 #endif | |
581 | 563 |
582 void FullscreenController::SetFullscreenedTab(WebContents* tab) { | 564 void FullscreenController::SetFullscreenedTab(WebContents* tab) { |
583 fullscreened_tab_ = tab; | 565 fullscreened_tab_ = tab; |
584 UpdateNotificationRegistrations(); | 566 UpdateNotificationRegistrations(); |
585 } | 567 } |
586 | 568 |
587 void FullscreenController::SetMouseLockTab(WebContents* tab) { | 569 void FullscreenController::SetMouseLockTab(WebContents* tab) { |
588 mouse_lock_tab_ = tab; | 570 mouse_lock_tab_ = tab; |
589 UpdateNotificationRegistrations(); | 571 UpdateNotificationRegistrations(); |
590 } | 572 } |
591 | 573 |
592 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() { | 574 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() { |
593 if (tab_caused_fullscreen_) | 575 if (tab_caused_fullscreen_) |
594 ToggleFullscreenModeInternal(true); | 576 ToggleFullscreenModeInternal(true, false); |
595 else | 577 else |
596 NotifyTabOfExitIfNecessary(); | 578 NotifyTabOfExitIfNecessary(); |
597 } | 579 } |
598 | 580 |
599 void FullscreenController::UpdateFullscreenExitBubbleContent() { | 581 void FullscreenController::UpdateFullscreenExitBubbleContent() { |
600 GURL url = GetFullscreenExitBubbleURL(); | 582 GURL url = GetFullscreenExitBubbleURL(); |
601 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); | 583 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); |
602 | 584 |
603 // If bubble displays buttons, unlock mouse to allow pressing them. | 585 // If bubble displays buttons, unlock mouse to allow pressing them. |
604 if (fullscreen_bubble::ShowButtonsForType(bubble_type) && | 586 if (fullscreen_bubble::ShowButtonsForType(bubble_type) && |
(...skipping 18 matching lines...) Expand all Loading... |
623 | 605 |
624 ContentSetting | 606 ContentSetting |
625 FullscreenController::GetMouseLockSetting(const GURL& url) const { | 607 FullscreenController::GetMouseLockSetting(const GURL& url) const { |
626 if (url.SchemeIsFile()) | 608 if (url.SchemeIsFile()) |
627 return CONTENT_SETTING_ALLOW; | 609 return CONTENT_SETTING_ALLOW; |
628 | 610 |
629 HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap(); | 611 HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap(); |
630 return settings_map->GetContentSetting(url, url, | 612 return settings_map->GetContentSetting(url, url, |
631 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string()); | 613 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string()); |
632 } | 614 } |
OLD | NEW |