Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / browser_command_controller.cc
index 2704f1d..4e6c9e1 100644 (file)
@@ -4,15 +4,16 @@
 
 #include "chrome/browser/ui/browser_command_controller.h"
 
+#include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
-#include "chrome/browser/profiles/avatar_menu.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/sessions/tab_restore_service.h"
@@ -29,6 +30,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_utils.h"
 #include "chrome/browser/ui/webui/inspect_ui.h"
+#include "chrome/common/chrome_switches.h"
 #include "chrome/common/content_restriction.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/profiling.h"
@@ -39,6 +41,7 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/url_constants.h"
+#include "extensions/browser/extension_system.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
 #if defined(OS_MACOSX)
 
 #if defined(OS_CHROMEOS)
 #include "ash/multi_profile_uma.h"
-#include "ash/session_state_delegate.h"
+#include "ash/session/session_state_delegate.h"
 #include "ash/shell.h"
-#include "chrome/browser/ui/ash/multi_user_window_manager.h"
+#include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h"
+#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
+#include "chrome/browser/ui/browser_commands_chromeos.h"
+#endif
+
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
 #endif
 
 using content::NavigationEntry;
@@ -89,13 +98,13 @@ bool HasInternalURL(const NavigationEntry* entry) {
 
   // Check the |virtual_url()| first. This catches regular chrome:// URLs
   // including URLs that were rewritten (such as chrome://bookmarks).
-  if (entry->GetVirtualURL().SchemeIs(chrome::kChromeUIScheme))
+  if (entry->GetVirtualURL().SchemeIs(content::kChromeUIScheme))
     return true;
 
   // If the |virtual_url()| isn't a chrome:// URL, check if it's actually
   // view-source: of a chrome:// URL.
   if (entry->GetVirtualURL().SchemeIs(content::kViewSourceScheme))
-    return entry->GetURL().SchemeIs(chrome::kChromeUIScheme);
+    return entry->GetURL().SchemeIs(content::kChromeUIScheme);
 
   return false;
 }
