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_controller.h" | 5 #include "chrome/browser/ui/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 21 matching lines...) Expand all Loading... | |
32 Profile* profile, | 32 Profile* profile, |
33 Browser* browser) | 33 Browser* browser) |
34 : window_(window), | 34 : window_(window), |
35 profile_(profile), | 35 profile_(profile), |
36 browser_(browser), | 36 browser_(browser), |
37 fullscreened_tab_(NULL), | 37 fullscreened_tab_(NULL), |
38 tab_caused_fullscreen_(false), | 38 tab_caused_fullscreen_(false), |
39 tab_fullscreen_accepted_(false), | 39 tab_fullscreen_accepted_(false), |
40 toggled_into_fullscreen_(false), | 40 toggled_into_fullscreen_(false), |
41 mouse_lock_tab_(NULL), | 41 mouse_lock_tab_(NULL), |
42 mouse_lock_state_(MOUSELOCK_NOT_REQUESTED), | 42 mouse_lock_state_(MOUSELOCK_NOT_REQUESTED) { |
43 cancel_fullscreen_on_navigate_mode_(false) { | |
44 } | 43 } |
45 | 44 |
46 void FullscreenController::Observe(int type, | 45 void FullscreenController::Observe(int type, |
47 const content::NotificationSource& source, | 46 const content::NotificationSource& source, |
48 const content::NotificationDetails& details) { | 47 const content::NotificationDetails& details) { |
49 switch (type) { | 48 switch (type) { |
50 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: | 49 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: |
51 if (content::Details<content::LoadCommittedDetails>(details)-> | 50 if (content::Details<content::LoadCommittedDetails>(details)-> |
52 is_navigation_to_different_page()) { | 51 is_navigation_to_different_page()) { |
53 ExitTabFullscreenOrMouseLockIfNecessary(); | 52 ExitTabFullscreenOrMouseLockIfNecessary(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 | 108 |
110 // Must have a user gesture to prevent misbehaving sites from constantly | 109 // Must have a user gesture to prevent misbehaving sites from constantly |
111 // re-locking the mouse. Exceptions are when the page has unlocked | 110 // re-locking the mouse. Exceptions are when the page has unlocked |
112 // (i.e. not the user), or if we're in tab fullscreen (user gesture required | 111 // (i.e. not the user), or if we're in tab fullscreen (user gesture required |
113 // for that) | 112 // for that) |
114 if (!last_unlocked_by_target && !user_gesture && | 113 if (!last_unlocked_by_target && !user_gesture && |
115 !IsFullscreenForTabOrPending(web_contents)) { | 114 !IsFullscreenForTabOrPending(web_contents)) { |
116 web_contents->GotResponseToLockMouseRequest(false); | 115 web_contents->GotResponseToLockMouseRequest(false); |
117 return; | 116 return; |
118 } | 117 } |
119 mouse_lock_tab_ = TabContents::FromWebContents(web_contents); | 118 SetMouseLockTab(TabContents::FromWebContents(web_contents)); |
120 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); | 119 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); |
121 | 120 |
122 switch (GetMouseLockSetting(web_contents->GetURL())) { | 121 switch (GetMouseLockSetting(web_contents->GetURL())) { |
123 case CONTENT_SETTING_ALLOW: | 122 case CONTENT_SETTING_ALLOW: |
124 // If bubble already displaying buttons we must not lock the mouse yet, | 123 // If bubble already displaying buttons we must not lock the mouse yet, |
125 // or it would prevent pressing those buttons. Instead, merge the request. | 124 // or it would prevent pressing those buttons. Instead, merge the request. |
126 if (fullscreen_bubble::ShowButtonsForType(bubble_type)) { | 125 if (fullscreen_bubble::ShowButtonsForType(bubble_type)) { |
127 mouse_lock_state_ = MOUSELOCK_REQUESTED; | 126 mouse_lock_state_ = MOUSELOCK_REQUESTED; |
128 } else { | 127 } else { |
129 // Lock mouse. | 128 // Lock mouse. |
130 if (web_contents->GotResponseToLockMouseRequest(true)) { | 129 if (web_contents->GotResponseToLockMouseRequest(true)) { |
131 if (last_unlocked_by_target) { | 130 if (last_unlocked_by_target) { |
132 mouse_lock_state_ = MOUSELOCK_ACCEPTED_SILENTLY; | 131 mouse_lock_state_ = MOUSELOCK_ACCEPTED_SILENTLY; |
133 } else { | 132 } else { |
134 mouse_lock_state_ = MOUSELOCK_ACCEPTED; | 133 mouse_lock_state_ = MOUSELOCK_ACCEPTED; |
135 } | 134 } |
136 } else { | 135 } else { |
137 mouse_lock_tab_ = NULL; | 136 SetMouseLockTab(NULL); |
138 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; | 137 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
139 } | 138 } |
140 } | 139 } |
141 break; | 140 break; |
142 case CONTENT_SETTING_BLOCK: | 141 case CONTENT_SETTING_BLOCK: |
143 web_contents->GotResponseToLockMouseRequest(false); | 142 web_contents->GotResponseToLockMouseRequest(false); |
144 mouse_lock_tab_ = NULL; | 143 SetMouseLockTab(NULL); |
145 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; | 144 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
146 break; | 145 break; |
147 case CONTENT_SETTING_ASK: | 146 case CONTENT_SETTING_ASK: |
148 mouse_lock_state_ = MOUSELOCK_REQUESTED; | 147 mouse_lock_state_ = MOUSELOCK_REQUESTED; |
149 break; | 148 break; |
150 default: | 149 default: |
151 NOTREACHED(); | 150 NOTREACHED(); |
152 } | 151 } |
153 UpdateFullscreenExitBubbleContent(); | 152 UpdateFullscreenExitBubbleContent(); |
154 } | 153 } |
(...skipping 13 matching lines...) Expand all Loading... | |
168 #endif | 167 #endif |
169 | 168 |
170 bool in_browser_or_tab_fullscreen_mode; | 169 bool in_browser_or_tab_fullscreen_mode; |
171 #if defined(OS_MACOSX) | 170 #if defined(OS_MACOSX) |
172 in_browser_or_tab_fullscreen_mode = window_->InPresentationMode(); | 171 in_browser_or_tab_fullscreen_mode = window_->InPresentationMode(); |
173 #else | 172 #else |
174 in_browser_or_tab_fullscreen_mode = window_->IsFullscreen(); | 173 in_browser_or_tab_fullscreen_mode = window_->IsFullscreen(); |
175 #endif | 174 #endif |
176 | 175 |
177 if (enter_fullscreen) { | 176 if (enter_fullscreen) { |
178 fullscreened_tab_ = TabContents::FromWebContents(web_contents); | 177 SetFullscreenedTab(TabContents::FromWebContents(web_contents)); |
179 EnterCancelFullscreenOnNavigateMode(); | |
180 if (!in_browser_or_tab_fullscreen_mode) { | 178 if (!in_browser_or_tab_fullscreen_mode) { |
181 tab_caused_fullscreen_ = true; | 179 tab_caused_fullscreen_ = true; |
182 #if defined(OS_MACOSX) | 180 #if defined(OS_MACOSX) |
183 TogglePresentationModeInternal(true); | 181 TogglePresentationModeInternal(true); |
184 #else | 182 #else |
185 ToggleFullscreenModeInternal(true); | 183 ToggleFullscreenModeInternal(true); |
186 #endif | 184 #endif |
187 } else { | 185 } else { |
188 // We need to update the fullscreen exit bubble, e.g., going from browser | 186 // We need to update the fullscreen exit bubble, e.g., going from browser |
189 // fullscreen to tab fullscreen will need to show different content. | 187 // fullscreen to tab fullscreen will need to show different content. |
190 const GURL& url = web_contents->GetURL(); | 188 const GURL& url = web_contents->GetURL(); |
191 if (!tab_fullscreen_accepted_) { | 189 if (!tab_fullscreen_accepted_) { |
192 tab_fullscreen_accepted_ = | 190 tab_fullscreen_accepted_ = |
193 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; | 191 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; |
194 } | 192 } |
195 UpdateFullscreenExitBubbleContent(); | 193 UpdateFullscreenExitBubbleContent(); |
196 } | 194 } |
197 } else { | 195 } else { |
198 ExitCancelFullscreenOnNavigateMode(); | |
199 if (in_browser_or_tab_fullscreen_mode) { | 196 if (in_browser_or_tab_fullscreen_mode) { |
200 if (tab_caused_fullscreen_) { | 197 if (tab_caused_fullscreen_) { |
201 #if defined(OS_MACOSX) | 198 #if defined(OS_MACOSX) |
202 TogglePresentationModeInternal(true); | 199 TogglePresentationModeInternal(true); |
203 #else | 200 #else |
204 ToggleFullscreenModeInternal(true); | 201 ToggleFullscreenModeInternal(true); |
205 #endif | 202 #endif |
206 } else { | 203 } else { |
207 // If currently there is a tab in "tab fullscreen" mode and fullscreen | 204 // If currently there is a tab in "tab fullscreen" mode and fullscreen |
208 // was not caused by it (i.e., previously it was in "browser fullscreen" | 205 // was not caused by it (i.e., previously it was in "browser fullscreen" |
(...skipping 27 matching lines...) Expand all Loading... | |
236 void FullscreenController::ToggleFullscreenModeWithExtension( | 233 void FullscreenController::ToggleFullscreenModeWithExtension( |
237 const GURL& extension_url) { | 234 const GURL& extension_url) { |
238 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to | 235 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to |
239 // exit. | 236 // exit. |
240 extension_caused_fullscreen_ = extension_url; | 237 extension_caused_fullscreen_ = extension_url; |
241 ToggleFullscreenModeInternal(false); | 238 ToggleFullscreenModeInternal(false); |
242 } | 239 } |
243 | 240 |
244 void FullscreenController::LostMouseLock() { | 241 void FullscreenController::LostMouseLock() { |
245 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; | 242 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
246 mouse_lock_tab_ = NULL; | 243 SetMouseLockTab(NULL); |
247 NotifyMouseLockChange(); | 244 NotifyMouseLockChange(); |
248 UpdateFullscreenExitBubbleContent(); | 245 UpdateFullscreenExitBubbleContent(); |
249 } | 246 } |
250 | 247 |
251 void FullscreenController::OnTabClosing(WebContents* web_contents) { | 248 void FullscreenController::OnTabClosing(WebContents* web_contents) { |
252 if (IsFullscreenForTabOrPending(web_contents)) { | 249 if (IsFullscreenForTabOrPending(web_contents)) { |
253 ExitTabFullscreenOrMouseLockIfNecessary(); | 250 ExitTabFullscreenOrMouseLockIfNecessary(); |
254 // The call to exit fullscreen may result in asynchronous notification of | 251 // The call to exit fullscreen may result in asynchronous notification of |
255 // fullscreen state change (e.g., on Linux). We don't want to rely on it | 252 // fullscreen state change (e.g., on Linux). We don't want to rely on it |
256 // to call NotifyTabOfExitIfNecessary(), because at that point | 253 // to call NotifyTabOfExitIfNecessary(), because at that point |
(...skipping 30 matching lines...) Expand all Loading... | |
287 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string(), | 284 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string(), |
288 CONTENT_SETTING_ALLOW); | 285 CONTENT_SETTING_ALLOW); |
289 } | 286 } |
290 | 287 |
291 if (mouse_lock_tab_ && | 288 if (mouse_lock_tab_ && |
292 mouse_lock_tab_->web_contents() && | 289 mouse_lock_tab_->web_contents() && |
293 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(true)) { | 290 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(true)) { |
294 mouse_lock_state_ = MOUSELOCK_ACCEPTED; | 291 mouse_lock_state_ = MOUSELOCK_ACCEPTED; |
295 } else { | 292 } else { |
296 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; | 293 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
297 mouse_lock_tab_ = NULL; | 294 SetMouseLockTab(NULL); |
298 } | 295 } |
299 NotifyMouseLockChange(); | 296 NotifyMouseLockChange(); |
300 } | 297 } |
301 | 298 |
302 if (fullscreen && !tab_fullscreen_accepted_) { | 299 if (fullscreen && !tab_fullscreen_accepted_) { |
303 DCHECK(fullscreened_tab_); | 300 DCHECK(fullscreened_tab_); |
304 if (pattern.IsValid()) { | 301 if (pattern.IsValid()) { |
305 settings_map->SetContentSetting( | 302 settings_map->SetContentSetting( |
306 pattern, ContentSettingsPattern::Wildcard(), | 303 pattern, ContentSettingsPattern::Wildcard(), |
307 CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string(), | 304 CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string(), |
(...skipping 12 matching lines...) Expand all Loading... | |
320 &mouse_lock); | 317 &mouse_lock); |
321 DCHECK(fullscreened_tab_ || mouse_lock_tab_); | 318 DCHECK(fullscreened_tab_ || mouse_lock_tab_); |
322 DCHECK(!(fullscreen && tab_fullscreen_accepted_)); | 319 DCHECK(!(fullscreen && tab_fullscreen_accepted_)); |
323 DCHECK(!(mouse_lock && IsMouseLocked())); | 320 DCHECK(!(mouse_lock && IsMouseLocked())); |
324 | 321 |
325 if (mouse_lock) { | 322 if (mouse_lock) { |
326 DCHECK(IsMouseLockRequested()); | 323 DCHECK(IsMouseLockRequested()); |
327 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; | 324 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
328 if (mouse_lock_tab_ && mouse_lock_tab_->web_contents()) | 325 if (mouse_lock_tab_ && mouse_lock_tab_->web_contents()) |
329 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(false); | 326 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(false); |
330 mouse_lock_tab_ = NULL; | 327 SetMouseLockTab(NULL); |
331 NotifyMouseLockChange(); | 328 NotifyMouseLockChange(); |
332 | 329 |
333 // UpdateFullscreenExitBubbleContent() must be called, but to avoid | 330 // UpdateFullscreenExitBubbleContent() must be called, but to avoid |
334 // duplicate calls we do so only if not adjusting the fullscreen state | 331 // duplicate calls we do so only if not adjusting the fullscreen state |
335 // below, which also calls UpdateFullscreenExitBubbleContent(). | 332 // below, which also calls UpdateFullscreenExitBubbleContent(). |
336 if (!fullscreen) | 333 if (!fullscreen) |
337 UpdateFullscreenExitBubbleContent(); | 334 UpdateFullscreenExitBubbleContent(); |
338 } | 335 } |
339 | 336 |
340 if (fullscreen) | 337 if (fullscreen) |
(...skipping 25 matching lines...) Expand all Loading... | |
366 return true; | 363 return true; |
367 } | 364 } |
368 | 365 |
369 return false; | 366 return false; |
370 } | 367 } |
371 | 368 |
372 FullscreenController::~FullscreenController() {} | 369 FullscreenController::~FullscreenController() {} |
373 | 370 |
374 void FullscreenController::NotifyTabOfExitIfNecessary() { | 371 void FullscreenController::NotifyTabOfExitIfNecessary() { |
375 if (fullscreened_tab_) { | 372 if (fullscreened_tab_) { |
376 ExitCancelFullscreenOnNavigateMode(); | |
377 RenderViewHost* rvh = | 373 RenderViewHost* rvh = |
378 fullscreened_tab_->web_contents()->GetRenderViewHost(); | 374 fullscreened_tab_->web_contents()->GetRenderViewHost(); |
379 fullscreened_tab_ = NULL; | 375 SetFullscreenedTab(NULL); |
380 tab_caused_fullscreen_ = false; | 376 tab_caused_fullscreen_ = false; |
381 tab_fullscreen_accepted_ = false; | 377 tab_fullscreen_accepted_ = false; |
382 if (rvh) | 378 if (rvh) |
383 rvh->ExitFullscreen(); | 379 rvh->ExitFullscreen(); |
384 } | 380 } |
385 | 381 |
386 if (mouse_lock_tab_) { | 382 if (mouse_lock_tab_) { |
387 WebContents* web_contents = mouse_lock_tab_->web_contents(); | 383 WebContents* web_contents = mouse_lock_tab_->web_contents(); |
388 if (IsMouseLockRequested()) { | 384 if (IsMouseLockRequested()) { |
389 web_contents->GotResponseToLockMouseRequest(false); | 385 web_contents->GotResponseToLockMouseRequest(false); |
386 NotifyMouseLockChange(); | |
390 } else if (web_contents->GetRenderViewHost() && | 387 } else if (web_contents->GetRenderViewHost() && |
391 web_contents->GetRenderViewHost()->GetView()) { | 388 web_contents->GetRenderViewHost()->GetView()) { |
392 web_contents->GetRenderViewHost()->GetView()->UnlockMouse(); | 389 web_contents->GetRenderViewHost()->GetView()->UnlockMouse(); |
393 } | 390 } |
394 mouse_lock_tab_ = NULL; | 391 SetMouseLockTab(NULL); |
395 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; | 392 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
396 } | 393 } |
397 | 394 |
398 UpdateFullscreenExitBubbleContent(); | 395 UpdateFullscreenExitBubbleContent(); |
399 } | 396 } |
400 | 397 |
401 void FullscreenController::EnterCancelFullscreenOnNavigateMode() { | 398 void FullscreenController::UpdateNotificationRegistrations() { |
402 if (cancel_fullscreen_on_navigate_mode_) | 399 if (fullscreened_tab_ && mouse_lock_tab_) |
403 return; | 400 DCHECK(fullscreened_tab_ == mouse_lock_tab_); |
sky
2012/06/21 18:07:22
This makes me mildly nervous because its a single
| |
404 cancel_fullscreen_on_navigate_mode_ = true; | 401 |
405 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 402 TabContents* tab = fullscreened_tab_ ? fullscreened_tab_ : mouse_lock_tab_; |
406 content::Source<content::NavigationController>( | 403 |
407 &fullscreened_tab_->web_contents()->GetController())); | 404 if (tab && registrar_.IsEmpty()) { |
405 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | |
406 content::Source<content::NavigationController>( | |
407 &tab->web_contents()->GetController())); | |
408 } else if (!tab && !registrar_.IsEmpty()) { | |
409 registrar_.RemoveAll(); | |
410 } | |
408 } | 411 } |
409 | 412 |
410 void FullscreenController::ExitCancelFullscreenOnNavigateMode() { | |
411 if (!cancel_fullscreen_on_navigate_mode_) | |
412 return; | |
413 cancel_fullscreen_on_navigate_mode_ = false; | |
414 registrar_.RemoveAll(); | |
415 } | |
416 | |
417 | |
418 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() { | 413 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() { |
419 if (tab_caused_fullscreen_) | 414 if (tab_caused_fullscreen_) |
420 ToggleFullscreenMode(); | 415 ToggleFullscreenMode(); |
421 else | 416 else |
422 NotifyTabOfExitIfNecessary(); | 417 NotifyTabOfExitIfNecessary(); |
423 } | 418 } |
424 | 419 |
425 void FullscreenController::UpdateFullscreenExitBubbleContent() { | 420 void FullscreenController::UpdateFullscreenExitBubbleContent() { |
426 GURL url; | 421 GURL url; |
427 if (fullscreened_tab_) | 422 if (fullscreened_tab_) |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 window_->ExitFullscreen(); | 576 window_->ExitFullscreen(); |
582 extension_caused_fullscreen_ = GURL(); | 577 extension_caused_fullscreen_ = GURL(); |
583 } | 578 } |
584 UpdateFullscreenExitBubbleContent(); | 579 UpdateFullscreenExitBubbleContent(); |
585 | 580 |
586 // Once the window has become fullscreen it'll call back to | 581 // Once the window has become fullscreen it'll call back to |
587 // WindowFullscreenStateChanged(). We don't do this immediately as | 582 // WindowFullscreenStateChanged(). We don't do this immediately as |
588 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let | 583 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let |
589 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate. | 584 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate. |
590 } | 585 } |
586 | |
587 void FullscreenController::SetFullscreenedTab(TabContents* tab) { | |
588 fullscreened_tab_ = tab; | |
589 UpdateNotificationRegistrations(); | |
590 } | |
591 | |
592 void FullscreenController::SetMouseLockTab(TabContents* tab) { | |
593 mouse_lock_tab_ = tab; | |
594 UpdateNotificationRegistrations(); | |
595 } | |
OLD | NEW |