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