@@ -175,17 +184,12 @@ namespace chrome {
 ///////////////////////////////////////////////////////////////////////////////
 // BrowserCommandController, public:
 
-BrowserCommandController::BrowserCommandController(
-    Browser* browser,
-    ProfileManager* profile_manager)
+BrowserCommandController::BrowserCommandController(Browser* browser)
     : browser_(browser),
-      profile_manager_(profile_manager),
       command_updater_(this),
       block_command_execution_(false),
       last_blocked_command_id_(-1),
       last_blocked_command_disposition_(CURRENT_TAB) {
-  if (profile_manager_)
-    profile_manager_->GetProfileInfoCache().AddObserver(this);
   browser_->tab_strip_model()->AddObserver(this);
   PrefService* local_state = g_browser_process->local_state();
   if (local_state) {
@@ -203,11 +207,11 @@ BrowserCommandController::BrowserCommandController(
       base::Bind(&BrowserCommandController::UpdateCommandsForDevTools,
                  base::Unretained(this)));
   profile_pref_registrar_.Add(
-      prefs::kEditBookmarksEnabled,
+      bookmarks::prefs::kEditBookmarksEnabled,
       base::Bind(&BrowserCommandController::UpdateCommandsForBookmarkEditing,
                  base::Unretained(this)));
   profile_pref_registrar_.Add(
-      prefs::kShowBookmarkBar,
+      bookmarks::prefs::kShowBookmarkBar,
       base::Bind(&BrowserCommandController::UpdateCommandsForBookmarkBar,
                  base::Unretained(this)));
   profile_pref_registrar_.Add(
@@ -251,8 +255,6 @@ BrowserCommandController::~BrowserCommandController() {
   profile_pref_registrar_.RemoveAll();
   local_pref_registrar_.RemoveAll();
   browser_->tab_strip_model()->RemoveObserver(this);
-  if (profile_manager_)
-    profile_manager_->GetProfileInfoCache().RemoveObserver(this);
 }
 
 bool BrowserCommandController::IsReservedCommandOrKey(
@@ -278,6 +280,16 @@ bool BrowserCommandController::IsReservedCommandOrKey(
 
   if (window()->IsFullscreen() && command_id == IDC_FULLSCREEN)
     return true;
+
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  // If this key was registered by the user as a content editing hotkey, then
+  // it is not reserved.
+  ui::TextEditKeyBindingsDelegateAuraLinux* delegate =
+      ui::GetTextEditKeyBindingsDelegate();
+  if (delegate && event.os_event && delegate->MatchEvent(*event.os_event, NULL))
+    return false;
+#endif
+
   return command_id == IDC_CLOSE_TAB ||
          command_id == IDC_CLOSE_WINDOW ||
          command_id == IDC_NEW_INCOGNITO_WINDOW ||
@@ -286,7 +298,6 @@ bool BrowserCommandController::IsReservedCommandOrKey(
          command_id == IDC_RESTORE_TAB ||
          command_id == IDC_SELECT_NEXT_TAB ||
          command_id == IDC_SELECT_PREVIOUS_TAB ||
-         command_id == IDC_TABPOSE ||
          command_id == IDC_EXIT;
 }
 
@@ -309,6 +320,10 @@ void BrowserCommandController::TabStateChanged() {
   UpdateCommandsForTabState();
 }
 
+void BrowserCommandController::ZoomStateChanged() {
+  UpdateCommandsForZoomState();
+}
+
 void BrowserCommandController::ContentRestrictionsChanged() {
   UpdateCommandsForContentRestrictionState();
 }
@@ -392,28 +407,25 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
       NewIncognitoWindow(browser_);
       break;
     case IDC_CLOSE_WINDOW:
-      content::RecordAction(content::UserMetricsAction("CloseWindowByKey"));
+      content::RecordAction(base::UserMetricsAction("CloseWindowByKey"));
       CloseWindow(browser_);
       break;
     case IDC_NEW_TAB:
       NewTab(browser_);
       break;
     case IDC_CLOSE_TAB:
-      content::RecordAction(content::UserMetricsAction("CloseTabByKey"));
+      content::RecordAction(base::UserMetricsAction("CloseTabByKey"));
       CloseTab(browser_);
       break;
     case IDC_SELECT_NEXT_TAB:
-      content::RecordAction(content::UserMetricsAction("Accel_SelectNextTab"));
+      content::RecordAction(base::UserMetricsAction("Accel_SelectNextTab"));
       SelectNextTab(browser_);
       break;
     case IDC_SELECT_PREVIOUS_TAB:
       content::RecordAction(
-          content::UserMetricsAction("Accel_SelectPreviousTab"));
+          base::UserMetricsAction("Accel_SelectPreviousTab"));
       SelectPreviousTab(browser_);
       break;
-    case IDC_TABPOSE:
-      OpenTabpose(browser_);
-      break;
     case IDC_MOVE_TAB_NEXT:
       MoveTabNext(browser_);
       break;
@@ -450,32 +462,20 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
 #endif
       break;
 
-#if defined(USE_ASH)
-    case IDC_TOGGLE_ASH_DESKTOP:
-      chrome::ToggleAshDesktop();
-      break;
-    case IDC_MINIMIZE_WINDOW:
-      ash::accelerators::ToggleMinimized();
+#if defined(OS_CHROMEOS)
+    case IDC_VISIT_DESKTOP_OF_LRU_USER_2:
+    case IDC_VISIT_DESKTOP_OF_LRU_USER_3:
+      ExecuteVisitDesktopCommand(id, browser_->window()->GetNativeWindow());
       break;
-    // If Ash needs many more commands here we should implement a general
-    // mechanism to pass accelerators back into Ash. http://crbug.com/285308
 #endif
 
-#if defined(OS_CHROMEOS)
-    case IDC_VISIT_DESKTOP_OF_LRU_USER_2:
-    case IDC_VISIT_DESKTOP_OF_LRU_USER_3: {
-        ash::MultiProfileUMA::RecordTeleportAction(
-            ash::MultiProfileUMA::TELEPORT_WINDOW_CAPTION_MENU);
-        // When running the multi user mode on Chrome OS, windows can "visit"
-        // another user's desktop.
-        const std::string& user_id =
-            ash::Shell::GetInstance()->session_state_delegate()->GetUserID(
-                IDC_VISIT_DESKTOP_OF_LRU_USER_2 == id ? 1 : 2);
-        chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser(
-            browser_->window()->GetNativeWindow(),
-            user_id);
-        break;
-      }
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+    case IDC_USE_SYSTEM_TITLE_BAR: {
+      PrefService* prefs = browser_->profile()->GetPrefs();
+      prefs->SetBoolean(prefs::kUseCustomChromeFrame,
+                        !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
+      break;
+    }
 #endif
 
 #if defined(OS_WIN)
@@ -486,20 +486,29 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
     case IDC_METRO_SNAP_DISABLE:
       browser_->SetMetroSnapMode(false);
       break;
-    case IDC_WIN8_DESKTOP_RESTART:
-      if (!VerifyMetroSwitchForApps(window()->GetNativeWindow(), id))
+    case IDC_WIN_DESKTOP_RESTART:
+      if (!VerifyASHSwitchForApps(window()->GetNativeWindow(), id))
         break;
 
       chrome::AttemptRestartToDesktopMode();
-      content::RecordAction(content::UserMetricsAction("Win8DesktopRestart"));
+      if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
+        content::RecordAction(base::UserMetricsAction("Win8DesktopRestart"));
+      } else {
+        content::RecordAction(base::UserMetricsAction("Win7DesktopRestart"));
+      }
       break;
     case IDC_WIN8_METRO_RESTART:
-      if (!VerifyMetroSwitchForApps(window()->GetNativeWindow(), id))
+    case IDC_WIN_CHROMEOS_RESTART:
+      if (!VerifyASHSwitchForApps(window()->GetNativeWindow(), id))
         break;
-
-      // SwitchToMetroUIHandler deletes itself.
-      new SwitchToMetroUIHandler;
-      content::RecordAction(content::UserMetricsAction("Win8MetroRestart"));
+      if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
+        // SwitchToMetroUIHandler deletes itself.
+        new SwitchToMetroUIHandler;
+        content::RecordAction(base::UserMetricsAction("Win8MetroRestart"));
+      } else {
+        content::RecordAction(base::UserMetricsAction("Win7ASHRestart"));
+        chrome::AttemptRestartToMetroMode();
+      }
       break;
 #endif
 
@@ -519,9 +528,6 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
     case IDC_BOOKMARK_PAGE:
       BookmarkCurrentPage(browser_);
       break;
-    case IDC_BOOKMARK_PAGE_FROM_STAR:
-      BookmarkCurrentPageFromStar(browser_);
-      break;
     case IDC_PIN_TO_START_SCREEN:
       TogglePagePinnedToStartScreen(browser_);
       break;
@@ -537,15 +543,20 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
     case IDC_PRINT:
       Print(browser_);
       break;
-    case IDC_ADVANCED_PRINT:
-      AdvancedPrint(browser_);
-      break;
-    case IDC_PRINT_TO_DESTINATION:
-      PrintToDestination(browser_);
+#if !defined(DISABLE_BASIC_PRINTING)
+    case IDC_BASIC_PRINT:
+      content::RecordAction(base::UserMetricsAction("Accel_Advanced_Print"));
+      BasicPrint(browser_);
       break;
+#endif  // !DISABLE_BASIC_PRINTING
     case IDC_TRANSLATE_PAGE:
       Translate(browser_);
       break;
+    case IDC_MANAGE_PASSWORDS_FOR_PAGE:
+      ManagePasswordsForPage(browser_);
+      break;
+
+    // Page encoding commands
     case IDC_ENCODING_AUTO_DETECT:
       browser_->ToggleEncodingAutoDetect();
       break;
@@ -624,18 +635,23 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
 
     // Focus various bits of UI
     case IDC_FOCUS_TOOLBAR:
+      content::RecordAction(base::UserMetricsAction("Accel_Focus_Toolbar"));
       FocusToolbar(browser_);
       break;
     case IDC_FOCUS_LOCATION:
+      content::RecordAction(base::UserMetricsAction("Accel_Focus_Location"));
       FocusLocationBar(browser_);
       break;
     case IDC_FOCUS_SEARCH:
+      content::RecordAction(base::UserMetricsAction("Accel_Focus_Search"));
       FocusSearch(browser_);
       break;
     case IDC_FOCUS_MENU_BAR:
       FocusAppMenu(browser_);
       break;
     case IDC_FOCUS_BOOKMARKS:
+      content::RecordAction(
+          base::UserMetricsAction("Accel_Focus_Bookmarks"));
       FocusBookmarksToolbar(browser_);
       break;
     case IDC_FOCUS_INFOBARS:
@@ -655,6 +671,9 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
     case IDC_CREATE_SHORTCUTS:
       CreateApplicationShortcuts(browser_);
       break;
+    case IDC_CREATE_HOSTED_APP:
+      CreateBookmarkAppFromCurrentWebContents(browser_);
+      break;
     case IDC_DEV_TOOLS:
       ToggleDevToolsWindow(browser_, DevToolsToggleAction::Show());
       break;
@@ -673,6 +692,11 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
     case IDC_TASK_MANAGER:
       OpenTaskManager(browser_);
       break;
+#if defined(OS_CHROMEOS)
+    case IDC_TAKE_SCREENSHOT:
+      TakeScreenshot();
+      break;
+#endif
 #if defined(GOOGLE_CHROME_BUILD)
     case IDC_FEEDBACK:
       OpenFeedbackDialog(browser_);
@@ -689,6 +713,7 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
       ShowBookmarkManager(browser_);
       break;
     case IDC_SHOW_APP_MENU:
+      content::RecordAction(base::UserMetricsAction("Accel_Show_App_Menu"));
       ShowAppMenu(browser_);
       break;
     case IDC_SHOW_AVATAR_MENU:
@@ -742,6 +767,9 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
     case IDC_TOGGLE_SPEECH_INPUT:
       ToggleSpeechInput(browser_);
       break;
+    case IDC_DISTILL_PAGE:
+      DistillCurrentPage(browser_);
+      break;
 
     default:
       LOG(WARNING) << "Received Unimplemented Command: " << id;
@@ -750,20 +778,6 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// BrowserCommandController, ProfileInfoCacheObserver implementation:
-
-void BrowserCommandController::OnProfileAdded(
-    const base::FilePath& profile_path) {
-  UpdateCommandsForMultipleProfiles();
-}
-
-void BrowserCommandController::OnProfileWasRemoved(
-    const base::FilePath& profile_path,
-    const string16& profile_name) {
-  UpdateCommandsForMultipleProfiles();
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // BrowserCommandController, SigninPrefObserver implementation:
 
 void BrowserCommandController::OnSigninAllowedPrefChange() {
@@ -806,9 +820,7 @@ void BrowserCommandController::TabBlockedStateChanged(
 
 void BrowserCommandController::TabRestoreServiceChanged(
     TabRestoreService* service) {
-  command_updater_.UpdateCommandEnabled(
-      IDC_RESTORE_TAB,
-      GetRestoreTabType(browser_) != TabStripModelDelegate::RESTORE_NONE);
+  UpdateTabRestoreCommandState();
 }
 
 void BrowserCommandController::TabRestoreServiceDestroyed(
@@ -816,6 +828,11 @@ void BrowserCommandController::TabRestoreServiceDestroyed(
   service->RemoveObserver(this);
 }
 
+void BrowserCommandController::TabRestoreServiceLoaded(
+    TabRestoreService* service) {
+  UpdateTabRestoreCommandState();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // BrowserCommandController, private:
 
@@ -828,8 +845,6 @@ class BrowserCommandController::InterstitialObserver
         controller_(controller) {
   }
 
-  using content::WebContentsObserver::web_contents;
-
   virtual void DidAttachInterstitialPage() OVERRIDE {
     controller_->UpdateCommandsForTabState();
   }
@@ -864,7 +879,7 @@ void BrowserCommandController::InitCommandState() {
   command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
   command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
   command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
-  command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
+  UpdateTabRestoreCommandState();
 #if defined(OS_WIN) && defined(USE_ASH)
   if (browser_->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH)
     command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
@@ -872,11 +887,6 @@ void BrowserCommandController::InitCommandState() {
   command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
 #endif
   command_updater_.UpdateCommandEnabled(IDC_DEBUG_FRAME_TOGGLE, true);
-#if defined(OS_WIN) && defined(USE_ASH) && !defined(NDEBUG)
-  if (base::win::GetVersion() < base::win::VERSION_WIN8 &&
-      chrome::HOST_DESKTOP_TYPE_NATIVE != chrome::HOST_DESKTOP_TYPE_ASH)
-    command_updater_.UpdateCommandEnabled(IDC_TOGGLE_ASH_DESKTOP, true);
-#endif
 #if defined(USE_ASH)
   command_updater_.UpdateCommandEnabled(IDC_MINIMIZE_WINDOW, true);
 #endif
@@ -884,9 +894,13 @@ void BrowserCommandController::InitCommandState() {
   command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_2, true);
   command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_3, true);
 #endif
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  command_updater_.UpdateCommandEnabled(IDC_USE_SYSTEM_TITLE_BAR, true);
+#endif
 
   // Page-related commands
   command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
+  command_updater_.UpdateCommandEnabled(IDC_MANAGE_PASSWORDS_FOR_PAGE, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
@@ -929,32 +943,41 @@ void BrowserCommandController::InitCommandState() {
   // Zoom
   command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
   command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
-  command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
+  command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, false);
   command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
 
   // Show various bits of UI
+  const bool guest_session = profile()->IsGuestSession();
+  const bool normal_window = browser_->is_type_tabbed();
   UpdateOpenFileState(&command_updater_);
   command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
   UpdateCommandsForDevTools();
   command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, CanOpenTaskManager());
-  command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY,
-                                        !profile()->IsGuestSession());
+  command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, !guest_session);
   command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
+  command_updater_.UpdateCommandEnabled(IDC_HELP_MENU, true);
   command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_KEYBOARD, true);
   command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_MENU, true);
-  command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU,
-                                        !profile()->IsGuestSession());
+  command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, !guest_session);
   command_updater_.UpdateCommandEnabled(IDC_RECENT_TABS_MENU,
-                                        !profile()->IsGuestSession() &&
+                                        !guest_session &&
                                         !profile()->IsOffTheRecord());
+  command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
+#if defined(OS_CHROMEOS)
+  command_updater_.UpdateCommandEnabled(IDC_TAKE_SCREENSHOT, true);
+#else
+  // Chrome OS uses the system tray menu to handle multi-profiles.
+  if (normal_window && (guest_session || !profile()->IsOffTheRecord()))
+    command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU, true);
+#endif
 
   UpdateShowSyncState(true);
 
-  // Initialize other commands based on the window type.
-  bool normal_window = browser_->is_type_tabbed();
-
   // Navigation commands
-  command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
+  command_updater_.UpdateCommandEnabled(
+      IDC_HOME,
+      normal_window || (extensions::util::IsStreamlinedHostedAppsEnabled() &&
+                        browser_->is_app()));
 
   // Window management commands
   command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
@@ -972,40 +995,32 @@ void BrowserCommandController::InitCommandState() {
   command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
   command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
 #if defined(OS_WIN)
-#if !defined(USE_AURA)
-  const bool metro_mode = base::win::IsMetroProcess();
-#else
-  const bool metro_mode =
-     browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH ?
-         true : false;
-#endif
-  command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_ENABLE, metro_mode);
-  command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_DISABLE, metro_mode);
-  int restart_mode = metro_mode ?
-      IDC_WIN8_DESKTOP_RESTART : IDC_WIN8_METRO_RESTART;
+  bool metro = browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH;
+  command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_ENABLE, metro);
+  command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_DISABLE, metro);
+  int restart_mode = metro ? IDC_WIN_DESKTOP_RESTART :
+      (base::win::GetVersion() >= base::win::VERSION_WIN8 ?
+          IDC_WIN8_METRO_RESTART : IDC_WIN_CHROMEOS_RESTART);
   command_updater_.UpdateCommandEnabled(restart_mode, normal_window);
 #endif
