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 11 matching lines...) Expand all Loading... |
22 #include "content/public/browser/notification_service.h" | 22 #include "content/public/browser/notification_service.h" |
23 #include "content/public/browser/render_view_host.h" | 23 #include "content/public/browser/render_view_host.h" |
24 #include "content/public/browser/render_widget_host_view.h" | 24 #include "content/public/browser/render_widget_host_view.h" |
25 #include "content/public/browser/user_metrics.h" | 25 #include "content/public/browser/user_metrics.h" |
26 #include "content/public/browser/web_contents.h" | 26 #include "content/public/browser/web_contents.h" |
27 | 27 |
28 using content::RenderViewHost; | 28 using content::RenderViewHost; |
29 using content::UserMetricsAction; | 29 using content::UserMetricsAction; |
30 using content::WebContents; | 30 using content::WebContents; |
31 | 31 |
32 FullscreenController::FullscreenController(BrowserWindow* window, | 32 FullscreenController::FullscreenController(Browser* browser) |
33 Profile* profile, | 33 : ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
34 Browser* browser) | 34 browser_(browser), |
35 : window_(window), | 35 window_(browser->window()), |
36 profile_(profile), | 36 profile_(browser->profile()), |
37 browser_(browser), | 37 fullscreened_tab_(NULL), |
38 fullscreened_tab_(NULL), | 38 tab_caused_fullscreen_(false), |
39 tab_caused_fullscreen_(false), | 39 tab_fullscreen_accepted_(false), |
40 tab_fullscreen_accepted_(false), | 40 toggled_into_fullscreen_(false), |
41 toggled_into_fullscreen_(false), | 41 mouse_lock_tab_(NULL), |
42 mouse_lock_tab_(NULL), | 42 mouse_lock_state_(MOUSELOCK_NOT_REQUESTED) { |
43 mouse_lock_state_(MOUSELOCK_NOT_REQUESTED) { | 43 DCHECK(window_); |
| 44 DCHECK(profile_); |
44 } | 45 } |
45 | 46 |
46 void FullscreenController::Observe(int type, | 47 FullscreenController::~FullscreenController() { |
47 const content::NotificationSource& source, | |
48 const content::NotificationDetails& details) { | |
49 switch (type) { | |
50 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: | |
51 if (content::Details<content::LoadCommittedDetails>(details)-> | |
52 is_navigation_to_different_page()) { | |
53 ExitTabFullscreenOrMouseLockIfNecessary(); | |
54 } | |
55 break; | |
56 | |
57 default: | |
58 NOTREACHED() << "Got a notification we didn't register for."; | |
59 } | |
60 } | 48 } |
61 | 49 |
62 bool FullscreenController::IsFullscreenForBrowser() const { | 50 bool FullscreenController::IsFullscreenForBrowser() const { |
63 return window_->IsFullscreen() && !tab_caused_fullscreen_; | 51 return window_->IsFullscreen() && !tab_caused_fullscreen_; |
64 } | 52 } |
65 | 53 |
| 54 void FullscreenController::ToggleFullscreenMode() { |
| 55 extension_caused_fullscreen_ = GURL(); |
| 56 ToggleFullscreenModeInternal(false); |
| 57 } |
| 58 |
66 bool FullscreenController::IsFullscreenForTabOrPending() const { | 59 bool FullscreenController::IsFullscreenForTabOrPending() const { |
67 return fullscreened_tab_ != NULL; | 60 return fullscreened_tab_ != NULL; |
68 } | 61 } |
69 | 62 |
70 bool FullscreenController::IsFullscreenForTabOrPending( | 63 bool FullscreenController::IsFullscreenForTabOrPending( |
71 const WebContents* web_contents) const { | 64 const WebContents* web_contents) const { |
72 const TabContents* tab_contents = | 65 const TabContents* tab_contents = |
73 TabContents::FromWebContents(web_contents); | 66 TabContents::FromWebContents(web_contents); |
74 if (!tab_contents || (tab_contents != fullscreened_tab_)) | 67 if (!tab_contents || (tab_contents != fullscreened_tab_)) |
75 return false; | 68 return false; |
76 DCHECK(web_contents == chrome::GetActiveWebContents(browser_)); | 69 DCHECK(web_contents == chrome::GetActiveWebContents(browser_)); |
77 return true; | 70 return true; |
78 } | 71 } |
79 | 72 |
80 #if defined(OS_WIN) | |
81 bool FullscreenController::IsInMetroSnapMode() { | |
82 return window_->IsInMetroSnapMode(); | |
83 } | |
84 #endif | |
85 | |
86 bool FullscreenController::IsMouseLockRequested() const { | |
87 return mouse_lock_state_ == MOUSELOCK_REQUESTED; | |
88 } | |
89 | |
90 bool FullscreenController::IsMouseLocked() const { | |
91 return mouse_lock_state_ == MOUSELOCK_ACCEPTED || | |
92 mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY; | |
93 } | |
94 | |
95 void FullscreenController::RequestToLockMouse(WebContents* web_contents, | |
96 bool user_gesture, | |
97 bool last_unlocked_by_target) { | |
98 DCHECK(!IsMouseLocked()); | |
99 NotifyMouseLockChange(); | |
100 | |
101 // Check for command line switch disabling mouse lock when not tab fullscreen. | |
102 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
103 switches::kDisableNonFullscreenMouseLock) && | |
104 !IsFullscreenForTabOrPending(web_contents)) { | |
105 web_contents->GotResponseToLockMouseRequest(false); | |
106 return; | |
107 } | |
108 | |
109 // Must have a user gesture to prevent misbehaving sites from constantly | |
110 // re-locking the mouse. Exceptions are when the page has unlocked | |
111 // (i.e. not the user), or if we're in tab fullscreen (user gesture required | |
112 // for that) | |
113 if (!last_unlocked_by_target && !user_gesture && | |
114 !IsFullscreenForTabOrPending(web_contents)) { | |
115 web_contents->GotResponseToLockMouseRequest(false); | |
116 return; | |
117 } | |
118 SetMouseLockTab(TabContents::FromWebContents(web_contents)); | |
119 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); | |
120 | |
121 switch (GetMouseLockSetting(web_contents->GetURL())) { | |
122 case CONTENT_SETTING_ALLOW: | |
123 // If bubble already displaying buttons we must not lock the mouse yet, | |
124 // or it would prevent pressing those buttons. Instead, merge the request. | |
125 if (fullscreen_bubble::ShowButtonsForType(bubble_type)) { | |
126 mouse_lock_state_ = MOUSELOCK_REQUESTED; | |
127 } else { | |
128 // Lock mouse. | |
129 if (web_contents->GotResponseToLockMouseRequest(true)) { | |
130 if (last_unlocked_by_target) { | |
131 mouse_lock_state_ = MOUSELOCK_ACCEPTED_SILENTLY; | |
132 } else { | |
133 mouse_lock_state_ = MOUSELOCK_ACCEPTED; | |
134 } | |
135 } else { | |
136 SetMouseLockTab(NULL); | |
137 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; | |
138 } | |
139 } | |
140 break; | |
141 case CONTENT_SETTING_BLOCK: | |
142 web_contents->GotResponseToLockMouseRequest(false); | |
143 SetMouseLockTab(NULL); | |
144 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; | |
145 break; | |
146 case CONTENT_SETTING_ASK: | |
147 mouse_lock_state_ = MOUSELOCK_REQUESTED; | |
148 break; | |
149 default: | |
150 NOTREACHED(); | |
151 } | |
152 UpdateFullscreenExitBubbleContent(); | |
153 } | |
154 | |
155 void FullscreenController::ToggleFullscreenModeForTab(WebContents* web_contents, | 73 void FullscreenController::ToggleFullscreenModeForTab(WebContents* web_contents, |
156 bool enter_fullscreen) { | 74 bool enter_fullscreen) { |
157 if (web_contents != chrome::GetActiveWebContents(browser_)) | 75 if (web_contents != chrome::GetActiveWebContents(browser_)) |
158 return; | 76 return; |
159 | 77 |
160 #if defined(OS_WIN) | 78 #if defined(OS_WIN) |
161 // For now, avoid breaking when initiating full screen tab mode while in | 79 // For now, avoid breaking when initiating full screen tab mode while in |
162 // a metro snap. | 80 // a metro snap. |
163 // TODO(robertshield): Find a way to reconcile tab-initiated fullscreen | 81 // TODO(robertshield): Find a way to reconcile tab-initiated fullscreen |
164 // modes with metro snap. | 82 // modes with metro snap. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 // was not caused by it (i.e., previously it was in "browser fullscreen" | 123 // was not caused by it (i.e., previously it was in "browser fullscreen" |
206 // mode), we need to switch back to "browser fullscreen" mode. In this | 124 // mode), we need to switch back to "browser fullscreen" mode. In this |
207 // case, all we have to do is notifying the tab that it has exited "tab | 125 // case, all we have to do is notifying the tab that it has exited "tab |
208 // fullscreen" mode. | 126 // fullscreen" mode. |
209 NotifyTabOfExitIfNecessary(); | 127 NotifyTabOfExitIfNecessary(); |
210 } | 128 } |
211 } | 129 } |
212 } | 130 } |
213 } | 131 } |
214 | 132 |
| 133 void FullscreenController::ToggleFullscreenModeWithExtension( |
| 134 const GURL& extension_url) { |
| 135 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to |
| 136 // exit. |
| 137 extension_caused_fullscreen_ = extension_url; |
| 138 ToggleFullscreenModeInternal(false); |
| 139 } |
| 140 |
215 #if defined(OS_WIN) | 141 #if defined(OS_WIN) |
| 142 bool FullscreenController::IsInMetroSnapMode() { |
| 143 return window_->IsInMetroSnapMode(); |
| 144 } |
| 145 |
216 void FullscreenController::SetMetroSnapMode(bool enable) { | 146 void FullscreenController::SetMetroSnapMode(bool enable) { |
217 toggled_into_fullscreen_ = false; | 147 toggled_into_fullscreen_ = false; |
218 window_->SetMetroSnapMode(enable); | 148 window_->SetMetroSnapMode(enable); |
219 } | 149 } |
220 #endif | 150 #endif // defined(OS_WIN) |
221 | 151 |
222 #if defined(OS_MACOSX) | 152 #if defined(OS_MACOSX) |
223 void FullscreenController::TogglePresentationMode() { | 153 void FullscreenController::TogglePresentationMode() { |
224 TogglePresentationModeInternal(false); | 154 TogglePresentationModeInternal(false); |
225 } | 155 } |
226 #endif | 156 #endif |
227 | 157 |
228 void FullscreenController::ToggleFullscreenMode() { | 158 bool FullscreenController::IsMouseLockRequested() const { |
229 extension_caused_fullscreen_ = GURL(); | 159 return mouse_lock_state_ == MOUSELOCK_REQUESTED; |
230 ToggleFullscreenModeInternal(false); | |
231 } | 160 } |
232 | 161 |
233 void FullscreenController::ToggleFullscreenModeWithExtension( | 162 bool FullscreenController::IsMouseLocked() const { |
234 const GURL& extension_url) { | 163 return mouse_lock_state_ == MOUSELOCK_ACCEPTED || |
235 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to | 164 mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY; |
236 // exit. | |
237 extension_caused_fullscreen_ = extension_url; | |
238 ToggleFullscreenModeInternal(false); | |
239 } | 165 } |
240 | 166 |
241 void FullscreenController::LostMouseLock() { | 167 void FullscreenController::RequestToLockMouse(WebContents* web_contents, |
242 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; | 168 bool user_gesture, |
243 SetMouseLockTab(NULL); | 169 bool last_unlocked_by_target) { |
| 170 DCHECK(!IsMouseLocked()); |
244 NotifyMouseLockChange(); | 171 NotifyMouseLockChange(); |
| 172 |
| 173 // Check for command line switch disabling mouse lock when not tab fullscreen. |
| 174 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 175 switches::kDisableNonFullscreenMouseLock) && |
| 176 !IsFullscreenForTabOrPending(web_contents)) { |
| 177 web_contents->GotResponseToLockMouseRequest(false); |
| 178 return; |
| 179 } |
| 180 |
| 181 // Must have a user gesture to prevent misbehaving sites from constantly |
| 182 // re-locking the mouse. Exceptions are when the page has unlocked |
| 183 // (i.e. not the user), or if we're in tab fullscreen (user gesture required |
| 184 // for that) |
| 185 if (!last_unlocked_by_target && !user_gesture && |
| 186 !IsFullscreenForTabOrPending(web_contents)) { |
| 187 web_contents->GotResponseToLockMouseRequest(false); |
| 188 return; |
| 189 } |
| 190 SetMouseLockTab(TabContents::FromWebContents(web_contents)); |
| 191 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); |
| 192 |
| 193 switch (GetMouseLockSetting(web_contents->GetURL())) { |
| 194 case CONTENT_SETTING_ALLOW: |
| 195 // If bubble already displaying buttons we must not lock the mouse yet, |
| 196 // or it would prevent pressing those buttons. Instead, merge the request. |
| 197 if (fullscreen_bubble::ShowButtonsForType(bubble_type)) { |
| 198 mouse_lock_state_ = MOUSELOCK_REQUESTED; |
| 199 } else { |
| 200 // Lock mouse. |
| 201 if (web_contents->GotResponseToLockMouseRequest(true)) { |
| 202 if (last_unlocked_by_target) { |
| 203 mouse_lock_state_ = MOUSELOCK_ACCEPTED_SILENTLY; |
| 204 } else { |
| 205 mouse_lock_state_ = MOUSELOCK_ACCEPTED; |
| 206 } |
| 207 } else { |
| 208 SetMouseLockTab(NULL); |
| 209 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
| 210 } |
| 211 } |
| 212 break; |
| 213 case CONTENT_SETTING_BLOCK: |
| 214 web_contents->GotResponseToLockMouseRequest(false); |
| 215 SetMouseLockTab(NULL); |
| 216 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
| 217 break; |
| 218 case CONTENT_SETTING_ASK: |
| 219 mouse_lock_state_ = MOUSELOCK_REQUESTED; |
| 220 break; |
| 221 default: |
| 222 NOTREACHED(); |
| 223 } |
245 UpdateFullscreenExitBubbleContent(); | 224 UpdateFullscreenExitBubbleContent(); |
246 } | 225 } |
247 | 226 |
| 227 void FullscreenController::OnTabDeactivated(TabContents* contents) { |
| 228 if (contents && |
| 229 (contents == fullscreened_tab_ || contents == mouse_lock_tab_)) { |
| 230 ExitTabFullscreenOrMouseLockIfNecessary(); |
| 231 } |
| 232 } |
| 233 |
248 void FullscreenController::OnTabClosing(WebContents* web_contents) { | 234 void FullscreenController::OnTabClosing(WebContents* web_contents) { |
249 const TabContents* contents = TabContents::FromWebContents(web_contents); | 235 const TabContents* contents = TabContents::FromWebContents(web_contents); |
250 if (contents && | 236 if (contents && |
251 (contents == fullscreened_tab_ || contents == mouse_lock_tab_)) { | 237 (contents == fullscreened_tab_ || contents == mouse_lock_tab_)) { |
252 ExitTabFullscreenOrMouseLockIfNecessary(); | 238 ExitTabFullscreenOrMouseLockIfNecessary(); |
253 // The call to exit fullscreen may result in asynchronous notification of | 239 // The call to exit fullscreen may result in asynchronous notification of |
254 // fullscreen state change (e.g., on Linux). We don't want to rely on it | 240 // fullscreen state change (e.g., on Linux). We don't want to rely on it |
255 // to call NotifyTabOfExitIfNecessary(), because at that point | 241 // to call NotifyTabOfExitIfNecessary(), because at that point |
256 // |fullscreened_tab_| may not be valid. Instead, we call it here to clean | 242 // |fullscreened_tab_| may not be valid. Instead, we call it here to clean |
257 // up tab fullscreen related state. | 243 // up tab fullscreen related state. |
258 NotifyTabOfExitIfNecessary(); | 244 NotifyTabOfExitIfNecessary(); |
259 } | 245 } |
260 } | 246 } |
261 | 247 |
262 void FullscreenController::OnTabDeactivated(TabContents* contents) { | 248 void FullscreenController::WindowFullscreenStateChanged() { |
263 if (contents && | 249 bool exiting_fullscreen; |
264 (contents == fullscreened_tab_ || contents == mouse_lock_tab_)) | 250 #if defined(OS_MACOSX) |
| 251 exiting_fullscreen = !window_->InPresentationMode(); |
| 252 #else |
| 253 exiting_fullscreen = !window_->IsFullscreen(); |
| 254 #endif |
| 255 MessageLoop::current()->PostTask(FROM_HERE, |
| 256 base::Bind(&FullscreenController::NotifyFullscreenChange, |
| 257 ptr_factory_.GetWeakPtr(), !exiting_fullscreen)); |
| 258 if (exiting_fullscreen) |
| 259 NotifyTabOfExitIfNecessary(); |
| 260 if (exiting_fullscreen) |
| 261 window_->GetDownloadShelf()->Unhide(); |
| 262 else |
| 263 window_->GetDownloadShelf()->Hide(); |
| 264 } |
| 265 |
| 266 bool FullscreenController::HandleUserPressedEscape() { |
| 267 if (IsFullscreenForTabOrPending() || |
| 268 IsMouseLocked() || IsMouseLockRequested()) { |
265 ExitTabFullscreenOrMouseLockIfNecessary(); | 269 ExitTabFullscreenOrMouseLockIfNecessary(); |
| 270 return true; |
| 271 } |
| 272 |
| 273 return false; |
266 } | 274 } |
267 | 275 |
268 void FullscreenController::OnAcceptFullscreenPermission( | 276 void FullscreenController::OnAcceptFullscreenPermission( |
269 const GURL& url, | 277 const GURL& url, |
270 FullscreenExitBubbleType bubble_type) { | 278 FullscreenExitBubbleType bubble_type) { |
271 bool mouse_lock = false; | 279 bool mouse_lock = false; |
272 bool fullscreen = false; | 280 bool fullscreen = false; |
273 fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen, | 281 fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen, |
274 &mouse_lock); | 282 &mouse_lock); |
275 DCHECK(!(fullscreen && tab_fullscreen_accepted_)); | 283 DCHECK(!(fullscreen && tab_fullscreen_accepted_)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 // duplicate calls we do so only if not adjusting the fullscreen state | 342 // duplicate calls we do so only if not adjusting the fullscreen state |
335 // below, which also calls UpdateFullscreenExitBubbleContent(). | 343 // below, which also calls UpdateFullscreenExitBubbleContent(). |
336 if (!fullscreen) | 344 if (!fullscreen) |
337 UpdateFullscreenExitBubbleContent(); | 345 UpdateFullscreenExitBubbleContent(); |
338 } | 346 } |
339 | 347 |
340 if (fullscreen) | 348 if (fullscreen) |
341 ExitTabFullscreenOrMouseLockIfNecessary(); | 349 ExitTabFullscreenOrMouseLockIfNecessary(); |
342 } | 350 } |
343 | 351 |
344 void FullscreenController::WindowFullscreenStateChanged() { | 352 void FullscreenController::LostMouseLock() { |
345 bool exiting_fullscreen; | 353 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
346 #if defined(OS_MACOSX) | 354 SetMouseLockTab(NULL); |
347 exiting_fullscreen = !window_->InPresentationMode(); | 355 NotifyMouseLockChange(); |
348 #else | |
349 exiting_fullscreen = !window_->IsFullscreen(); | |
350 #endif | |
351 MessageLoop::current()->PostTask(FROM_HERE, | |
352 base::Bind(&FullscreenController::NotifyFullscreenChange, | |
353 this, !exiting_fullscreen)); | |
354 if (exiting_fullscreen) | |
355 NotifyTabOfExitIfNecessary(); | |
356 if (exiting_fullscreen) | |
357 window_->GetDownloadShelf()->Unhide(); | |
358 else | |
359 window_->GetDownloadShelf()->Hide(); | |
360 } | |
361 | |
362 bool FullscreenController::HandleUserPressedEscape() { | |
363 if (IsFullscreenForTabOrPending() || | |
364 IsMouseLocked() || IsMouseLockRequested()) { | |
365 ExitTabFullscreenOrMouseLockIfNecessary(); | |
366 return true; | |
367 } | |
368 | |
369 return false; | |
370 } | |
371 | |
372 FullscreenController::~FullscreenController() {} | |
373 | |
374 void FullscreenController::NotifyTabOfExitIfNecessary() { | |
375 if (fullscreened_tab_) { | |
376 RenderViewHost* rvh = | |
377 fullscreened_tab_->web_contents()->GetRenderViewHost(); | |
378 SetFullscreenedTab(NULL); | |
379 tab_caused_fullscreen_ = false; | |
380 tab_fullscreen_accepted_ = false; | |
381 if (rvh) | |
382 rvh->ExitFullscreen(); | |
383 } | |
384 | |
385 if (mouse_lock_tab_) { | |
386 WebContents* web_contents = mouse_lock_tab_->web_contents(); | |
387 if (IsMouseLockRequested()) { | |
388 web_contents->GotResponseToLockMouseRequest(false); | |
389 NotifyMouseLockChange(); | |
390 } else if (web_contents->GetRenderViewHost() && | |
391 web_contents->GetRenderViewHost()->GetView()) { | |
392 web_contents->GetRenderViewHost()->GetView()->UnlockMouse(); | |
393 } | |
394 SetMouseLockTab(NULL); | |
395 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; | |
396 } | |
397 | |
398 UpdateFullscreenExitBubbleContent(); | 356 UpdateFullscreenExitBubbleContent(); |
399 } | 357 } |
400 | 358 |
401 void FullscreenController::UpdateNotificationRegistrations() { | 359 void FullscreenController::Observe(int type, |
402 if (fullscreened_tab_ && mouse_lock_tab_) | 360 const content::NotificationSource& source, |
403 DCHECK(fullscreened_tab_ == mouse_lock_tab_); | 361 const content::NotificationDetails& details) { |
| 362 switch (type) { |
| 363 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: |
| 364 if (content::Details<content::LoadCommittedDetails>(details)-> |
| 365 is_navigation_to_different_page()) { |
| 366 ExitTabFullscreenOrMouseLockIfNecessary(); |
| 367 } |
| 368 break; |
404 | 369 |
405 TabContents* tab = fullscreened_tab_ ? fullscreened_tab_ : mouse_lock_tab_; | 370 default: |
406 | 371 NOTREACHED() << "Got a notification we didn't register for."; |
407 if (tab && registrar_.IsEmpty()) { | |
408 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | |
409 content::Source<content::NavigationController>( | |
410 &tab->web_contents()->GetController())); | |
411 } else if (!tab && !registrar_.IsEmpty()) { | |
412 registrar_.RemoveAll(); | |
413 } | 372 } |
414 } | 373 } |
415 | 374 |
416 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() { | |
417 if (tab_caused_fullscreen_) | |
418 ToggleFullscreenMode(); | |
419 else | |
420 NotifyTabOfExitIfNecessary(); | |
421 } | |
422 | |
423 void FullscreenController::UpdateFullscreenExitBubbleContent() { | |
424 GURL url; | |
425 if (fullscreened_tab_) | |
426 url = fullscreened_tab_->web_contents()->GetURL(); | |
427 else if (mouse_lock_tab_) | |
428 url = mouse_lock_tab_->web_contents()->GetURL(); | |
429 else if (!extension_caused_fullscreen_.is_empty()) | |
430 url = extension_caused_fullscreen_; | |
431 | |
432 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); | |
433 | |
434 // If bubble displays buttons, unlock mouse to allow pressing them. | |
435 if (fullscreen_bubble::ShowButtonsForType(bubble_type) && | |
436 IsMouseLocked() && | |
437 mouse_lock_tab_->web_contents()) { | |
438 WebContents* web_contents = mouse_lock_tab_->web_contents(); | |
439 if (web_contents && web_contents->GetRenderViewHost() && | |
440 web_contents->GetRenderViewHost()->GetView()) | |
441 web_contents->GetRenderViewHost()->GetView()->UnlockMouse(); | |
442 } | |
443 | |
444 window_->UpdateFullscreenExitBubbleContent(url, bubble_type); | |
445 } | |
446 | |
447 void FullscreenController::NotifyFullscreenChange(bool is_fullscreen) { | |
448 content::NotificationService::current()->Notify( | |
449 chrome::NOTIFICATION_FULLSCREEN_CHANGED, | |
450 content::Source<FullscreenController>(this), | |
451 content::Details<bool>(&is_fullscreen)); | |
452 } | |
453 | |
454 void FullscreenController::NotifyMouseLockChange() { | |
455 content::NotificationService::current()->Notify( | |
456 chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, | |
457 content::Source<FullscreenController>(this), | |
458 content::NotificationService::NoDetails()); | |
459 } | |
460 | |
461 FullscreenExitBubbleType FullscreenController::GetFullscreenExitBubbleType() | 375 FullscreenExitBubbleType FullscreenController::GetFullscreenExitBubbleType() |
462 const { | 376 const { |
463 // In kiosk mode we always want to be fullscreen and do not want to show | 377 // In kiosk mode we always want to be fullscreen and do not want to show |
464 // exit instructions for browser mode fullscreen. | 378 // exit instructions for browser mode fullscreen. |
465 bool kiosk = false; | 379 bool kiosk = false; |
466 #if !defined(OS_MACOSX) // Kiosk mode not available on Mac. | 380 #if !defined(OS_MACOSX) // Kiosk mode not available on Mac. |
467 kiosk = CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode); | 381 kiosk = CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode); |
468 #endif | 382 #endif |
469 | 383 |
470 if (mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY) { | 384 if (mouse_lock_state_ == MOUSELOCK_ACCEPTED_SILENTLY) { |
(...skipping 28 matching lines...) Expand all Loading... |
499 return FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION; | 413 return FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION; |
500 } else { | 414 } else { |
501 return FEB_TYPE_NONE; | 415 return FEB_TYPE_NONE; |
502 } | 416 } |
503 } | 417 } |
504 } | 418 } |
505 NOTREACHED(); | 419 NOTREACHED(); |
506 return FEB_TYPE_NONE; | 420 return FEB_TYPE_NONE; |
507 } | 421 } |
508 | 422 |
509 ContentSetting | 423 void FullscreenController::UpdateNotificationRegistrations() { |
510 FullscreenController::GetFullscreenSetting(const GURL& url) const { | 424 if (fullscreened_tab_ && mouse_lock_tab_) |
511 if (url.SchemeIsFile()) | 425 DCHECK(fullscreened_tab_ == mouse_lock_tab_); |
512 return CONTENT_SETTING_ALLOW; | |
513 | 426 |
514 return profile_->GetHostContentSettingsMap()->GetContentSetting(url, url, | 427 TabContents* tab = fullscreened_tab_ ? fullscreened_tab_ : mouse_lock_tab_; |
515 CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string()); | 428 |
| 429 if (tab && registrar_.IsEmpty()) { |
| 430 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| 431 content::Source<content::NavigationController>( |
| 432 &tab->web_contents()->GetController())); |
| 433 } else if (!tab && !registrar_.IsEmpty()) { |
| 434 registrar_.RemoveAll(); |
| 435 } |
516 } | 436 } |
517 | 437 |
518 ContentSetting | 438 void FullscreenController::NotifyFullscreenChange(bool is_fullscreen) { |
519 FullscreenController::GetMouseLockSetting(const GURL& url) const { | 439 content::NotificationService::current()->Notify( |
520 if (url.SchemeIsFile()) | 440 chrome::NOTIFICATION_FULLSCREEN_CHANGED, |
521 return CONTENT_SETTING_ALLOW; | 441 content::Source<FullscreenController>(this), |
522 | 442 content::Details<bool>(&is_fullscreen)); |
523 HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap(); | |
524 return settings_map->GetContentSetting(url, url, | |
525 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string()); | |
526 } | 443 } |
527 | 444 |
528 #if defined(OS_MACOSX) | 445 void FullscreenController::NotifyTabOfExitIfNecessary() { |
529 void FullscreenController::TogglePresentationModeInternal(bool for_tab) { | 446 if (fullscreened_tab_) { |
530 toggled_into_fullscreen_ = !window_->InPresentationMode(); | 447 RenderViewHost* rvh = |
531 GURL url; | 448 fullscreened_tab_->web_contents()->GetRenderViewHost(); |
532 if (for_tab) { | 449 SetFullscreenedTab(NULL); |
533 url = chrome::GetActiveWebContents(browser_)->GetURL(); | 450 tab_caused_fullscreen_ = false; |
534 tab_fullscreen_accepted_ = toggled_into_fullscreen_ && | 451 tab_fullscreen_accepted_ = false; |
535 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; | 452 if (rvh) |
| 453 rvh->ExitFullscreen(); |
536 } | 454 } |
537 if (toggled_into_fullscreen_) | 455 |
538 window_->EnterPresentationMode(url, GetFullscreenExitBubbleType()); | 456 if (mouse_lock_tab_) { |
539 else | 457 WebContents* web_contents = mouse_lock_tab_->web_contents(); |
540 window_->ExitPresentationMode(); | 458 if (IsMouseLockRequested()) { |
| 459 web_contents->GotResponseToLockMouseRequest(false); |
| 460 NotifyMouseLockChange(); |
| 461 } else if (web_contents->GetRenderViewHost() && |
| 462 web_contents->GetRenderViewHost()->GetView()) { |
| 463 web_contents->GetRenderViewHost()->GetView()->UnlockMouse(); |
| 464 } |
| 465 SetMouseLockTab(NULL); |
| 466 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
| 467 } |
| 468 |
541 UpdateFullscreenExitBubbleContent(); | 469 UpdateFullscreenExitBubbleContent(); |
| 470 } |
542 | 471 |
543 // WindowFullscreenStateChanged will be called by BrowserWindowController | 472 void FullscreenController::NotifyMouseLockChange() { |
544 // when the transition completes. | 473 content::NotificationService::current()->Notify( |
| 474 chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, |
| 475 content::Source<FullscreenController>(this), |
| 476 content::NotificationService::NoDetails()); |
545 } | 477 } |
546 #endif | |
547 | 478 |
548 // TODO(koz): Change |for_tab| to an enum. | 479 // TODO(koz): Change |for_tab| to an enum. |
549 void FullscreenController::ToggleFullscreenModeInternal(bool for_tab) { | 480 void FullscreenController::ToggleFullscreenModeInternal(bool for_tab) { |
550 #if defined(OS_WIN) | 481 #if defined(OS_WIN) |
551 // When in Metro snap mode, toggling in and out of fullscreen is prevented. | 482 // When in Metro snap mode, toggling in and out of fullscreen is prevented. |
552 if (IsInMetroSnapMode()) | 483 if (IsInMetroSnapMode()) |
553 return; | 484 return; |
554 #endif | 485 #endif |
555 | 486 |
556 toggled_into_fullscreen_ = !window_->IsFullscreen(); | 487 toggled_into_fullscreen_ = !window_->IsFullscreen(); |
(...skipping 21 matching lines...) Expand all Loading... |
578 extension_caused_fullscreen_ = GURL(); | 509 extension_caused_fullscreen_ = GURL(); |
579 } | 510 } |
580 UpdateFullscreenExitBubbleContent(); | 511 UpdateFullscreenExitBubbleContent(); |
581 | 512 |
582 // Once the window has become fullscreen it'll call back to | 513 // Once the window has become fullscreen it'll call back to |
583 // WindowFullscreenStateChanged(). We don't do this immediately as | 514 // WindowFullscreenStateChanged(). We don't do this immediately as |
584 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let | 515 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let |
585 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate. | 516 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate. |
586 } | 517 } |
587 | 518 |
| 519 #if defined(OS_MACOSX) |
| 520 void FullscreenController::TogglePresentationModeInternal(bool for_tab) { |
| 521 toggled_into_fullscreen_ = !window_->InPresentationMode(); |
| 522 GURL url; |
| 523 if (for_tab) { |
| 524 url = chrome::GetActiveWebContents(browser_)->GetURL(); |
| 525 tab_fullscreen_accepted_ = toggled_into_fullscreen_ && |
| 526 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; |
| 527 } |
| 528 if (toggled_into_fullscreen_) |
| 529 window_->EnterPresentationMode(url, GetFullscreenExitBubbleType()); |
| 530 else |
| 531 window_->ExitPresentationMode(); |
| 532 UpdateFullscreenExitBubbleContent(); |
| 533 |
| 534 // WindowFullscreenStateChanged will be called by BrowserWindowController |
| 535 // when the transition completes. |
| 536 } |
| 537 #endif |
| 538 |
588 void FullscreenController::SetFullscreenedTab(TabContents* tab) { | 539 void FullscreenController::SetFullscreenedTab(TabContents* tab) { |
589 fullscreened_tab_ = tab; | 540 fullscreened_tab_ = tab; |
590 UpdateNotificationRegistrations(); | 541 UpdateNotificationRegistrations(); |
591 } | 542 } |
592 | 543 |
593 void FullscreenController::SetMouseLockTab(TabContents* tab) { | 544 void FullscreenController::SetMouseLockTab(TabContents* tab) { |
594 mouse_lock_tab_ = tab; | 545 mouse_lock_tab_ = tab; |
595 UpdateNotificationRegistrations(); | 546 UpdateNotificationRegistrations(); |
596 } | 547 } |
| 548 |
| 549 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() { |
| 550 if (tab_caused_fullscreen_) |
| 551 ToggleFullscreenMode(); |
| 552 else |
| 553 NotifyTabOfExitIfNecessary(); |
| 554 } |
| 555 |
| 556 void FullscreenController::UpdateFullscreenExitBubbleContent() { |
| 557 GURL url; |
| 558 if (fullscreened_tab_) |
| 559 url = fullscreened_tab_->web_contents()->GetURL(); |
| 560 else if (mouse_lock_tab_) |
| 561 url = mouse_lock_tab_->web_contents()->GetURL(); |
| 562 else if (!extension_caused_fullscreen_.is_empty()) |
| 563 url = extension_caused_fullscreen_; |
| 564 |
| 565 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); |
| 566 |
| 567 // If bubble displays buttons, unlock mouse to allow pressing them. |
| 568 if (fullscreen_bubble::ShowButtonsForType(bubble_type) && |
| 569 IsMouseLocked() && |
| 570 mouse_lock_tab_->web_contents()) { |
| 571 WebContents* web_contents = mouse_lock_tab_->web_contents(); |
| 572 if (web_contents && web_contents->GetRenderViewHost() && |
| 573 web_contents->GetRenderViewHost()->GetView()) |
| 574 web_contents->GetRenderViewHost()->GetView()->UnlockMouse(); |
| 575 } |
| 576 |
| 577 window_->UpdateFullscreenExitBubbleContent(url, bubble_type); |
| 578 } |
| 579 |
| 580 ContentSetting |
| 581 FullscreenController::GetFullscreenSetting(const GURL& url) const { |
| 582 if (url.SchemeIsFile()) |
| 583 return CONTENT_SETTING_ALLOW; |
| 584 |
| 585 return profile_->GetHostContentSettingsMap()->GetContentSetting(url, url, |
| 586 CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string()); |
| 587 } |
| 588 |
| 589 ContentSetting |
| 590 FullscreenController::GetMouseLockSetting(const GURL& url) const { |
| 591 if (url.SchemeIsFile()) |
| 592 return CONTENT_SETTING_ALLOW; |
| 593 |
| 594 HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap(); |
| 595 return settings_map->GetContentSetting(url, url, |
| 596 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string()); |
| 597 } |
OLD | NEW |