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