-  command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
 
-  // Show various bits of UI
-  command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
-
-  // The upgrade entry and the view incompatibility entry should always be
-  // enabled. Whether they are visible is a separate matter determined on menu
-  // show.
+  // These are always enabled; the menu determines their menu item visibility.
   command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
   command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
 
   // Toggle speech input
   command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true);
 
-  // Initialize other commands whose state changes based on fullscreen mode.
-  UpdateCommandsForFullscreenMode();
+  // Distill current page.
+  command_updater_.UpdateCommandEnabled(
+      IDC_DISTILL_PAGE,
+      CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableDomDistiller));
 
+  // Initialize other commands whose state changes based on various conditions.
+  UpdateCommandsForFullscreenMode();
   UpdateCommandsForContentRestrictionState();
-
   UpdateCommandsForBookmarkEditing();
-
   UpdateCommandsForIncognitoAvailability();
 }
 
@@ -1013,6 +1028,8 @@ void BrowserCommandController::InitCommandState() {
 void BrowserCommandController::UpdateSharedCommandsForIncognitoAvailability(
     CommandUpdater* command_updater,
     Profile* profile) {
+  const bool guest_session = profile->IsGuestSession();
+  // TODO(mlerman): Make GetAvailability account for profile->IsGuestSession().
   IncognitoModePrefs::Availability incognito_availability =
       IncognitoModePrefs::GetAvailability(profile->GetPrefs());
   command_updater->UpdateCommandEnabled(
@@ -1020,24 +1037,28 @@ void BrowserCommandController::UpdateSharedCommandsForIncognitoAvailability(
       incognito_availability != IncognitoModePrefs::FORCED);
   command_updater->UpdateCommandEnabled(
       IDC_NEW_INCOGNITO_WINDOW,
-      incognito_availability != IncognitoModePrefs::DISABLED);
+      incognito_availability != IncognitoModePrefs::DISABLED && !guest_session);
 
-  // Bookmark manager and settings page/subpages are forced to open in normal
-  // mode. For this reason we disable these commands when incognito is forced.
-  const bool command_enabled =
-      incognito_availability != IncognitoModePrefs::FORCED;
+  const bool forced_incognito =
+      incognito_availability == IncognitoModePrefs::FORCED ||
+      guest_session;  // Guest always runs in Incognito mode.
   command_updater->UpdateCommandEnabled(
       IDC_SHOW_BOOKMARK_MANAGER,
-      browser_defaults::bookmarks_enabled && command_enabled);
-  ExtensionService* extension_service = profile->GetExtensionService();
-  bool enable_extensions =
+      browser_defaults::bookmarks_enabled && !forced_incognito);
+  ExtensionService* extension_service =
+      extensions::ExtensionSystem::Get(profile)->extension_service();
+  const bool enable_extensions =
       extension_service && extension_service->extensions_enabled();
+
+  // Bookmark manager and settings page/subpages are forced to open in normal
+  // mode. For this reason we disable these commands when incognito is forced.
   command_updater->UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
-                                        enable_extensions && command_enabled);
+                                        enable_extensions && !forced_incognito);
 
