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