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