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(BROWSER); |
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(TAB); |
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(TAB); |
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(BROWSER); |
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(BROWSER_WITH_CHROME); |
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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 if (IsFullscreenForTabOrPending() || | 259 if (IsFullscreenForTabOrPending() || |
268 IsMouseLocked() || IsMouseLockRequested()) { | 260 IsMouseLocked() || IsMouseLockRequested()) { |
269 ExitTabFullscreenOrMouseLockIfNecessary(); | 261 ExitTabFullscreenOrMouseLockIfNecessary(); |
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 } | |
286 } | 273 } |
287 | 274 |
288 void FullscreenController::OnAcceptFullscreenPermission() { | 275 void FullscreenController::OnAcceptFullscreenPermission() { |
289 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); | 276 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); |
290 bool mouse_lock = false; | 277 bool mouse_lock = false; |
291 bool fullscreen = false; | 278 bool fullscreen = false; |
292 fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen, | 279 fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen, |
293 &mouse_lock); | 280 &mouse_lock); |
294 DCHECK(!(fullscreen && tab_fullscreen_accepted_)); | 281 DCHECK(!(fullscreen && tab_fullscreen_accepted_)); |
295 DCHECK(!(mouse_lock && IsMouseLocked())); | 282 DCHECK(!(mouse_lock && IsMouseLocked())); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 } | 477 } |
491 | 478 |
492 void FullscreenController::NotifyMouseLockChange() { | 479 void FullscreenController::NotifyMouseLockChange() { |
493 content::NotificationService::current()->Notify( | 480 content::NotificationService::current()->Notify( |
494 chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, | 481 chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, |
495 content::Source<FullscreenController>(this), | 482 content::Source<FullscreenController>(this), |
496 content::NotificationService::NoDetails()); | 483 content::NotificationService::NoDetails()); |
497 } | 484 } |
498 | 485 |
499 // TODO(koz): Change |for_tab| to an enum. | 486 // TODO(koz): Change |for_tab| to an enum. |
500 void FullscreenController::ToggleFullscreenModeInternal(bool for_tab) { | 487 void FullscreenController::ToggleFullscreenModeInternal( |
| 488 FullscreenInternalOption option) { |
501 #if defined(OS_WIN) | 489 #if defined(OS_WIN) |
502 // 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. |
503 if (IsInMetroSnapMode()) | 491 if (IsInMetroSnapMode()) |
504 return; | 492 return; |
505 #endif | 493 #endif |
506 | 494 |
507 toggled_into_fullscreen_ = !window_->IsFullscreen(); | 495 bool enter_fullscreen = !window_->IsFullscreen(); |
508 #if defined(OS_MACOSX) | 496 #if defined(OS_MACOSX) |
509 // 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 |
510 // FullscreenWithoutChrome to FullscreenWithChrome. | 498 // FullscreenWithoutChrome and FullscreenWithChrome. |
511 if (!IsFullscreenForTabOrPending()) | 499 if (!IsFullscreenForTabOrPending()) { |
512 toggled_into_fullscreen_ |= window_->IsFullscreenWithoutChrome(); | 500 if (option == BROWSER_WITH_CHROME) |
| 501 enter_fullscreen |= window_->IsFullscreenWithoutChrome(); |
| 502 else |
| 503 enter_fullscreen |= window_->IsFullscreenWithChrome(); |
| 504 } |
513 #endif | 505 #endif |
514 | 506 |
515 // In kiosk mode, we always want to be fullscreen. When the browser first | 507 // In kiosk mode, we always want to be fullscreen. When the browser first |
516 // starts we're not yet fullscreen, so let the initial toggle go through. | 508 // starts we're not yet fullscreen, so let the initial toggle go through. |
517 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) && | 509 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) && |
518 !toggled_into_fullscreen_) | 510 window_->IsFullscreen()) |
519 return; | 511 return; |
520 | 512 |
| 513 if (enter_fullscreen) |
| 514 EnterFullscreenModeInternal(option); |
| 515 else |
| 516 ExitFullscreenModeInternal(); |
| 517 } |
| 518 |
| 519 void FullscreenController::EnterFullscreenModeInternal( |
| 520 FullscreenInternalOption option) { |
| 521 toggled_into_fullscreen_ = true; |
521 GURL url; | 522 GURL url; |
522 if (for_tab) { | 523 if (option == TAB) { |
523 url = browser_->tab_strip_model()->GetActiveWebContents()->GetURL(); | 524 url = browser_->tab_strip_model()->GetActiveWebContents()->GetURL(); |
524 tab_fullscreen_accepted_ = toggled_into_fullscreen_ && | 525 tab_fullscreen_accepted_ = |
525 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; | 526 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; |
526 } else { | 527 } else { |
527 if (!extension_caused_fullscreen_.is_empty()) | 528 if (!extension_caused_fullscreen_.is_empty()) |
528 url = extension_caused_fullscreen_; | 529 url = extension_caused_fullscreen_; |
529 content::RecordAction(UserMetricsAction("ToggleFullscreen")); | 530 content::RecordAction(UserMetricsAction("ToggleFullscreen")); |
530 } | 531 } |
531 if (toggled_into_fullscreen_) { | 532 |
532 #if defined(OS_MACOSX) | 533 #if defined(OS_MACOSX) |
533 CHECK(!for_tab); // EnterFullscreenWithChrome invalid for tab fullscreen. | 534 if (option == BROWSER_WITH_CHROME) { |
534 CHECK(base::mac::IsOSLionOrLater()); | 535 CHECK(base::mac::IsOSLionOrLater()); |
535 window_->EnterFullscreenWithChrome(); | 536 window_->EnterFullscreenWithChrome(); |
| 537 } else { |
536 #else | 538 #else |
| 539 { |
| 540 #endif |
537 window_->EnterFullscreen(url, GetFullscreenExitBubbleType()); | 541 window_->EnterFullscreen(url, GetFullscreenExitBubbleType()); |
538 #endif | |
539 } else { | |
540 #if defined(OS_MACOSX) | |
541 // Mac windows report a state change instantly, and so we must also clear | |
542 // tab_caused_fullscreen_ to match them else other logic using | |
543 // tab_caused_fullscreen_ will be incorrect. | |
544 NotifyTabOfExitIfNecessary(); | |
545 #endif | |
546 window_->ExitFullscreen(); | |
547 extension_caused_fullscreen_ = GURL(); | |
548 } | 542 } |
| 543 |
549 UpdateFullscreenExitBubbleContent(); | 544 UpdateFullscreenExitBubbleContent(); |
550 | 545 |
551 // Once the window has become fullscreen it'll call back to | 546 // Once the window has become fullscreen it'll call back to |
552 // WindowFullscreenStateChanged(). We don't do this immediately as | 547 // WindowFullscreenStateChanged(). We don't do this immediately as |
553 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let | 548 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let |
554 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate. | 549 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate. |
555 } | 550 } |
556 | 551 |
| 552 void FullscreenController::ExitFullscreenModeInternal() { |
| 553 toggled_into_fullscreen_ = false; |
557 #if defined(OS_MACOSX) | 554 #if defined(OS_MACOSX) |
558 void FullscreenController::TogglePresentationModeInternal(bool for_tab) { | 555 // Mac windows report a state change instantly, and so we must also clear |
559 toggled_into_fullscreen_ = !window_->IsFullscreenWithoutChrome(); | 556 // tab_caused_fullscreen_ to match them else other logic using |
560 GURL url; | 557 // tab_caused_fullscreen_ will be incorrect. |
561 if (for_tab) { | 558 NotifyTabOfExitIfNecessary(); |
562 url = browser_->tab_strip_model()->GetActiveWebContents()->GetURL(); | 559 #endif |
563 tab_fullscreen_accepted_ = toggled_into_fullscreen_ && | 560 window_->ExitFullscreen(); |
564 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; | 561 extension_caused_fullscreen_ = GURL(); |
565 } | |
566 if (!window_->IsFullscreenWithoutChrome()) { | |
567 window_->EnterFullscreen(url, GetFullscreenExitBubbleType()); | |
568 } else { | |
569 window_->ExitFullscreen(); | |
570 | 562 |
571 // Mac windows report a state change instantly, and so we must also clear | |
572 // tab_caused_fullscreen_ to match them else other logic using | |
573 // tab_caused_fullscreen_ will be incorrect. | |
574 NotifyTabOfExitIfNecessary(); | |
575 } | |
576 UpdateFullscreenExitBubbleContent(); | 563 UpdateFullscreenExitBubbleContent(); |
577 | |
578 // WindowFullscreenStateChanged will be called by BrowserWindowController | |
579 // when the transition completes. | |
580 } | 564 } |
581 #endif | |
582 | 565 |
583 void FullscreenController::SetFullscreenedTab(WebContents* tab) { | 566 void FullscreenController::SetFullscreenedTab(WebContents* tab) { |
584 fullscreened_tab_ = tab; | 567 fullscreened_tab_ = tab; |
585 UpdateNotificationRegistrations(); | 568 UpdateNotificationRegistrations(); |
586 } | 569 } |
587 | 570 |
588 void FullscreenController::SetMouseLockTab(WebContents* tab) { | 571 void FullscreenController::SetMouseLockTab(WebContents* tab) { |
589 mouse_lock_tab_ = tab; | 572 mouse_lock_tab_ = tab; |
590 UpdateNotificationRegistrations(); | 573 UpdateNotificationRegistrations(); |
591 } | 574 } |
592 | 575 |
593 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() { | 576 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() { |
594 if (tab_caused_fullscreen_) | 577 if (tab_caused_fullscreen_) |
595 ToggleFullscreenModeInternal(true); | 578 ToggleFullscreenModeInternal(TAB); |
596 else | 579 else |
597 NotifyTabOfExitIfNecessary(); | 580 NotifyTabOfExitIfNecessary(); |
598 } | 581 } |
599 | 582 |
600 void FullscreenController::UpdateFullscreenExitBubbleContent() { | 583 void FullscreenController::UpdateFullscreenExitBubbleContent() { |
601 GURL url = GetFullscreenExitBubbleURL(); | 584 GURL url = GetFullscreenExitBubbleURL(); |
602 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); | 585 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); |
603 | 586 |
604 // If bubble displays buttons, unlock mouse to allow pressing them. | 587 // If bubble displays buttons, unlock mouse to allow pressing them. |
605 if (fullscreen_bubble::ShowButtonsForType(bubble_type) && | 588 if (fullscreen_bubble::ShowButtonsForType(bubble_type) && |
(...skipping 18 matching lines...) Expand all Loading... |
624 | 607 |
625 ContentSetting | 608 ContentSetting |
626 FullscreenController::GetMouseLockSetting(const GURL& url) const { | 609 FullscreenController::GetMouseLockSetting(const GURL& url) const { |
627 if (url.SchemeIsFile()) | 610 if (url.SchemeIsFile()) |
628 return CONTENT_SETTING_ALLOW; | 611 return CONTENT_SETTING_ALLOW; |
629 | 612 |
630 HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap(); | 613 HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap(); |
631 return settings_map->GetContentSetting(url, url, | 614 return settings_map->GetContentSetting(url, url, |
632 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string()); | 615 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string()); |
633 } | 616 } |
OLD | NEW |