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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h"
10 #include "chrome/browser/app_mode/app_mode_utils.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/content_settings/host_content_settings_map.h"
13 #include "chrome/browser/download/download_shelf.h"
14 #include "chrome/browser/fullscreen.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_window.h"
18 #include "chrome/browser/ui/status_bubble.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "content/public/browser/navigation_details.h"
22 #include "content/public/browser/navigation_entry.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/render_view_host.h"
25 #include "content/public/browser/render_widget_host_view.h"
26 #include "content/public/browser/user_metrics.h"
27 #include "content/public/browser/web_contents.h"
28 #include "extensions/common/extension.h"
30 #if defined(OS_MACOSX)
31 #include "base/mac/mac_util.h"
33 #include "base/prefs/pref_service.h"
34 #include "chrome/common/pref_names.h"
37 using base::UserMetricsAction
;
38 using content::RenderViewHost
;
39 using content::WebContents
;
41 FullscreenController::FullscreenController(Browser
* browser
)
43 window_(browser
->window()),
44 profile_(browser
->profile()),
45 fullscreened_tab_(NULL
),
46 state_prior_to_tab_fullscreen_(STATE_INVALID
),
47 tab_fullscreen_accepted_(false),
48 toggled_into_fullscreen_(false),
49 mouse_lock_tab_(NULL
),
50 mouse_lock_state_(MOUSELOCK_NOT_REQUESTED
),
51 reentrant_window_state_change_call_check_(false),
52 is_privileged_fullscreen_for_testing_(false),
58 FullscreenController::~FullscreenController() {
61 bool FullscreenController::IsFullscreenForBrowser() const {
62 return window_
->IsFullscreen() && !IsFullscreenCausedByTab();
65 void FullscreenController::ToggleFullscreenMode() {
66 extension_caused_fullscreen_
= GURL();
67 ToggleFullscreenModeInternal(BROWSER
);
70 bool FullscreenController::IsFullscreenForTabOrPending() const {
71 return fullscreened_tab_
!= NULL
;
74 bool FullscreenController::IsFullscreenForTabOrPending(
75 const WebContents
* web_contents
) const {
76 if (web_contents
!= fullscreened_tab_
)
78 DCHECK(web_contents
== browser_
->tab_strip_model()->GetActiveWebContents());
82 bool FullscreenController::IsFullscreenCausedByTab() const {
83 return state_prior_to_tab_fullscreen_
== STATE_NORMAL
;
86 void FullscreenController::ToggleFullscreenModeForTab(WebContents
* web_contents
,
87 bool enter_fullscreen
) {
88 if (fullscreened_tab_
) {
89 if (web_contents
!= fullscreened_tab_
)
92 web_contents
!= browser_
->tab_strip_model()->GetActiveWebContents()) {
95 if (IsFullscreenForTabOrPending() == enter_fullscreen
)
99 // For now, avoid breaking when initiating full screen tab mode while in
101 // TODO(robertshield): Find a way to reconcile tab-initiated fullscreen
102 // modes with metro snap.
103 if (IsInMetroSnapMode())
107 bool in_browser_or_tab_fullscreen_mode
= window_
->IsFullscreen();
108 bool window_is_fullscreen_with_chrome
= false;
109 #if defined(OS_MACOSX)
110 window_is_fullscreen_with_chrome
= window_
->IsFullscreenWithChrome();
113 if (enter_fullscreen
) {
114 SetFullscreenedTab(web_contents
);
115 if (!in_browser_or_tab_fullscreen_mode
) {
116 state_prior_to_tab_fullscreen_
= STATE_NORMAL
;
117 ToggleFullscreenModeInternal(TAB
);
118 } else if (window_is_fullscreen_with_chrome
) {
119 #if defined(OS_MACOSX)
120 state_prior_to_tab_fullscreen_
= STATE_BROWSER_FULLSCREEN_WITH_CHROME
;
121 EnterFullscreenModeInternal(TAB
);
126 state_prior_to_tab_fullscreen_
= STATE_BROWSER_FULLSCREEN_NO_CHROME
;
128 // We need to update the fullscreen exit bubble, e.g., going from browser
129 // fullscreen to tab fullscreen will need to show different content.
130 const GURL
& url
= web_contents
->GetURL();
131 if (!tab_fullscreen_accepted_
) {
132 tab_fullscreen_accepted_
=
133 GetFullscreenSetting(url
) == CONTENT_SETTING_ALLOW
;
135 UpdateFullscreenExitBubbleContent();
137 // This is only a change between Browser and Tab fullscreen. We generate
138 // a fullscreen notification now because there is no window change.
139 PostFullscreenChangeNotification(true);
142 if (in_browser_or_tab_fullscreen_mode
) {
143 if (IsFullscreenCausedByTab()) {
144 ToggleFullscreenModeInternal(TAB
);
146 #if defined(OS_MACOSX)
147 if (state_prior_to_tab_fullscreen_
==
148 STATE_BROWSER_FULLSCREEN_WITH_CHROME
) {
149 EnterFullscreenModeInternal(BROWSER_WITH_CHROME
);
151 // Clear the bubble URL, which forces the Mac UI to redraw.
152 UpdateFullscreenExitBubbleContent();
155 // If currently there is a tab in "tab fullscreen" mode and fullscreen
156 // was not caused by it (i.e., previously it was in "browser fullscreen"
157 // mode), we need to switch back to "browser fullscreen" mode. In this
158 // case, all we have to do is notifying the tab that it has exited "tab
160 NotifyTabOfExitIfNecessary();
162 // This is only a change between Browser and Tab fullscreen. We generate
163 // a fullscreen notification now because there is no window change.
164 PostFullscreenChangeNotification(true);
170 void FullscreenController::ToggleFullscreenModeWithExtension(
171 const GURL
& extension_url
) {
172 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to
174 extension_caused_fullscreen_
= extension_url
;
175 ToggleFullscreenModeInternal(BROWSER
);
178 bool FullscreenController::IsInMetroSnapMode() {
180 return window_
->IsInMetroSnapMode();
187 void FullscreenController::SetMetroSnapMode(bool enable
) {
188 reentrant_window_state_change_call_check_
= false;
190 toggled_into_fullscreen_
= false;
191 window_
->SetMetroSnapMode(enable
);
193 // FullscreenController unit tests for metro snap assume that on Windows calls
194 // to WindowFullscreenStateChanged are reentrant. If that assumption is
195 // invalidated, the tests must be updated to maintain coverage.
196 CHECK(reentrant_window_state_change_call_check_
);
198 #endif // defined(OS_WIN)
200 #if defined(OS_MACOSX)
201 void FullscreenController::ToggleFullscreenWithChrome() {
202 // This method cannot be called if simplified fullscreen is enabled.
203 const CommandLine
* command_line
= CommandLine::ForCurrentProcess();
204 DCHECK(!command_line
->HasSwitch(switches::kEnableSimplifiedFullscreen
));
205 ToggleFullscreenModeInternal(BROWSER_WITH_CHROME
);
209 bool FullscreenController::IsMouseLockRequested() const {
210 return mouse_lock_state_
== MOUSELOCK_REQUESTED
;
213 bool FullscreenController::IsMouseLocked() const {
214 return mouse_lock_state_
== MOUSELOCK_ACCEPTED
||
215 mouse_lock_state_
== MOUSELOCK_ACCEPTED_SILENTLY
;
218 void FullscreenController::RequestToLockMouse(WebContents
* web_contents
,
220 bool last_unlocked_by_target
) {
221 DCHECK(!IsMouseLocked());
222 NotifyMouseLockChange();
224 // Must have a user gesture to prevent misbehaving sites from constantly
225 // 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
228 if (!last_unlocked_by_target
&& !user_gesture
&&
229 !IsFullscreenForTabOrPending(web_contents
)) {
230 web_contents
->GotResponseToLockMouseRequest(false);
233 SetMouseLockTab(web_contents
);
234 FullscreenExitBubbleType bubble_type
= GetFullscreenExitBubbleType();
236 switch (GetMouseLockSetting(web_contents
->GetURL())) {
237 case CONTENT_SETTING_ALLOW
:
238 // If bubble already displaying buttons we must not lock the mouse yet,
239 // or it would prevent pressing those buttons. Instead, merge the request.
240 if (!IsPrivilegedFullscreenForTab() &&
241 fullscreen_bubble::ShowButtonsForType(bubble_type
)) {
242 mouse_lock_state_
= MOUSELOCK_REQUESTED
;
245 if (web_contents
->GotResponseToLockMouseRequest(true)) {
246 if (last_unlocked_by_target
) {
247 mouse_lock_state_
= MOUSELOCK_ACCEPTED_SILENTLY
;
249 mouse_lock_state_
= MOUSELOCK_ACCEPTED
;
252 SetMouseLockTab(NULL
);
253 mouse_lock_state_
= MOUSELOCK_NOT_REQUESTED
;
257 case CONTENT_SETTING_BLOCK
:
258 web_contents
->GotResponseToLockMouseRequest(false);
259 SetMouseLockTab(NULL
);
260 mouse_lock_state_
= MOUSELOCK_NOT_REQUESTED
;
262 case CONTENT_SETTING_ASK
:
263 mouse_lock_state_
= MOUSELOCK_REQUESTED
;
268 UpdateFullscreenExitBubbleContent();
271 void FullscreenController::OnTabDeactivated(WebContents
* web_contents
) {
272 if (web_contents
== fullscreened_tab_
|| web_contents
== mouse_lock_tab_
)
273 ExitTabFullscreenOrMouseLockIfNecessary();
276 void FullscreenController::OnTabClosing(WebContents
* web_contents
) {
277 if (web_contents
== fullscreened_tab_
|| web_contents
== mouse_lock_tab_
) {
278 ExitTabFullscreenOrMouseLockIfNecessary();
279 // 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
281 // to call NotifyTabOfExitIfNecessary(), because at that point
282 // |fullscreened_tab_| may not be valid. Instead, we call it here to clean
283 // up tab fullscreen related state.
284 NotifyTabOfExitIfNecessary();
288 void FullscreenController::WindowFullscreenStateChanged() {
289 reentrant_window_state_change_call_check_
= true;
291 bool exiting_fullscreen
= !window_
->IsFullscreen();
293 PostFullscreenChangeNotification(!exiting_fullscreen
);
294 if (exiting_fullscreen
) {
295 toggled_into_fullscreen_
= false;
296 extension_caused_fullscreen_
= GURL();
297 NotifyTabOfExitIfNecessary();
299 if (exiting_fullscreen
) {
300 window_
->GetDownloadShelf()->Unhide();
302 window_
->GetDownloadShelf()->Hide();
303 if (window_
->GetStatusBubble())
304 window_
->GetStatusBubble()->Hide();
308 bool FullscreenController::HandleUserPressedEscape() {
309 if (IsFullscreenForTabOrPending() ||
310 IsMouseLocked() || IsMouseLockRequested()) {
311 ExitTabFullscreenOrMouseLockIfNecessary();
318 void FullscreenController::ExitTabOrBrowserFullscreenToPreviousState() {
319 if (IsFullscreenForTabOrPending())
320 ExitTabFullscreenOrMouseLockIfNecessary();
321 else if (IsFullscreenForBrowser())
322 ExitFullscreenModeInternal();
325 void FullscreenController::OnAcceptFullscreenPermission() {
326 FullscreenExitBubbleType bubble_type
= GetFullscreenExitBubbleType();
327 bool mouse_lock
= false;
328 bool fullscreen
= false;
329 fullscreen_bubble::PermissionRequestedByType(bubble_type
, &fullscreen
,
331 DCHECK(!(fullscreen
&& tab_fullscreen_accepted_
));
332 DCHECK(!(mouse_lock
&& IsMouseLocked()));
334 HostContentSettingsMap
* settings_map
= profile_
->GetHostContentSettingsMap();
336 GURL url
= GetFullscreenExitBubbleURL();
337 ContentSettingsPattern pattern
= ContentSettingsPattern::FromURL(url
);
339 if (mouse_lock
&& !IsMouseLocked()) {
340 DCHECK(IsMouseLockRequested());
341 // TODO(markusheintz): We should allow patterns for all possible URLs here.
342 if (pattern
.IsValid()) {
343 settings_map
->SetContentSetting(
344 pattern
, ContentSettingsPattern::Wildcard(),
345 CONTENT_SETTINGS_TYPE_MOUSELOCK
, std::string(),
346 CONTENT_SETTING_ALLOW
);
349 if (mouse_lock_tab_
&&
350 mouse_lock_tab_
->GotResponseToLockMouseRequest(true)) {
351 mouse_lock_state_
= MOUSELOCK_ACCEPTED
;
353 mouse_lock_state_
= MOUSELOCK_NOT_REQUESTED
;
354 SetMouseLockTab(NULL
);
356 NotifyMouseLockChange();
359 if (fullscreen
&& !tab_fullscreen_accepted_
) {
360 DCHECK(fullscreened_tab_
);
361 if (pattern
.IsValid()) {
362 settings_map
->SetContentSetting(
363 pattern
, ContentSettingsPattern::Wildcard(),
364 CONTENT_SETTINGS_TYPE_FULLSCREEN
, std::string(),
365 CONTENT_SETTING_ALLOW
);
367 tab_fullscreen_accepted_
= true;
369 UpdateFullscreenExitBubbleContent();
372 void FullscreenController::OnDenyFullscreenPermission() {
373 if (!fullscreened_tab_
&& !mouse_lock_tab_
)
376 if (IsMouseLockRequested()) {
377 mouse_lock_state_
= MOUSELOCK_NOT_REQUESTED
;
379 mouse_lock_tab_
->GotResponseToLockMouseRequest(false);
380 SetMouseLockTab(NULL
);
381 NotifyMouseLockChange();
383 // UpdateFullscreenExitBubbleContent() must be called, but to avoid
384 // duplicate calls we do so only if not adjusting the fullscreen state
385 // below, which also calls UpdateFullscreenExitBubbleContent().
386 if (!IsFullscreenForTabOrPending())
387 UpdateFullscreenExitBubbleContent();
390 if (IsFullscreenForTabOrPending())
391 ExitTabFullscreenOrMouseLockIfNecessary();
394 void FullscreenController::LostMouseLock() {
395 mouse_lock_state_
= MOUSELOCK_NOT_REQUESTED
;
396 SetMouseLockTab(NULL
);
397 NotifyMouseLockChange();
398 UpdateFullscreenExitBubbleContent();
401 void FullscreenController::Observe(int type
,
402 const content::NotificationSource
& source
,
403 const content::NotificationDetails
& details
) {
405 case content::NOTIFICATION_NAV_ENTRY_COMMITTED
:
406 if (content::Details
<content::LoadCommittedDetails
>(details
)->
407 is_navigation_to_different_page()) {
408 ExitTabFullscreenOrMouseLockIfNecessary();
413 NOTREACHED() << "Got a notification we didn't register for.";
417 GURL
FullscreenController::GetFullscreenExitBubbleURL() const {
418 if (fullscreened_tab_
)
419 return fullscreened_tab_
->GetURL();
420 else if (mouse_lock_tab_
)
421 return mouse_lock_tab_
->GetURL();
422 else if (!extension_caused_fullscreen_
.is_empty())
423 return extension_caused_fullscreen_
;
428 FullscreenExitBubbleType
FullscreenController::GetFullscreenExitBubbleType()
430 // In kiosk and exclusive app mode we always want to be fullscreen and do not
431 // want to show exit instructions for browser mode fullscreen.
432 bool app_mode
= false;
433 #if !defined(OS_MACOSX) // App mode (kiosk) is not available on Mac yet.
434 app_mode
= chrome::IsRunningInAppMode();
437 if (mouse_lock_state_
== MOUSELOCK_ACCEPTED_SILENTLY
) {
438 return FEB_TYPE_NONE
;
441 if (fullscreened_tab_
) {
442 if (tab_fullscreen_accepted_
) {
443 if (IsPrivilegedFullscreenForTab()) {
444 return FEB_TYPE_NONE
;
445 } else if (IsMouseLocked()) {
446 return FEB_TYPE_FULLSCREEN_MOUSELOCK_EXIT_INSTRUCTION
;
447 } else if (IsMouseLockRequested()) {
448 return FEB_TYPE_MOUSELOCK_BUTTONS
;
450 return FEB_TYPE_FULLSCREEN_EXIT_INSTRUCTION
;
452 } else { // Full screen not yet accepted.
453 if (IsMouseLockRequested()) {
454 return FEB_TYPE_FULLSCREEN_MOUSELOCK_BUTTONS
;
456 return FEB_TYPE_FULLSCREEN_BUTTONS
;
459 } else { // Not tab full screen.
460 if (IsMouseLocked()) {
461 return FEB_TYPE_MOUSELOCK_EXIT_INSTRUCTION
;
462 } else if (IsMouseLockRequested()) {
463 return FEB_TYPE_MOUSELOCK_BUTTONS
;
465 if (!extension_caused_fullscreen_
.is_empty()) {
466 return FEB_TYPE_BROWSER_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION
;
467 } else if (toggled_into_fullscreen_
&& !app_mode
) {
468 return FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION
;
470 return FEB_TYPE_NONE
;
475 return FEB_TYPE_NONE
;
478 void FullscreenController::UpdateNotificationRegistrations() {
479 if (fullscreened_tab_
&& mouse_lock_tab_
)
480 DCHECK(fullscreened_tab_
== mouse_lock_tab_
);
482 WebContents
* tab
= fullscreened_tab_
? fullscreened_tab_
: mouse_lock_tab_
;
484 if (tab
&& registrar_
.IsEmpty()) {
485 registrar_
.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
486 content::Source
<content::NavigationController
>(&tab
->GetController()));
487 } else if (!tab
&& !registrar_
.IsEmpty()) {
488 registrar_
.RemoveAll();
492 void FullscreenController::PostFullscreenChangeNotification(
493 bool is_fullscreen
) {
494 base::MessageLoop::current()->PostTask(
496 base::Bind(&FullscreenController::NotifyFullscreenChange
,
497 ptr_factory_
.GetWeakPtr(),
501 void FullscreenController::NotifyFullscreenChange(bool is_fullscreen
) {
502 content::NotificationService::current()->Notify(
503 chrome::NOTIFICATION_FULLSCREEN_CHANGED
,
504 content::Source
<FullscreenController
>(this),
505 content::Details
<bool>(&is_fullscreen
));
508 void FullscreenController::NotifyTabOfExitIfNecessary() {
509 if (fullscreened_tab_
) {
510 RenderViewHost
* rvh
= fullscreened_tab_
->GetRenderViewHost();
511 SetFullscreenedTab(NULL
);
512 state_prior_to_tab_fullscreen_
= STATE_INVALID
;
513 tab_fullscreen_accepted_
= false;
515 rvh
->ExitFullscreen();
518 if (mouse_lock_tab_
) {
519 if (IsMouseLockRequested()) {
520 mouse_lock_tab_
->GotResponseToLockMouseRequest(false);
521 NotifyMouseLockChange();
525 SetMouseLockTab(NULL
);
526 mouse_lock_state_
= MOUSELOCK_NOT_REQUESTED
;
529 UpdateFullscreenExitBubbleContent();
532 void FullscreenController::NotifyMouseLockChange() {
533 content::NotificationService::current()->Notify(
534 chrome::NOTIFICATION_MOUSE_LOCK_CHANGED
,
535 content::Source
<FullscreenController
>(this),
536 content::NotificationService::NoDetails());
539 void FullscreenController::ToggleFullscreenModeInternal(
540 FullscreenInternalOption option
) {
542 // When in Metro snap mode, toggling in and out of fullscreen is prevented.
543 if (IsInMetroSnapMode())
547 bool enter_fullscreen
= !window_
->IsFullscreen();
548 #if defined(OS_MACOSX)
549 // When a Mac user requests a toggle they may be toggling between
550 // FullscreenWithoutChrome and FullscreenWithChrome.
551 if (!IsFullscreenForTabOrPending()) {
552 if (option
== BROWSER_WITH_CHROME
)
553 enter_fullscreen
|= window_
->IsFullscreenWithoutChrome();
555 enter_fullscreen
|= window_
->IsFullscreenWithChrome();
559 // In kiosk mode, we always want to be fullscreen. When the browser first
560 // starts we're not yet fullscreen, so let the initial toggle go through.
561 if (chrome::IsRunningInAppMode() && window_
->IsFullscreen())
564 #if !defined(OS_MACOSX)
565 // Do not enter fullscreen mode if disallowed by pref. This prevents the user
566 // from manually entering fullscreen mode and also disables kiosk mode on
567 // desktop platforms.
568 if (enter_fullscreen
&&
569 !profile_
->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed
)) {
574 if (enter_fullscreen
)
575 EnterFullscreenModeInternal(option
);
577 ExitFullscreenModeInternal();
580 void FullscreenController::EnterFullscreenModeInternal(
581 FullscreenInternalOption option
) {
582 toggled_into_fullscreen_
= true;
585 url
= browser_
->tab_strip_model()->GetActiveWebContents()->GetURL();
586 tab_fullscreen_accepted_
=
587 GetFullscreenSetting(url
) == CONTENT_SETTING_ALLOW
;
589 if (!extension_caused_fullscreen_
.is_empty())
590 url
= extension_caused_fullscreen_
;
593 if (option
== BROWSER
)
594 content::RecordAction(UserMetricsAction("ToggleFullscreen"));
595 // TODO(scheib): Record metrics for WITH_CHROME, without counting transitions
596 // from tab fullscreen out to browser with chrome.
598 #if defined(OS_MACOSX)
599 if (option
== BROWSER_WITH_CHROME
) {
600 CHECK(chrome::mac::SupportsSystemFullscreen());
601 window_
->EnterFullscreenWithChrome();
606 window_
->EnterFullscreen(url
, GetFullscreenExitBubbleType());
609 UpdateFullscreenExitBubbleContent();
611 // Once the window has become fullscreen it'll call back to
612 // WindowFullscreenStateChanged(). We don't do this immediately as
613 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let
614 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate.
617 void FullscreenController::ExitFullscreenModeInternal() {
618 toggled_into_fullscreen_
= false;
619 #if defined(OS_MACOSX)
620 // Mac windows report a state change instantly, and so we must also clear
621 // state_prior_to_tab_fullscreen_ to match them else other logic using
622 // state_prior_to_tab_fullscreen_ will be incorrect.
623 NotifyTabOfExitIfNecessary();
625 window_
->ExitFullscreen();
626 extension_caused_fullscreen_
= GURL();
628 UpdateFullscreenExitBubbleContent();
631 void FullscreenController::SetFullscreenedTab(WebContents
* tab
) {
632 fullscreened_tab_
= tab
;
633 UpdateNotificationRegistrations();
636 void FullscreenController::SetMouseLockTab(WebContents
* tab
) {
637 mouse_lock_tab_
= tab
;
638 UpdateNotificationRegistrations();
641 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() {
642 if (IsFullscreenForTabOrPending())
643 ToggleFullscreenModeForTab(fullscreened_tab_
, false);
645 NotifyTabOfExitIfNecessary();
648 void FullscreenController::UpdateFullscreenExitBubbleContent() {
649 GURL url
= GetFullscreenExitBubbleURL();
650 FullscreenExitBubbleType bubble_type
= GetFullscreenExitBubbleType();
652 // If bubble displays buttons, unlock mouse to allow pressing them.
653 if (fullscreen_bubble::ShowButtonsForType(bubble_type
) && IsMouseLocked())
656 window_
->UpdateFullscreenExitBubbleContent(url
, bubble_type
);
660 FullscreenController::GetFullscreenSetting(const GURL
& url
) const {
661 if (IsPrivilegedFullscreenForTab() || url
.SchemeIsFile())
662 return CONTENT_SETTING_ALLOW
;
664 return profile_
->GetHostContentSettingsMap()->GetContentSetting(url
, url
,
665 CONTENT_SETTINGS_TYPE_FULLSCREEN
, std::string());
669 FullscreenController::GetMouseLockSetting(const GURL
& url
) const {
670 if (IsPrivilegedFullscreenForTab() || url
.SchemeIsFile())
671 return CONTENT_SETTING_ALLOW
;
673 HostContentSettingsMap
* settings_map
= profile_
->GetHostContentSettingsMap();
674 return settings_map
->GetContentSetting(url
, url
,
675 CONTENT_SETTINGS_TYPE_MOUSELOCK
, std::string());
678 bool FullscreenController::IsPrivilegedFullscreenForTab() const {
679 const bool embedded_widget_present
=
681 fullscreened_tab_
->GetFullscreenRenderWidgetHostView() &&
682 implicit_cast
<const content::WebContentsDelegate
*>(browser_
)->
683 EmbedsFullscreenWidget();
684 return embedded_widget_present
|| is_privileged_fullscreen_for_testing_
;
687 void FullscreenController::SetPrivilegedFullscreenForTesting(
688 bool is_privileged
) {
689 is_privileged_fullscreen_for_testing_
= is_privileged
;
692 void FullscreenController::UnlockMouse() {
693 if (!mouse_lock_tab_
)
695 content::RenderWidgetHostView
* mouse_lock_view
=
696 (fullscreened_tab_
== mouse_lock_tab_
&& IsPrivilegedFullscreenForTab()) ?
697 mouse_lock_tab_
->GetFullscreenRenderWidgetHostView() : NULL
;
698 if (!mouse_lock_view
) {
699 RenderViewHost
* const rvh
= mouse_lock_tab_
->GetRenderViewHost();
701 mouse_lock_view
= rvh
->GetView();
704 mouse_lock_view
->UnlockMouse();