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.
4
5 #include "chrome/browser/ui/browser_command_controller.h"
6
7 #include "base/command_line.h"
8 #include "base/prefs/pref_service.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/defaults.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/extension_util.h"
15 #include "chrome/browser/lifetime/application_lifetime.h"
16 #include "chrome/browser/prefs/incognito_mode_prefs.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/sessions/tab_restore_service.h"
20 #include "chrome/browser/sessions/tab_restore_service_factory.h"
21 #include "chrome/browser/shell_integration.h"
22 #include "chrome/browser/signin/signin_promo.h"
23 #include "chrome/browser/sync/profile_sync_service.h"
24 #include "chrome/browser/sync/profile_sync_service_factory.h"
25 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
26 #include "chrome/browser/ui/browser.h"
27 #include "chrome/browser/ui/browser_commands.h"
28 #include "chrome/browser/ui/browser_window.h"
29 #include "chrome/browser/ui/chrome_pages.h"
30 #include "chrome/browser/ui/tabs/tab_strip_model.h"
31 #include "chrome/browser/ui/tabs/tab_strip_model_utils.h"
32 #include "chrome/browser/ui/webui/inspect_ui.h"
33 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/content_restriction.h"
35 #include "chrome/common/pref_names.h"
36 #include "chrome/common/profiling.h"
37 #include "content/public/browser/native_web_keyboard_event.h"
38 #include "content/public/browser/navigation_controller.h"
39 #include "content/public/browser/navigation_entry.h"
40 #include "content/public/browser/user_metrics.h"
41 #include "content/public/browser/web_contents.h"
42 #include "content/public/browser/web_contents_observer.h"
43 #include "content/public/common/url_constants.h"
44 #include "extensions/browser/extension_system.h"
45 #include "ui/events/keycodes/keyboard_codes.h"
46
47 #if defined(OS_MACOSX)
48 #include "chrome/browser/ui/browser_commands_mac.h"
49 #endif
50
51 #if defined(OS_WIN)
52 #include "base/win/metro.h"
53 #include "base/win/windows_version.h"
54 #include "chrome/browser/ui/apps/apps_metro_handler_win.h"
55 #include "content/public/browser/gpu_data_manager.h"
56 #endif
57
58 #if defined(USE_ASH)
59 #include "ash/accelerators/accelerator_commands.h"
60 #include "chrome/browser/ui/ash/ash_util.h"
61 #endif
62
63 #if defined(OS_CHROMEOS)
64 #include "ash/multi_profile_uma.h"
65 #include "ash/session/session_state_delegate.h"
66 #include "ash/shell.h"
67 #include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h"
68 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
69 #include "chrome/browser/ui/browser_commands_chromeos.h"
70 #endif
71
72 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
73 #include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
74 #endif
75
76 using content::NavigationEntry;
77 using content::NavigationController;
78 using content::WebContents;
79
80 namespace {
81
82 enum WindowState {
83 // Not in fullscreen mode.
84 WINDOW_STATE_NOT_FULLSCREEN,
85
86 // Fullscreen mode, occupying the whole screen.
87 WINDOW_STATE_FULLSCREEN,
88
89 // Fullscreen mode for metro snap, occupying the full height and 20% of
90 // the screen width.
91 WINDOW_STATE_METRO_SNAP,
92 };
93
94 // Returns |true| if entry has an internal chrome:// URL, |false| otherwise.
HasInternalURL(const NavigationEntry * entry)95 bool HasInternalURL(const NavigationEntry* entry) {
96 if (!entry)
97 return false;
98
99 // Check the |virtual_url()| first. This catches regular chrome:// URLs
100 // including URLs that were rewritten (such as chrome://bookmarks).
101 if (entry->GetVirtualURL().SchemeIs(content::kChromeUIScheme))
102 return true;
103
104 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually
105 // view-source: of a chrome:// URL.
106 if (entry->GetVirtualURL().SchemeIs(content::kViewSourceScheme))
107 return entry->GetURL().SchemeIs(content::kChromeUIScheme);
108
109 return false;
110 }
111
112 #if defined(OS_WIN)
113 // Windows 8 specific helper class to manage DefaultBrowserWorker. It does the
114 // following asynchronous actions in order:
115 // 1- Check that chrome is the default browser
116 // 2- If we are the default, restart chrome in metro and exit
117 // 3- If not the default browser show the 'select default browser' system dialog
118 // 4- When dialog dismisses check again who got made the default
119 // 5- If we are the default then restart chrome in metro and exit
120 // 6- If we are not the default exit.
121 //
122 // Note: this class deletes itself.
123 class SwitchToMetroUIHandler
124 : public ShellIntegration::DefaultWebClientObserver {
125 public:
SwitchToMetroUIHandler()126 SwitchToMetroUIHandler()
127 : default_browser_worker_(
128 new ShellIntegration::DefaultBrowserWorker(this)),
129 first_check_(true) {
130 default_browser_worker_->StartCheckIsDefault();
131 }
132
~SwitchToMetroUIHandler()133 virtual ~SwitchToMetroUIHandler() {
134 default_browser_worker_->ObserverDestroyed();
135 }
136
137 private:
SetDefaultWebClientUIState(ShellIntegration::DefaultWebClientUIState state)138 virtual void SetDefaultWebClientUIState(
139 ShellIntegration::DefaultWebClientUIState state) OVERRIDE {
140 switch (state) {
141 case ShellIntegration::STATE_PROCESSING:
142 return;
143 case ShellIntegration::STATE_UNKNOWN :
144 break;
145 case ShellIntegration::STATE_IS_DEFAULT:
146 chrome::AttemptRestartToMetroMode();
147 break;
148 case ShellIntegration::STATE_NOT_DEFAULT:
149 if (first_check_) {
150 default_browser_worker_->StartSetAsDefault();
151 return;
152 }
153 break;
154 default:
155 NOTREACHED();
156 }
157 delete this;
158 }
159
OnSetAsDefaultConcluded(bool success)160 virtual void OnSetAsDefaultConcluded(bool success) OVERRIDE {
161 if (!success) {
162 delete this;
163 return;
164 }
165 first_check_ = false;
166 default_browser_worker_->StartCheckIsDefault();
167 }
168
IsInteractiveSetDefaultPermitted()169 virtual bool IsInteractiveSetDefaultPermitted() OVERRIDE {
170 return true;
171 }
172
173 scoped_refptr<ShellIntegration::DefaultBrowserWorker> default_browser_worker_;
174 bool first_check_;
175
176 DISALLOW_COPY_AND_ASSIGN(SwitchToMetroUIHandler);
177 };
178 #endif // defined(OS_WIN)
179
180 } // namespace
181
182 namespace chrome {
183
184 ///////////////////////////////////////////////////////////////////////////////
185 // BrowserCommandController, public:
186
BrowserCommandController(Browser * browser)187 BrowserCommandController::BrowserCommandController(Browser* browser)
188 : browser_(browser),
189 command_updater_(this),
190 block_command_execution_(false),
191 last_blocked_command_id_(-1),
192 last_blocked_command_disposition_(CURRENT_TAB) {
193 browser_->tab_strip_model()->AddObserver(this);
194 PrefService* local_state = g_browser_process->local_state();
195 if (local_state) {
196 local_pref_registrar_.Init(local_state);
197 local_pref_registrar_.Add(
198 prefs::kAllowFileSelectionDialogs,
199 base::Bind(
200 &BrowserCommandController::UpdateCommandsForFileSelectionDialogs,
201 base::Unretained(this)));
202 }
203
204 profile_pref_registrar_.Init(profile()->GetPrefs());
205 profile_pref_registrar_.Add(
206 prefs::kDevToolsDisabled,
207 base::Bind(&BrowserCommandController::UpdateCommandsForDevTools,
208 base::Unretained(this)));
209 profile_pref_registrar_.Add(
210 bookmarks::prefs::kEditBookmarksEnabled,
211 base::Bind(&BrowserCommandController::UpdateCommandsForBookmarkEditing,
212 base::Unretained(this)));
213 profile_pref_registrar_.Add(
214 bookmarks::prefs::kShowBookmarkBar,
215 base::Bind(&BrowserCommandController::UpdateCommandsForBookmarkBar,
216 base::Unretained(this)));
217 profile_pref_registrar_.Add(
218 prefs::kIncognitoModeAvailability,
219 base::Bind(
220 &BrowserCommandController::UpdateCommandsForIncognitoAvailability,
221 base::Unretained(this)));
222 profile_pref_registrar_.Add(
223 prefs::kPrintingEnabled,
224 base::Bind(&BrowserCommandController::UpdatePrintingState,
225 base::Unretained(this)));
226 #if !defined(OS_MACOSX)
227 profile_pref_registrar_.Add(
228 prefs::kFullscreenAllowed,
229 base::Bind(&BrowserCommandController::UpdateCommandsForFullscreenMode,
230 base::Unretained(this)));
231 #endif
232 pref_signin_allowed_.Init(
233 prefs::kSigninAllowed,
234 profile()->GetOriginalProfile()->GetPrefs(),
235 base::Bind(&BrowserCommandController::OnSigninAllowedPrefChange,
236 base::Unretained(this)));
237
238 InitCommandState();
239
240 TabRestoreService* tab_restore_service =
241 TabRestoreServiceFactory::GetForProfile(profile());
242 if (tab_restore_service) {
243 tab_restore_service->AddObserver(this);
244 TabRestoreServiceChanged(tab_restore_service);
245 }
246 }
247
~BrowserCommandController()248 BrowserCommandController::~BrowserCommandController() {
249 // TabRestoreService may have been shutdown by the time we get here. Don't
250 // trigger creating it.
251 TabRestoreService* tab_restore_service =
252 TabRestoreServiceFactory::GetForProfileIfExisting(profile());
253 if (tab_restore_service)
254 tab_restore_service->RemoveObserver(this);
255 profile_pref_registrar_.RemoveAll();
256 local_pref_registrar_.RemoveAll();
257 browser_->tab_strip_model()->RemoveObserver(this);
258 }
259
IsReservedCommandOrKey(int command_id,const content::NativeWebKeyboardEvent & event)260 bool BrowserCommandController::IsReservedCommandOrKey(
261 int command_id,
262 const content::NativeWebKeyboardEvent& event) {
263 // In Apps mode, no keys are reserved.
264 if (browser_->is_app())
265 return false;
266
267 #if defined(OS_CHROMEOS)
268 // On Chrome OS, the top row of keys are mapped to browser actions like
269 // back/forward or refresh. We don't want web pages to be able to change the
270 // behavior of these keys. Ash handles F4 and up; this leaves us needing to
271 // reserve browser back/forward and refresh here.
272 ui::KeyboardCode key_code =
273 static_cast<ui::KeyboardCode>(event.windowsKeyCode);
274 if ((key_code == ui::VKEY_BROWSER_BACK && command_id == IDC_BACK) ||
275 (key_code == ui::VKEY_BROWSER_FORWARD && command_id == IDC_FORWARD) ||
276 (key_code == ui::VKEY_BROWSER_REFRESH && command_id == IDC_RELOAD)) {
277 return true;
278 }
279 #endif
280
281 if (window()->IsFullscreen() && command_id == IDC_FULLSCREEN)
282 return true;
283
284 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
285 // If this key was registered by the user as a content editing hotkey, then
286 // it is not reserved.
287 ui::TextEditKeyBindingsDelegateAuraLinux* delegate =
288 ui::GetTextEditKeyBindingsDelegate();
289 if (delegate && event.os_event && delegate->MatchEvent(*event.os_event, NULL))
290 return false;
291 #endif
292
293 return command_id == IDC_CLOSE_TAB ||
294 command_id == IDC_CLOSE_WINDOW ||
295 command_id == IDC_NEW_INCOGNITO_WINDOW ||
296 command_id == IDC_NEW_TAB ||
297 command_id == IDC_NEW_WINDOW ||
298 command_id == IDC_RESTORE_TAB ||
299 command_id == IDC_SELECT_NEXT_TAB ||
300 command_id == IDC_SELECT_PREVIOUS_TAB ||
301 command_id == IDC_EXIT;
302 }
303
SetBlockCommandExecution(bool block)304 void BrowserCommandController::SetBlockCommandExecution(bool block) {
305 block_command_execution_ = block;
306 if (block) {
307 last_blocked_command_id_ = -1;
308 last_blocked_command_disposition_ = CURRENT_TAB;
309 }
310 }
311
GetLastBlockedCommand(WindowOpenDisposition * disposition)312 int BrowserCommandController::GetLastBlockedCommand(
313 WindowOpenDisposition* disposition) {
314 if (disposition)
315 *disposition = last_blocked_command_disposition_;
316 return last_blocked_command_id_;
317 }
318
TabStateChanged()319 void BrowserCommandController::TabStateChanged() {
320 UpdateCommandsForTabState();
321 }
322
ZoomStateChanged()323 void BrowserCommandController::ZoomStateChanged() {
324 UpdateCommandsForZoomState();
325 }
326
ContentRestrictionsChanged()327 void BrowserCommandController::ContentRestrictionsChanged() {
328 UpdateCommandsForContentRestrictionState();
329 }
330
FullscreenStateChanged()331 void BrowserCommandController::FullscreenStateChanged() {
332 UpdateCommandsForFullscreenMode();
333 }
334
PrintingStateChanged()335 void BrowserCommandController::PrintingStateChanged() {
336 UpdatePrintingState();
337 }
338
LoadingStateChanged(bool is_loading,bool force)339 void BrowserCommandController::LoadingStateChanged(bool is_loading,
340 bool force) {
341 UpdateReloadStopState(is_loading, force);
342 }
343
344 ////////////////////////////////////////////////////////////////////////////////
345 // BrowserCommandController, CommandUpdaterDelegate implementation:
346
ExecuteCommandWithDisposition(int id,WindowOpenDisposition disposition)347 void BrowserCommandController::ExecuteCommandWithDisposition(
348 int id,
349 WindowOpenDisposition disposition) {
350 // No commands are enabled if there is not yet any selected tab.
351 // TODO(pkasting): It seems like we should not need this, because either
352 // most/all commands should not have been enabled yet anyway or the ones that
353 // are enabled should be global, or safe themselves against having no selected
354 // tab. However, Ben says he tried removing this before and got lots of
355 // crashes, e.g. from Windows sending WM_COMMANDs at random times during
356 // window construction. This probably could use closer examination someday.
357 if (browser_->tab_strip_model()->active_index() == TabStripModel::kNoTab)
358 return;
359
360 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
361 << id;
362
363 // If command execution is blocked then just record the command and return.
364 if (block_command_execution_) {
365 // We actually only allow no more than one blocked command, otherwise some
366 // commands maybe lost.
367 DCHECK_EQ(last_blocked_command_id_, -1);
368 last_blocked_command_id_ = id;
369 last_blocked_command_disposition_ = disposition;
370 return;
371 }
372
373 // The order of commands in this switch statement must match the function
374 // declaration order in browser.h!
375 switch (id) {
376 // Navigation commands
377 case IDC_BACK:
378 GoBack(browser_, disposition);
379 break;
380 case IDC_FORWARD:
381 GoForward(browser_, disposition);
382 break;
383 case IDC_RELOAD:
384 Reload(browser_, disposition);
385 break;
386 case IDC_RELOAD_CLEARING_CACHE:
387 ClearCache(browser_);
388 // FALL THROUGH
389 case IDC_RELOAD_IGNORING_CACHE:
390 ReloadIgnoringCache(browser_, disposition);
391 break;
392 case IDC_HOME:
393 Home(browser_, disposition);
394 break;
395 case IDC_OPEN_CURRENT_URL:
396 OpenCurrentURL(browser_);
397 break;
398 case IDC_STOP:
399 Stop(browser_);
400 break;
401
402 // Window management commands
403 case IDC_NEW_WINDOW:
404 NewWindow(browser_);
405 break;
406 case IDC_NEW_INCOGNITO_WINDOW:
407 NewIncognitoWindow(browser_);
408 break;
409 case IDC_CLOSE_WINDOW:
410 content::RecordAction(base::UserMetricsAction("CloseWindowByKey"));
411 CloseWindow(browser_);
412 break;
413 case IDC_NEW_TAB:
414 NewTab(browser_);
415 break;
416 case IDC_CLOSE_TAB:
417 content::RecordAction(base::UserMetricsAction("CloseTabByKey"));
418 CloseTab(browser_);
419 break;
420 case IDC_SELECT_NEXT_TAB:
421 content::RecordAction(base::UserMetricsAction("Accel_SelectNextTab"));
422 SelectNextTab(browser_);
423 break;
424 case IDC_SELECT_PREVIOUS_TAB:
425 content::RecordAction(
426 base::UserMetricsAction("Accel_SelectPreviousTab"));
427 SelectPreviousTab(browser_);
428 break;
429 case IDC_MOVE_TAB_NEXT:
430 MoveTabNext(browser_);
431 break;
432 case IDC_MOVE_TAB_PREVIOUS:
433 MoveTabPrevious(browser_);
434 break;
435 case IDC_SELECT_TAB_0:
436 case IDC_SELECT_TAB_1:
437 case IDC_SELECT_TAB_2:
438 case IDC_SELECT_TAB_3:
439 case IDC_SELECT_TAB_4:
440 case IDC_SELECT_TAB_5:
441 case IDC_SELECT_TAB_6:
442 case IDC_SELECT_TAB_7:
443 SelectNumberedTab(browser_, id - IDC_SELECT_TAB_0);
444 break;
445 case IDC_SELECT_LAST_TAB:
446 SelectLastTab(browser_);
447 break;
448 case IDC_DUPLICATE_TAB:
449 DuplicateTab(browser_);
450 break;
451 case IDC_RESTORE_TAB:
452 RestoreTab(browser_);
453 break;
454 case IDC_SHOW_AS_TAB:
455 ConvertPopupToTabbedBrowser(browser_);
456 break;
457 case IDC_FULLSCREEN:
458 #if defined(OS_MACOSX)
459 chrome::ToggleFullscreenWithChromeOrFallback(browser_);
460 #else
461 chrome::ToggleFullscreenMode(browser_);
462 #endif
463 break;
464
465 #if defined(OS_CHROMEOS)
466 case IDC_VISIT_DESKTOP_OF_LRU_USER_2:
467 case IDC_VISIT_DESKTOP_OF_LRU_USER_3:
468 ExecuteVisitDesktopCommand(id, browser_->window()->GetNativeWindow());
469 break;
470 #endif
471
472 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
473 case IDC_USE_SYSTEM_TITLE_BAR: {
474 PrefService* prefs = browser_->profile()->GetPrefs();
475 prefs->SetBoolean(prefs::kUseCustomChromeFrame,
476 !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
477 break;
478 }
479 #endif
480
481 #if defined(OS_WIN)
482 // Windows 8 specific commands.
483 case IDC_METRO_SNAP_ENABLE:
484 browser_->SetMetroSnapMode(true);
485 break;
486 case IDC_METRO_SNAP_DISABLE:
487 browser_->SetMetroSnapMode(false);
488 break;
489 case IDC_WIN_DESKTOP_RESTART:
490 if (!VerifyASHSwitchForApps(window()->GetNativeWindow(), id))
491 break;
492
493 chrome::AttemptRestartToDesktopMode();
494 if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
495 content::RecordAction(base::UserMetricsAction("Win8DesktopRestart"));
496 } else {
497 content::RecordAction(base::UserMetricsAction("Win7DesktopRestart"));
498 }
499 break;
500 case IDC_WIN8_METRO_RESTART:
501 case IDC_WIN_CHROMEOS_RESTART:
502 if (!VerifyASHSwitchForApps(window()->GetNativeWindow(), id))
503 break;
504 if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
505 // SwitchToMetroUIHandler deletes itself.
506 new SwitchToMetroUIHandler;
507 content::RecordAction(base::UserMetricsAction("Win8MetroRestart"));
508 } else {
509 content::RecordAction(base::UserMetricsAction("Win7ASHRestart"));
510 chrome::AttemptRestartToMetroMode();
511 }
512 break;
513 #endif
514
515 #if defined(OS_MACOSX)
516 case IDC_PRESENTATION_MODE:
517 chrome::ToggleFullscreenMode(browser_);
518 break;
519 #endif
520 case IDC_EXIT:
521 Exit();
522 break;
523
524 // Page-related commands
525 case IDC_SAVE_PAGE:
526 SavePage(browser_);
527 break;
528 case IDC_BOOKMARK_PAGE:
529 BookmarkCurrentPage(browser_);
530 break;
531 case IDC_PIN_TO_START_SCREEN:
532 TogglePagePinnedToStartScreen(browser_);
533 break;
534 case IDC_BOOKMARK_ALL_TABS:
535 BookmarkAllTabs(browser_);
536 break;
537 case IDC_VIEW_SOURCE:
538 ViewSelectedSource(browser_);
539 break;
540 case IDC_EMAIL_PAGE_LOCATION:
541 EmailPageLocation(browser_);
542 break;
543 case IDC_PRINT:
544 Print(browser_);
545 break;
546 #if !defined(DISABLE_BASIC_PRINTING)
547 case IDC_BASIC_PRINT:
548 content::RecordAction(base::UserMetricsAction("Accel_Advanced_Print"));
549 BasicPrint(browser_);
550 break;
551 #endif // !DISABLE_BASIC_PRINTING
552 case IDC_TRANSLATE_PAGE:
553 Translate(browser_);
554 break;
555 case IDC_MANAGE_PASSWORDS_FOR_PAGE:
556 ManagePasswordsForPage(browser_);
557 break;
558
559 // Page encoding commands
560 case IDC_ENCODING_AUTO_DETECT:
561 browser_->ToggleEncodingAutoDetect();
562 break;
563 case IDC_ENCODING_UTF8:
564 case IDC_ENCODING_UTF16LE:
565 case IDC_ENCODING_ISO88591:
566 case IDC_ENCODING_WINDOWS1252:
567 case IDC_ENCODING_GBK:
568 case IDC_ENCODING_GB18030:
569 case IDC_ENCODING_BIG5HKSCS:
570 case IDC_ENCODING_BIG5:
571 case IDC_ENCODING_KOREAN:
572 case IDC_ENCODING_SHIFTJIS:
573 case IDC_ENCODING_ISO2022JP:
574 case IDC_ENCODING_EUCJP:
575 case IDC_ENCODING_THAI:
576 case IDC_ENCODING_ISO885915:
577 case IDC_ENCODING_MACINTOSH:
578 case IDC_ENCODING_ISO88592:
579 case IDC_ENCODING_WINDOWS1250:
580 case IDC_ENCODING_ISO88595:
581 case IDC_ENCODING_WINDOWS1251:
582 case IDC_ENCODING_KOI8R:
583 case IDC_ENCODING_KOI8U:
584 case IDC_ENCODING_ISO88597:
585 case IDC_ENCODING_WINDOWS1253:
586 case IDC_ENCODING_ISO88594:
587 case IDC_ENCODING_ISO885913:
588 case IDC_ENCODING_WINDOWS1257:
589 case IDC_ENCODING_ISO88593:
590 case IDC_ENCODING_ISO885910:
591 case IDC_ENCODING_ISO885914:
592 case IDC_ENCODING_ISO885916:
593 case IDC_ENCODING_WINDOWS1254:
594 case IDC_ENCODING_ISO88596:
595 case IDC_ENCODING_WINDOWS1256:
596 case IDC_ENCODING_ISO88598:
597 case IDC_ENCODING_ISO88598I:
598 case IDC_ENCODING_WINDOWS1255:
599 case IDC_ENCODING_WINDOWS1258:
600 browser_->OverrideEncoding(id);
601 break;
602
603 // Clipboard commands
604 case IDC_CUT:
605 Cut(browser_);
606 break;
607 case IDC_COPY:
608 Copy(browser_);
609 break;
610 case IDC_PASTE:
611 Paste(browser_);
612 break;
613
614 // Find-in-page
615 case IDC_FIND:
616 Find(browser_);
617 break;
618 case IDC_FIND_NEXT:
619 FindNext(browser_);
620 break;
621 case IDC_FIND_PREVIOUS:
622 FindPrevious(browser_);
623 break;
624
625 // Zoom
626 case IDC_ZOOM_PLUS:
627 Zoom(browser_, content::PAGE_ZOOM_IN);
628 break;
629 case IDC_ZOOM_NORMAL:
630 Zoom(browser_, content::PAGE_ZOOM_RESET);
631 break;
632 case IDC_ZOOM_MINUS:
633 Zoom(browser_, content::PAGE_ZOOM_OUT);
634 break;
635
636 // Focus various bits of UI
637 case IDC_FOCUS_TOOLBAR:
638 content::RecordAction(base::UserMetricsAction("Accel_Focus_Toolbar"));
639 FocusToolbar(browser_);
640 break;
641 case IDC_FOCUS_LOCATION:
642 content::RecordAction(base::UserMetricsAction("Accel_Focus_Location"));
643 FocusLocationBar(browser_);
644 break;
645 case IDC_FOCUS_SEARCH:
646 content::RecordAction(base::UserMetricsAction("Accel_Focus_Search"));
647 FocusSearch(browser_);
648 break;
649 case IDC_FOCUS_MENU_BAR:
650 FocusAppMenu(browser_);
651 break;
652 case IDC_FOCUS_BOOKMARKS:
653 content::RecordAction(
654 base::UserMetricsAction("Accel_Focus_Bookmarks"));
655 FocusBookmarksToolbar(browser_);
656 break;
657 case IDC_FOCUS_INFOBARS:
658 FocusInfobars(browser_);
659 break;
660 case IDC_FOCUS_NEXT_PANE:
661 FocusNextPane(browser_);
662 break;
663 case IDC_FOCUS_PREVIOUS_PANE:
664 FocusPreviousPane(browser_);
665 break;
666
667 // Show various bits of UI
668 case IDC_OPEN_FILE:
669 browser_->OpenFile();
670 break;
671 case IDC_CREATE_SHORTCUTS:
672 CreateApplicationShortcuts(browser_);
673 break;
674 case IDC_CREATE_HOSTED_APP:
675 CreateBookmarkAppFromCurrentWebContents(browser_);
676 break;
677 case IDC_DEV_TOOLS:
678 ToggleDevToolsWindow(browser_, DevToolsToggleAction::Show());
679 break;
680 case IDC_DEV_TOOLS_CONSOLE:
681 ToggleDevToolsWindow(browser_, DevToolsToggleAction::ShowConsole());
682 break;
683 case IDC_DEV_TOOLS_DEVICES:
684 InspectUI::InspectDevices(browser_);
685 break;
686 case IDC_DEV_TOOLS_INSPECT:
687 ToggleDevToolsWindow(browser_, DevToolsToggleAction::Inspect());
688 break;
689 case IDC_DEV_TOOLS_TOGGLE:
690 ToggleDevToolsWindow(browser_, DevToolsToggleAction::Toggle());
691 break;
692 case IDC_TASK_MANAGER:
693 OpenTaskManager(browser_);
694 break;
695 #if defined(OS_CHROMEOS)
696 case IDC_TAKE_SCREENSHOT:
697 TakeScreenshot();
698 break;
699 #endif
700 #if defined(GOOGLE_CHROME_BUILD)
701 case IDC_FEEDBACK:
702 OpenFeedbackDialog(browser_);
703 break;
704 #endif
705 case IDC_SHOW_BOOKMARK_BAR:
706 ToggleBookmarkBar(browser_);
707 break;
708 case IDC_PROFILING_ENABLED:
709 Profiling::Toggle();
710 break;
711
712 case IDC_SHOW_BOOKMARK_MANAGER:
713 ShowBookmarkManager(browser_);
714 break;
715 case IDC_SHOW_APP_MENU:
716 content::RecordAction(base::UserMetricsAction("Accel_Show_App_Menu"));
717 ShowAppMenu(browser_);
718 break;
719 case IDC_SHOW_AVATAR_MENU:
720 ShowAvatarMenu(browser_);
721 break;
722 case IDC_SHOW_HISTORY:
723 ShowHistory(browser_);
724 break;
725 case IDC_SHOW_DOWNLOADS:
726 ShowDownloads(browser_);
727 break;
728 case IDC_MANAGE_EXTENSIONS:
729 ShowExtensions(browser_, std::string());
730 break;
731 case IDC_OPTIONS:
732 ShowSettings(browser_);
733 break;
734 case IDC_EDIT_SEARCH_ENGINES:
735 ShowSearchEngineSettings(browser_);
736 break;
737 case IDC_VIEW_PASSWORDS:
738 ShowPasswordManager(browser_);
739 break;
740 case IDC_CLEAR_BROWSING_DATA:
741 ShowClearBrowsingDataDialog(browser_);
742 break;
743 case IDC_IMPORT_SETTINGS:
744 ShowImportDialog(browser_);
745 break;
746 case IDC_TOGGLE_REQUEST_TABLET_SITE:
747 ToggleRequestTabletSite(browser_);
748 break;
749 case IDC_ABOUT:
750 ShowAboutChrome(browser_);
751 break;
752 case IDC_UPGRADE_DIALOG:
753 OpenUpdateChromeDialog(browser_);
754 break;
755 case IDC_VIEW_INCOMPATIBILITIES:
756 ShowConflicts(browser_);
757 break;
758 case IDC_HELP_PAGE_VIA_KEYBOARD:
759 ShowHelp(browser_, HELP_SOURCE_KEYBOARD);
760 break;
761 case IDC_HELP_PAGE_VIA_MENU:
762 ShowHelp(browser_, HELP_SOURCE_MENU);
763 break;
764 case IDC_SHOW_SIGNIN:
765 ShowBrowserSignin(browser_, signin::SOURCE_MENU);
766 break;
767 case IDC_TOGGLE_SPEECH_INPUT:
768 ToggleSpeechInput(browser_);
769 break;
770 case IDC_DISTILL_PAGE:
771 DistillCurrentPage(browser_);
772 break;
773
774 default:
775 LOG(WARNING) << "Received Unimplemented Command: " << id;
776 break;
777 }
778 }
779
780 ////////////////////////////////////////////////////////////////////////////////
781 // BrowserCommandController, SigninPrefObserver implementation:
782
OnSigninAllowedPrefChange()783 void BrowserCommandController::OnSigninAllowedPrefChange() {
784 // For unit tests, we don't have a window.
785 if (!window())
786 return;
787 UpdateShowSyncState(IsShowingMainUI());
788 }
789
790 // BrowserCommandController, TabStripModelObserver implementation:
791
TabInsertedAt(WebContents * contents,int index,bool foreground)792 void BrowserCommandController::TabInsertedAt(WebContents* contents,
793 int index,
794 bool foreground) {
795 AddInterstitialObservers(contents);
796 }
797
TabDetachedAt(WebContents * contents,int index)798 void BrowserCommandController::TabDetachedAt(WebContents* contents, int index) {
799 RemoveInterstitialObservers(contents);
800 }
801
TabReplacedAt(TabStripModel * tab_strip_model,WebContents * old_contents,WebContents * new_contents,int index)802 void BrowserCommandController::TabReplacedAt(TabStripModel* tab_strip_model,
803 WebContents* old_contents,
804 WebContents* new_contents,
805 int index) {
806 RemoveInterstitialObservers(old_contents);
807 AddInterstitialObservers(new_contents);
808 }
809
TabBlockedStateChanged(content::WebContents * contents,int index)810 void BrowserCommandController::TabBlockedStateChanged(
811 content::WebContents* contents,
812 int index) {
813 PrintingStateChanged();
814 FullscreenStateChanged();
815 UpdateCommandsForFind();
816 }
817
818 ////////////////////////////////////////////////////////////////////////////////
819 // BrowserCommandController, TabRestoreServiceObserver implementation:
820
TabRestoreServiceChanged(TabRestoreService * service)821 void BrowserCommandController::TabRestoreServiceChanged(
822 TabRestoreService* service) {
823 UpdateTabRestoreCommandState();
824 }
825
TabRestoreServiceDestroyed(TabRestoreService * service)826 void BrowserCommandController::TabRestoreServiceDestroyed(
827 TabRestoreService* service) {
828 service->RemoveObserver(this);
829 }
830
TabRestoreServiceLoaded(TabRestoreService * service)831 void BrowserCommandController::TabRestoreServiceLoaded(
832 TabRestoreService* service) {
833 UpdateTabRestoreCommandState();
834 }
835
836 ////////////////////////////////////////////////////////////////////////////////
837 // BrowserCommandController, private:
838
839 class BrowserCommandController::InterstitialObserver
840 : public content::WebContentsObserver {
841 public:
InterstitialObserver(BrowserCommandController * controller,content::WebContents * web_contents)842 InterstitialObserver(BrowserCommandController* controller,
843 content::WebContents* web_contents)
844 : WebContentsObserver(web_contents),
845 controller_(controller) {
846 }
847
DidAttachInterstitialPage()848 virtual void DidAttachInterstitialPage() OVERRIDE {
849 controller_->UpdateCommandsForTabState();
850 }
851
DidDetachInterstitialPage()852 virtual void DidDetachInterstitialPage() OVERRIDE {
853 controller_->UpdateCommandsForTabState();
854 }
855
856 private:
857 BrowserCommandController* controller_;
858
859 DISALLOW_COPY_AND_ASSIGN(InterstitialObserver);
860 };
861
IsShowingMainUI()862 bool BrowserCommandController::IsShowingMainUI() {
863 bool should_hide_ui = window() && window()->ShouldHideUIForFullscreen();
864 return browser_->is_type_tabbed() && !should_hide_ui;
865 }
866
InitCommandState()867 void BrowserCommandController::InitCommandState() {
868 // All browser commands whose state isn't set automagically some other way
869 // (like Back & Forward with initial page load) must have their state
870 // initialized here, otherwise they will be forever disabled.
871
872 // Navigation commands
873 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
874 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
875 command_updater_.UpdateCommandEnabled(IDC_RELOAD_CLEARING_CACHE, true);
876
877 // Window management commands
878 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
879 command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
880 command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
881 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
882 UpdateTabRestoreCommandState();
883 #if defined(OS_WIN) && defined(USE_ASH)
884 if (browser_->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH)
885 command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
886 #else
887 command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
888 #endif
889 command_updater_.UpdateCommandEnabled(IDC_DEBUG_FRAME_TOGGLE, true);
890 #if defined(USE_ASH)
891 command_updater_.UpdateCommandEnabled(IDC_MINIMIZE_WINDOW, true);
892 #endif
893 #if defined(OS_CHROMEOS)
894 command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_2, true);
895 command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_3, true);
896 #endif
897 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
898 command_updater_.UpdateCommandEnabled(IDC_USE_SYSTEM_TITLE_BAR, true);
899 #endif
900
901 // Page-related commands
902 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
903 command_updater_.UpdateCommandEnabled(IDC_MANAGE_PASSWORDS_FOR_PAGE, true);
904 command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
905 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
906 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
907 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
908 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
909 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
910 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
911 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true);
912 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true);
913 command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true);
914 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true);
915 command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true);
916 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true);
917 command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true);
918 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true);
919 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true);
920 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true);
921 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true);
922 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true);
923 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true);
924 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true);
925 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true);
926 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true);
927 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true);
928 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true);
929 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true);
930 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true);
931 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true);
932 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true);
933 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true);
934 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true);
935 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true);
936 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true);
937 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true);
938 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true);
939 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true);
940 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
941 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
942
943 // Zoom
944 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
945 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
946 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, false);
947 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
948
949 // Show various bits of UI
950 const bool guest_session = profile()->IsGuestSession();
951 const bool normal_window = browser_->is_type_tabbed();
952 UpdateOpenFileState(&command_updater_);
953 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
954 UpdateCommandsForDevTools();
955 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, CanOpenTaskManager());
956 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, !guest_session);
957 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
958 command_updater_.UpdateCommandEnabled(IDC_HELP_MENU, true);
959 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_KEYBOARD, true);
960 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_MENU, true);
961 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, !guest_session);
962 command_updater_.UpdateCommandEnabled(IDC_RECENT_TABS_MENU,
963 !guest_session &&
964 !profile()->IsOffTheRecord());
965 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
966 #if defined(OS_CHROMEOS)
967 command_updater_.UpdateCommandEnabled(IDC_TAKE_SCREENSHOT, true);
968 #else
969 // Chrome OS uses the system tray menu to handle multi-profiles.
970 if (normal_window && (guest_session || !profile()->IsOffTheRecord()))
971 command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU, true);
972 #endif
973
974 UpdateShowSyncState(true);
975
976 // Navigation commands
977 command_updater_.UpdateCommandEnabled(
978 IDC_HOME,
979 normal_window || (extensions::util::IsStreamlinedHostedAppsEnabled() &&
980 browser_->is_app()));
981
982 // Window management commands
983 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
984 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
985 normal_window);
986 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
987 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
988 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
989 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window);
990 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window);
991 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window);
992 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window);
993 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window);
994 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window);
995 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
996 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
997 #if defined(OS_WIN)
998 bool metro = browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH;
999 command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_ENABLE, metro);
1000 command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_DISABLE, metro);
1001 int restart_mode = metro ? IDC_WIN_DESKTOP_RESTART :
1002 (base::win::GetVersion() >= base::win::VERSION_WIN8 ?
1003 IDC_WIN8_METRO_RESTART : IDC_WIN_CHROMEOS_RESTART);
1004 command_updater_.UpdateCommandEnabled(restart_mode, normal_window);
1005 #endif
1006
1007 // These are always enabled; the menu determines their menu item visibility.
1008 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
1009 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
1010
1011 // Toggle speech input
1012 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true);
1013
1014 // Distill current page.
1015 command_updater_.UpdateCommandEnabled(
1016 IDC_DISTILL_PAGE,
1017 CommandLine::ForCurrentProcess()->HasSwitch(
1018 switches::kEnableDomDistiller));
1019
1020 // Initialize other commands whose state changes based on various conditions.
1021 UpdateCommandsForFullscreenMode();
1022 UpdateCommandsForContentRestrictionState();
1023 UpdateCommandsForBookmarkEditing();
1024 UpdateCommandsForIncognitoAvailability();
1025 }
1026
1027 // static
UpdateSharedCommandsForIncognitoAvailability(CommandUpdater * command_updater,Profile * profile)1028 void BrowserCommandController::UpdateSharedCommandsForIncognitoAvailability(
1029 CommandUpdater* command_updater,
1030 Profile* profile) {
1031 const bool guest_session = profile->IsGuestSession();
1032 // TODO(mlerman): Make GetAvailability account for profile->IsGuestSession().
1033 IncognitoModePrefs::Availability incognito_availability =
1034 IncognitoModePrefs::GetAvailability(profile->GetPrefs());
1035 command_updater->UpdateCommandEnabled(
1036 IDC_NEW_WINDOW,
1037 incognito_availability != IncognitoModePrefs::FORCED);
1038 command_updater->UpdateCommandEnabled(
1039 IDC_NEW_INCOGNITO_WINDOW,
1040 incognito_availability != IncognitoModePrefs::DISABLED && !guest_session);
1041
1042 const bool forced_incognito =
1043 incognito_availability == IncognitoModePrefs::FORCED ||
1044 guest_session; // Guest always runs in Incognito mode.
1045 command_updater->UpdateCommandEnabled(
1046 IDC_SHOW_BOOKMARK_MANAGER,
1047 browser_defaults::bookmarks_enabled && !forced_incognito);
1048 ExtensionService* extension_service =
1049 extensions::ExtensionSystem::Get(profile)->extension_service();
1050 const bool enable_extensions =
1051 extension_service && extension_service->extensions_enabled();
1052
1053 // Bookmark manager and settings page/subpages are forced to open in normal
1054 // mode. For this reason we disable these commands when incognito is forced.
1055 command_updater->UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
1056 enable_extensions && !forced_incognito);
1057
1058 command_updater->UpdateCommandEnabled(IDC_IMPORT_SETTINGS, !forced_incognito);
1059 command_updater->UpdateCommandEnabled(IDC_OPTIONS,
1060 !forced_incognito || guest_session);
1061 command_updater->UpdateCommandEnabled(IDC_SHOW_SIGNIN, !forced_incognito);
1062 }
1063
UpdateCommandsForIncognitoAvailability()1064 void BrowserCommandController::UpdateCommandsForIncognitoAvailability() {
1065 UpdateSharedCommandsForIncognitoAvailability(&command_updater_, profile());
1066
1067 if (!IsShowingMainUI()) {
1068 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, false);
1069 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, false);
1070 }
1071 }
1072
UpdateCommandsForTabState()1073 void BrowserCommandController::UpdateCommandsForTabState() {
1074 WebContents* current_web_contents =
1075 browser_->tab_strip_model()->GetActiveWebContents();
1076 if (!current_web_contents) // May be NULL during tab restore.
1077 return;
1078
1079 // Navigation commands
1080 command_updater_.UpdateCommandEnabled(IDC_BACK, CanGoBack(browser_));
1081 command_updater_.UpdateCommandEnabled(IDC_FORWARD, CanGoForward(browser_));
1082 command_updater_.UpdateCommandEnabled(IDC_RELOAD, CanReload(browser_));
1083 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE,
1084 CanReload(browser_));
1085 command_updater_.UpdateCommandEnabled(IDC_RELOAD_CLEARING_CACHE,
1086 CanReload(browser_));
1087
1088 // Window management commands
1089 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
1090 !browser_->is_app() && CanDuplicateTab(browser_));
1091
1092 // Page-related commands
1093 window()->SetStarredState(
1094 BookmarkTabHelper::FromWebContents(current_web_contents)->is_starred());
1095 window()->ZoomChangedForActiveTab(false);
1096 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
1097 CanViewSource(browser_));
1098 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
1099 CanEmailPageLocation(browser_));
1100 if (browser_->is_devtools())
1101 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
1102
1103 // Changing the encoding is not possible on Chrome-internal webpages.
1104 NavigationController& nc = current_web_contents->GetController();
1105 bool is_chrome_internal = HasInternalURL(nc.GetLastCommittedEntry()) ||
1106 current_web_contents->ShowingInterstitialPage();
1107 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
1108 !is_chrome_internal && current_web_contents->IsSavable());
1109
1110 // Show various bits of UI
1111 // TODO(pinkerton): Disable app-mode in the model until we implement it
1112 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
1113 #if !defined(OS_MACOSX)
1114 command_updater_.UpdateCommandEnabled(
1115 IDC_CREATE_SHORTCUTS,
1116 CanCreateApplicationShortcuts(browser_));
1117 command_updater_.UpdateCommandEnabled(IDC_CREATE_HOSTED_APP,
1118 CanCreateBookmarkApp(browser_));
1119 #endif
1120
1121 command_updater_.UpdateCommandEnabled(
1122 IDC_TOGGLE_REQUEST_TABLET_SITE,
1123 CanRequestTabletSite(current_web_contents));
1124
1125 UpdateCommandsForContentRestrictionState();
1126 UpdateCommandsForBookmarkEditing();
1127 UpdateCommandsForFind();
1128 // Update the zoom commands when an active tab is selected.
1129 UpdateCommandsForZoomState();
1130 }
1131
UpdateCommandsForZoomState()1132 void BrowserCommandController::UpdateCommandsForZoomState() {
1133 WebContents* contents =
1134 browser_->tab_strip_model()->GetActiveWebContents();
1135 if (!contents)
1136 return;
1137 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, CanZoomIn(contents));
1138 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, ActualSize(contents));
1139 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, CanZoomOut(contents));
1140 }
1141
UpdateCommandsForContentRestrictionState()1142 void BrowserCommandController::UpdateCommandsForContentRestrictionState() {
1143 int restrictions = GetContentRestrictions(browser_);
1144
1145 command_updater_.UpdateCommandEnabled(
1146 IDC_COPY, !(restrictions & CONTENT_RESTRICTION_COPY));
1147 command_updater_.UpdateCommandEnabled(
1148 IDC_CUT, !(restrictions & CONTENT_RESTRICTION_CUT));
1149 command_updater_.UpdateCommandEnabled(
1150 IDC_PASTE, !(restrictions & CONTENT_RESTRICTION_PASTE));
1151 UpdateSaveAsState();
1152 UpdatePrintingState();
1153 }
1154
UpdateCommandsForDevTools()1155 void BrowserCommandController::UpdateCommandsForDevTools() {
1156 bool dev_tools_enabled =
1157 !profile()->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled);
1158 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
1159 dev_tools_enabled);
1160 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
1161 dev_tools_enabled);
1162 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_DEVICES,
1163 dev_tools_enabled);
1164 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
1165 dev_tools_enabled);
1166 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_TOGGLE,
1167 dev_tools_enabled);
1168 }
1169
UpdateCommandsForBookmarkEditing()1170 void BrowserCommandController::UpdateCommandsForBookmarkEditing() {
1171 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
1172 CanBookmarkCurrentPage(browser_));
1173 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
1174 CanBookmarkAllTabs(browser_));
1175 command_updater_.UpdateCommandEnabled(IDC_PIN_TO_START_SCREEN,
1176 true);
1177 }
1178
UpdateCommandsForBookmarkBar()1179 void BrowserCommandController::UpdateCommandsForBookmarkBar() {
1180 command_updater_.UpdateCommandEnabled(
1181 IDC_SHOW_BOOKMARK_BAR,
1182 browser_defaults::bookmarks_enabled && !profile()->IsGuestSession() &&
1183 !profile()->GetPrefs()->IsManagedPreference(
1184 bookmarks::prefs::kShowBookmarkBar) &&
1185 IsShowingMainUI());
1186 }
1187
UpdateCommandsForFileSelectionDialogs()1188 void BrowserCommandController::UpdateCommandsForFileSelectionDialogs() {
1189 UpdateSaveAsState();
1190 UpdateOpenFileState(&command_updater_);
1191 }
1192
UpdateCommandsForFullscreenMode()1193 void BrowserCommandController::UpdateCommandsForFullscreenMode() {
1194 WindowState window_state = WINDOW_STATE_NOT_FULLSCREEN;
1195 if (window() && window()->IsFullscreen()) {
1196 window_state = WINDOW_STATE_FULLSCREEN;
1197 #if defined(OS_WIN)
1198 if (window()->IsInMetroSnapMode())
1199 window_state = WINDOW_STATE_METRO_SNAP;
1200 #endif
1201 }
1202 bool show_main_ui = IsShowingMainUI();
1203 bool main_not_fullscreen =
1204 show_main_ui && window_state == WINDOW_STATE_NOT_FULLSCREEN;
1205
1206 // Navigation commands
1207 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
1208
1209 // Window management commands
1210 command_updater_.UpdateCommandEnabled(
1211 IDC_SHOW_AS_TAB,
1212 !browser_->is_type_tabbed() &&
1213 window_state == WINDOW_STATE_NOT_FULLSCREEN);
1214
1215 // Focus various bits of UI
1216 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
1217 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
1218 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
1219 command_updater_.UpdateCommandEnabled(
1220 IDC_FOCUS_MENU_BAR, main_not_fullscreen);
1221 command_updater_.UpdateCommandEnabled(
1222 IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
1223 command_updater_.UpdateCommandEnabled(
1224 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
1225 command_updater_.UpdateCommandEnabled(
1226 IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
1227 command_updater_.UpdateCommandEnabled(
1228 IDC_FOCUS_INFOBARS, main_not_fullscreen);
1229
1230 // Show various bits of UI
1231 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
1232 #if defined(GOOGLE_CHROME_BUILD)
1233 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
1234 #endif
1235 UpdateShowSyncState(show_main_ui);
1236
1237 // Settings page/subpages are forced to open in normal mode. We disable these
1238 // commands for guest sessions and when incognito is forced.
1239 const bool options_enabled = show_main_ui &&
1240 IncognitoModePrefs::GetAvailability(
1241 profile()->GetPrefs()) != IncognitoModePrefs::FORCED;
1242 const bool guest_session = profile()->IsGuestSession();
1243 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled);
1244 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS,
1245 options_enabled && !guest_session);
1246
1247 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
1248 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
1249 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
1250 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
1251 #if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
1252 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
1253 #endif
1254
1255 // Disable explicit fullscreen toggling when in metro snap mode.
1256 bool fullscreen_enabled = window_state != WINDOW_STATE_METRO_SNAP;
1257 #if !defined(OS_MACOSX)
1258 if (window_state == WINDOW_STATE_NOT_FULLSCREEN &&
1259 !profile()->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed)) {
1260 // Disable toggling into fullscreen mode if disallowed by pref.
1261 fullscreen_enabled = false;
1262 }
1263 #endif
1264
1265 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN, fullscreen_enabled);
1266 command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE,
1267 fullscreen_enabled);
1268
1269 UpdateCommandsForBookmarkBar();
1270 }
1271
UpdatePrintingState()1272 void BrowserCommandController::UpdatePrintingState() {
1273 bool print_enabled = CanPrint(browser_);
1274 command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled);
1275 #if !defined(DISABLE_BASIC_PRINTING)
1276 command_updater_.UpdateCommandEnabled(IDC_BASIC_PRINT,
1277 CanBasicPrint(browser_));
1278 #endif // !DISABLE_BASIC_PRINTING
1279 }
1280
UpdateSaveAsState()1281 void BrowserCommandController::UpdateSaveAsState() {
1282 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, CanSavePage(browser_));
1283 }
1284
UpdateShowSyncState(bool show_main_ui)1285 void BrowserCommandController::UpdateShowSyncState(bool show_main_ui) {
1286 command_updater_.UpdateCommandEnabled(
1287 IDC_SHOW_SYNC_SETUP, show_main_ui && pref_signin_allowed_.GetValue());
1288 }
1289
1290 // static
UpdateOpenFileState(CommandUpdater * command_updater)1291 void BrowserCommandController::UpdateOpenFileState(
1292 CommandUpdater* command_updater) {
1293 bool enabled = true;
1294 PrefService* local_state = g_browser_process->local_state();
1295 if (local_state)
1296 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs);
1297
1298 command_updater->UpdateCommandEnabled(IDC_OPEN_FILE, enabled);
1299 }
1300
UpdateReloadStopState(bool is_loading,bool force)1301 void BrowserCommandController::UpdateReloadStopState(bool is_loading,
1302 bool force) {
1303 window()->UpdateReloadStopState(is_loading, force);
1304 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
1305 }
1306
UpdateTabRestoreCommandState()1307 void BrowserCommandController::UpdateTabRestoreCommandState() {
1308 TabRestoreService* tab_restore_service =
1309 TabRestoreServiceFactory::GetForProfile(profile());
1310 // The command is enabled if the service hasn't loaded yet to trigger loading.
1311 // The command is updated once the load completes.
1312 command_updater_.UpdateCommandEnabled(
1313 IDC_RESTORE_TAB,
1314 tab_restore_service &&
1315 (!tab_restore_service->IsLoaded() ||
1316 GetRestoreTabType(browser_) != TabStripModelDelegate::RESTORE_NONE));
1317 }
1318
UpdateCommandsForFind()1319 void BrowserCommandController::UpdateCommandsForFind() {
1320 TabStripModel* model = browser_->tab_strip_model();
1321 bool enabled = !model->IsTabBlocked(model->active_index()) &&
1322 !browser_->is_devtools();
1323
1324 command_updater_.UpdateCommandEnabled(IDC_FIND, enabled);
1325 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, enabled);
1326 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, enabled);
1327 }
1328
AddInterstitialObservers(WebContents * contents)1329 void BrowserCommandController::AddInterstitialObservers(WebContents* contents) {
1330 interstitial_observers_.push_back(new InterstitialObserver(this, contents));
1331 }
1332
RemoveInterstitialObservers(WebContents * contents)1333 void BrowserCommandController::RemoveInterstitialObservers(
1334 WebContents* contents) {
1335 for (size_t i = 0; i < interstitial_observers_.size(); i++) {
1336 if (interstitial_observers_[i]->web_contents() != contents)
1337 continue;
1338
1339 delete interstitial_observers_[i];
1340 interstitial_observers_.erase(interstitial_observers_.begin() + i);
1341 return;
1342 }
1343 }
1344
window()1345 BrowserWindow* BrowserCommandController::window() {
1346 return browser_->window();
1347 }
1348
profile()1349 Profile* BrowserCommandController::profile() {
1350 return browser_->profile();
1351 }
1352
1353 } // namespace chrome
1354