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