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