-  command_updater->UpdateCommandEnabled(IDC_IMPORT_SETTINGS, command_enabled);
-  command_updater->UpdateCommandEnabled(IDC_OPTIONS, command_enabled);
-  command_updater->UpdateCommandEnabled(IDC_SHOW_SIGNIN, command_enabled);
+  command_updater->UpdateCommandEnabled(IDC_IMPORT_SETTINGS, !forced_incognito);
+  command_updater->UpdateCommandEnabled(IDC_OPTIONS,
+                                        !forced_incognito || guest_session);
+  command_updater->UpdateCommandEnabled(IDC_SHOW_SIGNIN, !forced_incognito);
 }
 
 void BrowserCommandController::UpdateCommandsForIncognitoAvailability() {
@@ -1081,7 +1102,7 @@ void BrowserCommandController::UpdateCommandsForTabState() {
 
   // Changing the encoding is not possible on Chrome-internal webpages.
   NavigationController& nc = current_web_contents->GetController();
-  bool is_chrome_internal = HasInternalURL(nc.GetActiveEntry()) ||
+  bool is_chrome_internal = HasInternalURL(nc.GetLastCommittedEntry()) ||
       current_web_contents->ShowingInterstitialPage();
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
       !is_chrome_internal && current_web_contents->IsSavable());
@@ -1093,6 +1114,8 @@ void BrowserCommandController::UpdateCommandsForTabState() {
   command_updater_.UpdateCommandEnabled(
       IDC_CREATE_SHORTCUTS,
       CanCreateApplicationShortcuts(browser_));
+  command_updater_.UpdateCommandEnabled(IDC_CREATE_HOSTED_APP,
+                                        CanCreateBookmarkApp(browser_));
 #endif
 
   command_updater_.UpdateCommandEnabled(
@@ -1102,6 +1125,18 @@ void BrowserCommandController::UpdateCommandsForTabState() {
   UpdateCommandsForContentRestrictionState();
   UpdateCommandsForBookmarkEditing();
   UpdateCommandsForFind();
+  // Update the zoom commands when an active tab is selected.
+  UpdateCommandsForZoomState();
+}
+
+void BrowserCommandController::UpdateCommandsForZoomState() {
+  WebContents* contents =
+      browser_->tab_strip_model()->GetActiveWebContents();
+  if (!contents)
+    return;
+  command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, CanZoomIn(contents));
+  command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, ActualSize(contents));
+  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, CanZoomOut(contents));
 }
 
 void BrowserCommandController::UpdateCommandsForContentRestrictionState() {
@@ -1142,10 +1177,12 @@ void BrowserCommandController::UpdateCommandsForBookmarkEditing() {
 }
 
 void BrowserCommandController::UpdateCommandsForBookmarkBar() {
-  command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
-      browser_defaults::bookmarks_enabled &&
-      !profile()->GetPrefs()->IsManagedPreference(prefs::kShowBookmarkBar) &&
-      IsShowingMainUI());
+  command_updater_.UpdateCommandEnabled(
+      IDC_SHOW_BOOKMARK_BAR,
+      browser_defaults::bookmarks_enabled && !profile()->IsGuestSession() &&
+          !profile()->GetPrefs()->IsManagedPreference(
+              bookmarks::prefs::kShowBookmarkBar) &&
+          IsShowingMainUI());
 }
 
 void BrowserCommandController::UpdateCommandsForFileSelectionDialogs() {
@@ -1198,12 +1235,14 @@ void BrowserCommandController::UpdateCommandsForFullscreenMode() {
   UpdateShowSyncState(show_main_ui);
 
   // Settings page/subpages are forced to open in normal mode. We disable these
-  // commands when incognito is forced.
+  // commands for guest sessions and when incognito is forced.
   const bool options_enabled = show_main_ui &&
       IncognitoModePrefs::GetAvailability(
           profile()->GetPrefs()) != IncognitoModePrefs::FORCED;
+  const bool guest_session = profile()->IsGuestSession();
   command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled);
-  command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, options_enabled);
+  command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS,
+                                        options_enabled && !guest_session);
 
   command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
   command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
