Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: chrome/browser/ui/fullscreen_controller.cc

Issue 8423035: Split out fullscreen logic from Browser into FullscreenController. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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.
4
5 #include "chrome/browser/ui/fullscreen_controller.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "chrome/browser/content_settings/host_content_settings_map.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/browser_window.h"
13 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
14 #include "chrome/common/chrome_notification_types.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "content/browser/user_metrics.h"
17 #include "content/public/browser/notification_service.h"
18
19 FullscreenController::FullscreenController(BrowserWindow* window,
20 Profile* profile,
21 Browser* browser)
22 : window_(window),
23 profile_(profile),
24 browser_(browser),
25 fullscreened_tab_(NULL),
26 tab_caused_fullscreen_(false),
27 tab_fullscreen_accepted_(false),
28 mouse_lock_state_(MOUSELOCK_NOT_REQUESTED) {
29 }
30
31 FullscreenController::~FullscreenController() {}
32
33 bool FullscreenController::IsFullscreenForTab() const {
34 return fullscreened_tab_ != NULL;
35 }
36
37 bool FullscreenController::IsFullscreenForTab(const TabContents* tab) const {
38 const TabContentsWrapper* wrapper =
39 TabContentsWrapper::GetCurrentWrapperForContents(tab);
40 if (!wrapper || (wrapper != fullscreened_tab_))
41 return false;
42 DCHECK(tab == browser_->GetSelectedTabContents());
43 DCHECK(window_->IsFullscreen());
44 return true;
45 }
46
47 void FullscreenController::RequestToLockMouse(TabContents* tab) {
48 // Mouse Lock is only permitted when browser is in tab fullscreen.
49 if (!IsFullscreenForTab(tab)) {
50 tab->GotResponseToLockMouseRequest(false);
51 return;
52 }
53
54 if (mouse_lock_state_ == MOUSELOCK_ACCEPTED) {
55 tab->GotResponseToLockMouseRequest(true);
56 return;
57 }
58
59 switch (GetMouseLockSetting(tab->GetURL())) {
60 case CONTENT_SETTING_ALLOW:
61 mouse_lock_state_ = MOUSELOCK_ACCEPTED;
62 tab->GotResponseToLockMouseRequest(true);
63 break;
64 case CONTENT_SETTING_BLOCK:
65 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
66 tab->GotResponseToLockMouseRequest(false);
67 break;
68 case CONTENT_SETTING_ASK:
69 mouse_lock_state_ = MOUSELOCK_REQUESTED;
70 break;
71 default:
72 NOTREACHED();
73 }
74 UpdateFullscreenExitBubbleContent();
75 }
76
77 void FullscreenController::ToggleFullscreenModeForTab(TabContents* tab,
78 bool enter_fullscreen) {
79 if (tab != browser_->GetSelectedTabContents())
80 return;
81
82 bool in_browser_or_tab_fullscreen_mode;
83 #if defined(OS_MACOSX)
84 in_browser_or_tab_fullscreen_mode = window_->InPresentationMode();
85 #else
86 in_browser_or_tab_fullscreen_mode = window_->IsFullscreen();
87 #endif
88
89 if (enter_fullscreen) {
90 fullscreened_tab_ = TabContentsWrapper::GetCurrentWrapperForContents(tab);
91 if (!in_browser_or_tab_fullscreen_mode) {
92 tab_caused_fullscreen_ = true;
93 #if defined(OS_MACOSX)
94 TogglePresentationMode(true);
95 #else
96 ToggleFullscreenMode(true);
97 #endif
98 } else {
99 // We need to update the fullscreen exit bubble, e.g., going from browser
100 // fullscreen to tab fullscreen will need to show different content.
101 const GURL& url = tab->GetURL();
102 if (!tab_fullscreen_accepted_) {
103 tab_fullscreen_accepted_ =
104 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
105 }
106 UpdateFullscreenExitBubbleContent();
107 }
108 } else {
109 if (in_browser_or_tab_fullscreen_mode) {
110 if (tab_caused_fullscreen_) {
111 #if defined(OS_MACOSX)
112 TogglePresentationMode(true);
113 #else
114 ToggleFullscreenMode(true);
115 #endif
116 } else {
117 // If currently there is a tab in "tab fullscreen" mode and fullscreen
118 // was not caused by it (i.e., previously it was in "browser fullscreen"
119 // mode), we need to switch back to "browser fullscreen" mode. In this
120 // case, all we have to do is notifying the tab that it has exited "tab
121 // fullscreen" mode.
122 NotifyTabOfFullscreenExitIfNecessary();
123 }
124 }
125 }
126 }
127
128 #if defined(OS_MACOSX)
129 void FullscreenController::TogglePresentationMode(bool for_tab) {
130 bool entering_fullscreen = !window_->InPresentationMode();
131 GURL url;
132 if (for_tab) {
133 url = browser_->GetSelectedTabContents()->GetURL();
134 tab_fullscreen_accepted_ = entering_fullscreen &&
135 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
136 }
137 if (entering_fullscreen)
138 window_->EnterPresentationMode(url, GetFullscreenExitBubbleType());
139 else
140 window_->ExitPresentationMode();
141 WindowFullscreenStateChanged();
142 }
143 #endif
144
145 // TODO(koz): Change |for_tab| to an enum.
146 void FullscreenController::ToggleFullscreenMode(bool for_tab) {
147 bool entering_fullscreen = !window_->IsFullscreen();
148
149 #if !defined(OS_MACOSX)
150 // In kiosk mode, we always want to be fullscreen. When the browser first
151 // starts we're not yet fullscreen, so let the initial toggle go through.
152 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) &&
153 window_->IsFullscreen())
154 return;
155 #endif
156
157 GURL url;
158 if (for_tab) {
159 url = browser_->GetSelectedTabContents()->GetURL();
160 tab_fullscreen_accepted_ = entering_fullscreen &&
161 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
162 } else {
163 UserMetrics::RecordAction(UserMetricsAction("ToggleFullscreen"));
164 }
165 if (entering_fullscreen)
166 window_->EnterFullscreen(url, GetFullscreenExitBubbleType());
167 else
168 window_->ExitFullscreen();
169
170 // Once the window has become fullscreen it'll call back to
171 // WindowFullscreenStateChanged(). We don't do this immediately as
172 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let
173 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate.
174
175 // TODO: convert mac to invoke WindowFullscreenStateChanged once it updates
176 // the necessary state of the frame.
177 #if defined(OS_MACOSX)
178 WindowFullscreenStateChanged();
179 #endif
180 }
181
182 void FullscreenController::LostMouseLock() {
183 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
184 UpdateFullscreenExitBubbleContent();
185 }
186
187 void FullscreenController::OnTabClosing(TabContents* tab_contents) {
188 if (IsFullscreenForTab(tab_contents)) {
189 ExitTabbedFullscreenModeIfNecessary();
190 // The call to exit fullscreen may result in asynchronous notification of
191 // fullscreen state change (e.g., on Linux). We don't want to rely on it
192 // to call NotifyTabOfFullscreenExitIfNecessary(), because at that point
193 // |fullscreen_tab_| may not be valid. Instead, we call it here to clean up
194 // tab fullscreen related state.
195 NotifyTabOfFullscreenExitIfNecessary();
196 }
197 }
198
199 void FullscreenController::OnTabDeactivated(TabContentsWrapper* contents) {
200 if (contents == fullscreened_tab_)
201 ExitTabbedFullscreenModeIfNecessary();
202 }
203
204 void FullscreenController::OnAcceptFullscreenPermission(
205 const GURL& url,
206 FullscreenExitBubbleType bubble_type) {
207 bool mouse_lock = false;
208 bool fullscreen = false;
209 fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen,
210 &mouse_lock);
211 DCHECK(fullscreened_tab_);
212 DCHECK_NE(tab_fullscreen_accepted_, fullscreen);
213
214 HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap();
215 if (mouse_lock) {
216 DCHECK_EQ(mouse_lock_state_, MOUSELOCK_REQUESTED);
217 settings_map->SetContentSetting(ContentSettingsPattern::FromURL(url),
218 ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_MOUSELOCK,
219 std::string(), CONTENT_SETTING_ALLOW);
220 mouse_lock_state_ =
221 fullscreened_tab_->tab_contents()->GotResponseToLockMouseRequest(true) ?
222 MOUSELOCK_ACCEPTED : MOUSELOCK_NOT_REQUESTED;
223 }
224 if (!tab_fullscreen_accepted_) {
225 settings_map->SetContentSetting(ContentSettingsPattern::FromURL(url),
226 ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_FULLSCREEN,
227 std::string(), CONTENT_SETTING_ALLOW);
228 tab_fullscreen_accepted_ = true;
229 }
230 UpdateFullscreenExitBubbleContent();
231 }
232
233 void FullscreenController::OnDenyFullscreenPermission(
234 FullscreenExitBubbleType bubble_type) {
235 bool mouse_lock = false;
236 bool fullscreen = false;
237 fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen,
238 &mouse_lock);
239 DCHECK(fullscreened_tab_);
240 DCHECK_NE(tab_fullscreen_accepted_, fullscreen);
241
242 if (mouse_lock) {
243 DCHECK_EQ(mouse_lock_state_, MOUSELOCK_REQUESTED);
244 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
245 fullscreened_tab_->tab_contents()->GotResponseToLockMouseRequest(false);
246 if (!fullscreen)
247 UpdateFullscreenExitBubbleContent();
248 }
249
250 if (fullscreen)
251 ExitTabbedFullscreenModeIfNecessary();
252 }
253
254 void FullscreenController::WindowFullscreenStateChanged() {
255 MessageLoop::current()->PostTask(FROM_HERE,
256 base::Bind(&FullscreenController::NotifyFullscreenChange, this));
sky 2011/12/08 23:34:13 I just came across this in tracking down a regress
koz (OOO until 15th September) 2011/12/08 23:45:39 This notification has always been async (see the d
257 bool notify_tab_of_exit;
258 #if defined(OS_MACOSX)
259 notify_tab_of_exit = !window_->InPresentationMode();
260 #else
261 notify_tab_of_exit = !window_->IsFullscreen();
262 #endif
263 if (notify_tab_of_exit)
264 NotifyTabOfFullscreenExitIfNecessary();
265 }
266
267 bool FullscreenController::HandleUserPressedEscape() {
268 if (!IsFullscreenForTab())
269 return false;
270 ExitTabbedFullscreenModeIfNecessary();
271 return true;
272 }
273
274 void FullscreenController::NotifyTabOfFullscreenExitIfNecessary() {
275 if (fullscreened_tab_)
276 fullscreened_tab_->ExitFullscreenMode();
277 else
278 DCHECK_EQ(mouse_lock_state_, MOUSELOCK_NOT_REQUESTED);
279
280 fullscreened_tab_ = NULL;
281 tab_caused_fullscreen_ = false;
282 tab_fullscreen_accepted_ = false;
283 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
284
285 UpdateFullscreenExitBubbleContent();
286 }
287
288 void FullscreenController::ExitTabbedFullscreenModeIfNecessary() {
289 if (tab_caused_fullscreen_)
290 ToggleFullscreenMode(false);
291 else
292 NotifyTabOfFullscreenExitIfNecessary();
293 }
294
295 void FullscreenController::UpdateFullscreenExitBubbleContent() {
296 GURL url;
297 if (fullscreened_tab_)
298 url = fullscreened_tab_->tab_contents()->GetURL();
299
300 window_->UpdateFullscreenExitBubbleContent(url,
301 GetFullscreenExitBubbleType());
302 }
303
304 void FullscreenController::NotifyFullscreenChange() {
305 content::NotificationService::current()->Notify(
306 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
307 content::Source<FullscreenController>(this),
308 content::NotificationService::NoDetails());
309 }
310
311 FullscreenExitBubbleType
312 FullscreenController::GetFullscreenExitBubbleType() const {
313 if (!fullscreened_tab_) {
314 DCHECK_EQ(MOUSELOCK_NOT_REQUESTED, mouse_lock_state_);
315 return FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION;
316 }
317 if (fullscreened_tab_ && !tab_fullscreen_accepted_) {
318 DCHECK_NE(MOUSELOCK_ACCEPTED, mouse_lock_state_);
319 return mouse_lock_state_ == MOUSELOCK_REQUESTED ?
320 FEB_TYPE_FULLSCREEN_MOUSELOCK_BUTTONS : FEB_TYPE_FULLSCREEN_BUTTONS;
321 }
322 if (mouse_lock_state_ == MOUSELOCK_REQUESTED)
323 return FEB_TYPE_MOUSELOCK_BUTTONS;
324 return mouse_lock_state_ == MOUSELOCK_ACCEPTED ?
325 FEB_TYPE_FULLSCREEN_MOUSELOCK_EXIT_INSTRUCTION :
326 FEB_TYPE_FULLSCREEN_EXIT_INSTRUCTION;
327 }
328
329 ContentSetting
Peter Kasting 2011/11/21 19:17:46 Nit: Prefer to wrap these next two functions like:
330 FullscreenController::GetFullscreenSetting(const GURL& url) const {
331 if (url.SchemeIsFile())
332 return CONTENT_SETTING_ALLOW;
333
334 return profile_->GetHostContentSettingsMap()->GetContentSetting(url, url,
335 CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string());
336
Peter Kasting 2011/11/21 19:17:46 Nit: Extra blank line
337 }
338
339 ContentSetting
340 FullscreenController::GetMouseLockSetting(const GURL& url) const {
341 if (url.SchemeIsFile())
342 return CONTENT_SETTING_ALLOW;
343
344 HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap();
345 return settings_map->GetContentSetting(url, url,
346 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string());
347 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698