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