@@ -1215,13 +1254,7 @@ void BrowserCommandController::UpdateCommandsForFullscreenMode() {
 
   // Disable explicit fullscreen toggling when in metro snap mode.
   bool fullscreen_enabled = window_state != WINDOW_STATE_METRO_SNAP;
-#if defined(OS_MACOSX)
-  // The Mac implementation doesn't support switching to fullscreen while
-  // a tab modal dialog is displayed.
-  int tab_index = chrome::IndexOfFirstBlockedTab(browser_->tab_strip_model());
-  bool has_blocked_tab = tab_index != browser_->tab_strip_model()->count();
-  fullscreen_enabled &= !has_blocked_tab;
-#else
+#if !defined(OS_MACOSX)
   if (window_state == WINDOW_STATE_NOT_FULLSCREEN &&
       !profile()->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed)) {
     // Disable toggling into fullscreen mode if disallowed by pref.
@@ -1234,36 +1267,15 @@ void BrowserCommandController::UpdateCommandsForFullscreenMode() {
                                         fullscreen_enabled);
 
   UpdateCommandsForBookmarkBar();
-  UpdateCommandsForMultipleProfiles();
-}
-
-void BrowserCommandController::UpdateCommandsForMultipleProfiles() {
-  bool enable = IsShowingMainUI() &&
-      !profile()->IsOffTheRecord() &&
-      profile_manager_ &&
-      AvatarMenu::ShouldShowAvatarMenu();
-  command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU,
-                                        enable);
 }
 
 void BrowserCommandController::UpdatePrintingState() {
   bool print_enabled = CanPrint(browser_);
   command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled);
-  command_updater_.UpdateCommandEnabled(IDC_ADVANCED_PRINT,
-                                        CanAdvancedPrint(browser_));
-  command_updater_.UpdateCommandEnabled(IDC_PRINT_TO_DESTINATION,
-                                        print_enabled);
-#if defined(OS_WIN)
-  HMODULE metro_module = base::win::GetMetroModule();
-  if (metro_module != NULL) {
-    typedef void (*MetroEnablePrinting)(BOOL);
-    MetroEnablePrinting metro_enable_printing =
-        reinterpret_cast<MetroEnablePrinting>(
-            ::GetProcAddress(metro_module, "MetroEnablePrinting"));
-    if (metro_enable_printing)
-      metro_enable_printing(print_enabled);
-  }
-#endif
+#if !defined(DISABLE_BASIC_PRINTING)
+  command_updater_.UpdateCommandEnabled(IDC_BASIC_PRINT,
+                                        CanBasicPrint(browser_));
+#endif  // !DISABLE_BASIC_PRINTING
 }
 
 void BrowserCommandController::UpdateSaveAsState() {
@@ -1292,6 +1304,18 @@ void BrowserCommandController::UpdateReloadStopState(bool is_loading,
   command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
 }
 
+void BrowserCommandController::UpdateTabRestoreCommandState() {
+  TabRestoreService* tab_restore_service =
+      TabRestoreServiceFactory::GetForProfile(profile());
+  // The command is enabled if the service hasn't loaded yet to trigger loading.
+  // The command is updated once the load completes.
+  command_updater_.UpdateCommandEnabled(
+      IDC_RESTORE_TAB,
+      tab_restore_service &&
+      (!tab_restore_service->IsLoaded() ||
+       GetRestoreTabType(browser_) != TabStripModelDelegate::RESTORE_NONE));
+}
+
 void BrowserCommandController::UpdateCommandsForFind() {
   TabStripModel* model = browser_->tab_strip_model();
   bool enabled = !model->IsTabBlocked(model->active_index()) &&