12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_utils.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browsing_data/browsing_data_helper.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browsing_data/browsing_data_remover.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chrome_page_zoom.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/devtools/devtools_window.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_tab_helper.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/google/google_util.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/platform_util.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/incognito_mode_prefs.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/rlz/rlz.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_service_factory.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service_delegate.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service_factory.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_command_controller.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_instant_controller.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/chrome_pages.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_bar_controller.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_tab_helper.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/location_bar.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/status_bubble.h"
49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
51558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/upgrade_detector.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/chrome_version_info.h"
56ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/common/content_restriction.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/web_modal/web_contents_modal_dialog_manager.h"
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_agent_host.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_service.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/page_navigator.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/renderer_preferences.h"
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/url_constants.h"
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/url_utils.h"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/user_agent/user_agent_util.h"
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/cocoa/find_pasteboard.h"
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/metro_pin_tab_helper_win.h"
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "win8/util/win8_util.h"
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#if defined(ENABLE_PRINTING)
84a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#if defined(ENABLE_FULL_PRINTING)
85a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#include "chrome/browser/printing/print_preview_dialog_controller.h"
86a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#include "chrome/browser/printing/print_view_manager.h"
87a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#else
88a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#include "chrome/browser/printing/print_view_manager_basic.h"
89a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#endif  // defined(ENABLE_FULL_PRINTING)
90a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#endif  // defined(ENABLE_PRINTING)
91a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOsOverrideForTabletSite[] = "Linux; Android 4.0.3";
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::OpenURLParams;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::Referrer;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::SSLStatus;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UserMetricsAction;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using web_modal::WebContentsModalDialogManager;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkCurrentPageInternal(Browser* browser, bool from_star) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Star"));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkModel* model =
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BookmarkModelFactory::GetForProfile(browser->profile());
113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (!model || !model->loaded())
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // Ignore requests until bookmarks are loaded.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 title;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* web_contents =
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetActiveWebContents();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetURLAndTitleToBookmark(web_contents, &url, &title);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool was_bookmarked = model->IsBookmarked(url);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!was_bookmarked && web_contents->GetBrowserContext()->IsOffTheRecord()) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we're incognito the favicon may not have been saved. Save it now
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // so that bookmarks have an icon for the page.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FaviconTabHelper::FromWebContents(web_contents)->SaveFavicon();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_utils::AddIfNotBookmarked(model, url, title);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (from_star && !was_bookmarked)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BookmarkPromptController::AddedBookmark(browser, url);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the model actually added a bookmark before showing the star. A
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bookmark isn't created if the url is invalid.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser->window()->IsActive() && model->IsBookmarked(url)) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only show the bubble if the window is active, otherwise we may get into
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // weird situations where the bubble is deleted as soon as it is shown.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    browser->window()->ShowBookmarkBubble(url, was_bookmarked);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebContents* GetOrCloneTabForDisposition(Browser* browser,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         WindowOpenDisposition disposition) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (disposition) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_FOREGROUND_TAB:
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_BACKGROUND_TAB: {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      current_tab = current_tab->Clone();
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->AddWebContents(
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          current_tab, -1, content::PAGE_TRANSITION_LINK,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              TabStripModel::ADD_NONE);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_WINDOW: {
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      current_tab = current_tab->Clone();
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Browser* b = new Browser(Browser::CreateParams(
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          browser->profile(), browser->host_desktop_type()));
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      b->tab_strip_model()->AddWebContents(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          current_tab, -1, content::PAGE_TRANSITION_LINK,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          TabStripModel::ADD_ACTIVE);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      b->window()->Show();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return current_tab;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReloadInternal(Browser* browser,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    WindowOpenDisposition disposition,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    bool ignore_cache) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As this is caused by a user action, give the focus to the page.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also notify RenderViewHostDelegate of the user gesture; this is
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // normally done in Browser::Navigate, but a reload bypasses Navigate.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContents* web_contents = GetOrCloneTabForDisposition(browser, disposition);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents->UserGestureDone();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!web_contents->FocusLocationBarByDefault())
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    web_contents->GetView()->Focus();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ignore_cache)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents->GetController().ReloadIgnoringCache(true);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents->GetController().Reload(true);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsShowingWebContentsModalDialog(const Browser* browser) {
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* web_contents =
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetActiveWebContents();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!web_contents)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContentsModalDialogManager* web_contents_modal_dialog_manager =
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebContentsModalDialogManager::FromWebContents(web_contents);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return web_contents_modal_dialog_manager->IsShowingDialog();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrintPreviewShowing(const Browser* browser) {
197a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#if defined(ENABLE_FULL_PRINTING)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  printing::PrintPreviewDialogController* controller =
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      printing::PrintPreviewDialogController::GetInstance();
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return controller && (controller->GetPrintPreviewForContents(contents) ||
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        controller->is_creating_print_preview_dialog());
203a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#else
204a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch  return false;
205a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#endif
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsCommandEnabled(Browser* browser, int command) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser->command_controller()->command_updater()->IsCommandEnabled(
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SupportsCommand(Browser* browser, int command) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser->command_controller()->command_updater()->SupportsCommand(
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExecuteCommand(Browser* browser, int command) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser->command_controller()->command_updater()->ExecuteCommand(
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExecuteCommandWithDisposition(Browser* browser,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int command,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   WindowOpenDisposition disposition) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser->command_controller()->command_updater()->
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExecuteCommandWithDisposition(command, disposition);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->command_controller()->command_updater()->UpdateCommandEnabled(
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command, enabled);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddCommandObserver(Browser* browser,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int command,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        CommandObserver* observer) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->command_controller()->command_updater()->AddCommandObserver(
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command, observer);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveCommandObserver(Browser* browser,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int command,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           CommandObserver* observer) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->command_controller()->command_updater()->RemoveCommandObserver(
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command, observer);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetContentRestrictions(const Browser* browser) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int content_restrictions = 0;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_tab) {
255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CoreTabHelper* core_tab_helper =
256ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        CoreTabHelper::FromWebContents(current_tab);
257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    content_restrictions = core_tab_helper->content_restrictions();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NavigationEntry* active_entry =
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current_tab->GetController().GetActiveEntry();
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See comment in UpdateCommandsForTabState about why we call url().
26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!content::IsSavableURL(
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            active_entry ? active_entry->GetURL() : GURL()) ||
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current_tab->ShowingInterstitialPage())
264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      content_restrictions |= CONTENT_RESTRICTION_SAVE;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (current_tab->ShowingInterstitialPage())
266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      content_restrictions |= CONTENT_RESTRICTION_PRINT;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return content_restrictions;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool incognito = profile->IsOffTheRecord();
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* prefs = profile->GetPrefs();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (incognito) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IncognitoModePrefs::GetAvailability(prefs) ==
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          IncognitoModePrefs::DISABLED) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      incognito = false;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (browser_defaults::kAlwaysOpenIncognitoWindow &&
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IncognitoModePrefs::ShouldLaunchIncognito(
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *CommandLine::ForCurrentProcess(), prefs)) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      incognito = true;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (incognito) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OpenEmptyWindow(profile->GetOffTheRecordProfile(), desktop_type);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RecordAction(UserMetricsAction("NewWindow"));
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SessionService* session_service =
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SessionServiceFactory::GetForProfile(profile->GetOriginalProfile());
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!session_service ||
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !session_service->RestoreIfNecessary(std::vector<GURL>())) {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpenEmptyWindow(profile->GetOriginalProfile(), desktop_type);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Browser* OpenEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* browser = new Browser(
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddBlankTabAt(browser, -1, true);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->Show();
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OpenWindowWithRestoredTabs(Profile* profile,
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                HostDesktopType host_desktop_type) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (service)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service->RestoreMostRecentEntry(NULL, host_desktop_type);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OpenURLOffTheRecord(Profile* profile,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const GURL& url,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         chrome::HostDesktopType desktop_type) {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Browser* browser = chrome::FindOrCreateTabbedBrowser(
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile->GetOffTheRecordProfile(), desktop_type);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSelectedTabWithURL(browser, url, content::PAGE_TRANSITION_LINK);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->Show();
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanGoBack(const Browser* browser) {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return browser->tab_strip_model()->GetActiveWebContents()->
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetController().CanGoBack();
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GoBack(Browser* browser, WindowOpenDisposition disposition) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Back"));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CanGoBack(browser)) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents* new_tab = GetOrCloneTabForDisposition(browser, disposition);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we are on an interstitial page and clone the tab, it won't be copied
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to the new tab, so we don't need to go back.
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (current_tab->ShowingInterstitialPage() && new_tab != current_tab)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_tab->GetController().GoBack();
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanGoForward(const Browser* browser) {
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return browser->tab_strip_model()->GetActiveWebContents()->
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetController().CanGoForward();
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GoForward(Browser* browser, WindowOpenDisposition disposition) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Forward"));
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CanGoForward(browser)) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetOrCloneTabForDisposition(browser, disposition)->
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetController().GoForward();
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NavigateToIndexWithDisposition(Browser* browser,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int index,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    WindowOpenDisposition disp) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController& controller =
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetOrCloneTabForDisposition(browser, disp)->GetController();
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (index < 0 || index >= controller.GetEntryCount())
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoToIndex(index);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Reload(Browser* browser, WindowOpenDisposition disposition) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Reload"));
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReloadInternal(browser, disposition, false);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReloadIgnoringCache(Browser* browser, WindowOpenDisposition disposition) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReloadInternal(browser, disposition, true);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanReload(const Browser* browser) {
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !browser->is_devtools();
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Home(Browser* browser, WindowOpenDisposition disposition) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Home"));
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extra_headers;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ENABLE_RLZ)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the home page is a Google home page, add the RLZ header to the request.
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* pref_service = browser->profile()->GetPrefs();
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pref_service) {
390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (google_util::IsGoogleHomePageUrl(
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        GURL(pref_service->GetString(prefs::kHomePage)))) {
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extra_headers = RLZTracker::GetAccessPointHttpHeader(
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          RLZTracker::CHROME_HOME_PAGE);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenURLParams params(
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser->profile()->GetHomePage(), Referrer(), disposition,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PageTransitionFromInt(
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::PAGE_TRANSITION_AUTO_BOOKMARK |
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::PAGE_TRANSITION_HOME_PAGE),
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.extra_headers = extra_headers;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->OpenURL(params);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OpenCurrentURL(Browser* browser) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("LoadURL"));
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocationBar* location_bar = browser->window()->GetLocationBar();
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!location_bar)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL url(location_bar->GetInputString());
415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::PageTransition page_transition = location_bar->GetPageTransition();
41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  content::PageTransition page_transition_without_qualifier(
41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      PageTransitionStripQualifier(page_transition));
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowOpenDisposition open_disposition =
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      location_bar->GetWindowOpenDisposition();
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A PAGE_TRANSITION_TYPED means the user has typed a URL. We do not want to
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // open URLs with instant_controller since in some cases it disregards it
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and performs a search instead. For example, when using CTRL-Enter, the
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // location_bar is aware of the URL but instant is not.
42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Instant should also not handle PAGE_TRANSITION_RELOAD because its knowledge
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // of the omnibox text may be stale if the user focuses in the omnibox and
42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // presses enter without typing anything.
42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (page_transition_without_qualifier != content::PAGE_TRANSITION_TYPED &&
42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_transition_without_qualifier != content::PAGE_TRANSITION_RELOAD &&
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->instant_controller() &&
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      browser->instant_controller()->OpenInstant(open_disposition, url))
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateParams params(browser, url, page_transition);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.disposition = open_disposition;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // inherit the opener. In some cases the tabstrip will determine the group
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be inherited, in which case the group is inherited instead of the
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // opener.
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.tabstrip_add_types =
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Navigate(&params);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(browser->profile()->GetExtensionService());
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const extensions::Extension* extension =
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->profile()->GetExtensionService()->GetInstalledApp(url);
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (extension) {
448558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    CoreAppLauncherHandler::RecordAppLaunchType(
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        extension->GetType());
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Stop(Browser* browser) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Stop"));
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser->tab_strip_model()->GetActiveWebContents()->Stop();
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewWindow(Browser* browser) {
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NewEmptyWindow(browser->profile()->GetOriginalProfile(),
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 browser->host_desktop_type());
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewIncognitoWindow(Browser* browser) {
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NewEmptyWindow(browser->profile()->GetOffTheRecordProfile(),
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 browser->host_desktop_type());
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloseWindow(Browser* browser) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("CloseWindow"));
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->Close();
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewTab(Browser* browser) {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("NewTab"));
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(asvitkine): This is invoked programmatically from several places.
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audit the code and change it so that the histogram only gets collected for
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // user-initiated commands.
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", TabStripModel::NEW_TAB_COMMAND,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            TabStripModel::NEW_TAB_ENUM_COUNT);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser->is_type_tabbed()) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddBlankTabAt(browser, -1, true);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser->tab_strip_model()->GetActiveWebContents()->GetView()->
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        RestoreFocus();
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* b =
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        chrome::FindOrCreateTabbedBrowser(browser->profile(),
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          browser->host_desktop_type());
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddBlankTabAt(b, -1, true);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    b->window()->Show();
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The call to AddBlankTabAt above did not set the focus to the tab as its
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // window was not active, so we have to do it explicitly.
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See http://crbug.com/6380.
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    b->tab_strip_model()->GetActiveWebContents()->GetView()->RestoreFocus();
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloseTab(Browser* browser) {
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->tab_strip_model()->CloseSelectedTabs();
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RestoreTab(Browser* browser) {
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("RestoreTab"));
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabRestoreService* service =
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TabRestoreServiceFactory::GetForProfile(browser->profile());
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (service)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service->RestoreMostRecentEntry(browser->tab_restore_service_delegate(),
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    browser->host_desktop_type());
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TabStripModelDelegate::RestoreTabType GetRestoreTabType(
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Browser* browser) {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabRestoreService* service =
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TabRestoreServiceFactory::GetForProfile(browser->profile());
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!service || service->entries().empty())
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return TabStripModelDelegate::RESTORE_NONE;
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (service->entries().front()->type == TabRestoreService::WINDOW)
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return TabStripModelDelegate::RESTORE_WINDOW;
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return TabStripModelDelegate::RESTORE_TAB;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SelectNextTab(Browser* browser) {
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("SelectNextTab"));
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->tab_strip_model()->SelectNextTab();
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SelectPreviousTab(Browser* browser) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("SelectPrevTab"));
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->tab_strip_model()->SelectPreviousTab();
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OpenTabpose(Browser* browser) {
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switches::kEnableExposeForTabs)) {
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("OpenTabpose"));
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->OpenTabpose();
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MoveTabNext(Browser* browser) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("MoveTabNext"));
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->tab_strip_model()->MoveTabNext();
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MoveTabPrevious(Browser* browser) {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("MoveTabPrevious"));
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->tab_strip_model()->MoveTabPrevious();
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SelectNumberedTab(Browser* browser, int index) {
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (index < browser->tab_strip_model()->count()) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RecordAction(UserMetricsAction("SelectNumberedTab"));
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser->tab_strip_model()->ActivateTabAt(index, true);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SelectLastTab(Browser* browser) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("SelectLastTab"));
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->tab_strip_model()->SelectLastTab();
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DuplicateTab(Browser* browser) {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Duplicate"));
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DuplicateTabAt(browser, browser->tab_strip_model()->active_index());
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanDuplicateTab(const Browser* browser) {
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return contents && contents->GetController().GetLastCommittedEntry();
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebContents* DuplicateTabAt(Browser* browser, int index) {
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(index);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(contents);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents_dupe = contents->Clone();
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool pinned = false;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If this is a tabbed browser, just create a duplicate tab inside the same
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // window next to the tab being duplicated.
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pinned = browser->tab_strip_model()->IsTabPinned(index);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int add_types = TabStripModel::ADD_ACTIVE |
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TabStripModel::ADD_INHERIT_GROUP |
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (pinned ? TabStripModel::ADD_PINNED : 0);
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser->tab_strip_model()->InsertWebContentsAt(
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        index + 1, contents_dupe, add_types);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Browser* new_browser = NULL;
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (browser->is_app() &&
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        !browser->is_type_popup()) {
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_browser = new Browser(
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          Browser::CreateParams::CreateForApp(browser->type(),
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              browser->app_name(),
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              gfx::Rect(),
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              browser->profile(),
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              browser->host_desktop_type()));
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_browser = new Browser(
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          Browser::CreateParams(browser->type(), browser->profile(),
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                browser->host_desktop_type()));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Preserve the size of the original window. The new window has already
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // been given an offset by the OS, so we shouldn't copy the old bounds.
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserWindow* new_window = new_browser->window();
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          browser->window()->GetRestoredBounds().size()));
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We need to show the browser now.  Otherwise ContainerWin assumes the
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // WebContents is invisible and won't size it.
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_browser->window()->Show();
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The page transition below is only for the purpose of inserting the tab.
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_browser->tab_strip_model()->AddWebContents(
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        contents_dupe, -1,
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::PAGE_TRANSITION_LINK,
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        TabStripModel::ADD_ACTIVE);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SessionService* session_service =
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SessionServiceFactory::GetForProfileIfExisting(browser->profile());
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (session_service)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_service->TabRestored(contents_dupe, pinned);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return contents_dupe;
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanDuplicateTabAt(Browser* browser, int index) {
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NavigationController& nc =
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetWebContentsAt(index)->GetController();
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return nc.GetWebContents() && nc.GetLastCommittedEntry();
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConvertPopupToTabbedBrowser(Browser* browser) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("ShowAsTab"));
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip = browser->tab_strip_model();
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents =
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tab_strip->DetachWebContentsAt(tab_strip->active_index());
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Browser* b = new Browser(Browser::CreateParams(browser->profile(),
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 browser->host_desktop_type()));
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  b->tab_strip_model()->AppendWebContents(contents, true);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  b->window()->Show();
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Exit() {
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Exit"));
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome::AttemptUserExit();
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkCurrentPage(Browser* browser) {
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkCurrentPageInternal(browser, false);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkCurrentPageFromStar(Browser* browser) {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkCurrentPageInternal(browser, true);
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanBookmarkCurrentPage(const Browser* browser) {
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkModel* model =
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BookmarkModelFactory::GetForProfile(browser->profile());
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser_defaults::bookmarks_enabled &&
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser->profile()->GetPrefs()->GetBoolean(
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          prefs::kEditBookmarksEnabled) &&
673b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      model && model->loaded() && browser->is_type_tabbed();
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkAllTabs(Browser* browser) {
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::ShowBookmarkAllTabsDialog(browser);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanBookmarkAllTabs(const Browser* browser) {
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return browser->tab_strip_model()->count() > 1 &&
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             CanBookmarkCurrentPage(browser);
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TogglePagePinnedToStartScreen(Browser* browser) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MetroPinTabHelper::FromWebContents(
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetActiveWebContents())->
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          TogglePinnedToStartScreen();
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SavePage(Browser* browser) {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("SavePage"));
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RecordAction(UserMetricsAction("PDF.SavePage"));
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_tab->OnSavePage();
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanSavePage(const Browser* browser) {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LocalState can be NULL in tests.
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_browser_process->local_state() &&
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !g_browser_process->local_state()->GetBoolean(
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kAllowFileSelectionDialogs)) {
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !browser->is_devtools() &&
709ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowFindBar(Browser* browser) {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->GetFindBarController()->Show();
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShowWebsiteSettings(Browser* browser,
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         content::WebContents* web_contents,
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const GURL& url,
7197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                         const SSLStatus& ssl) {
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser->window()->ShowWebsiteSettings(
7217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      Profile::FromBrowserContext(web_contents->GetBrowserContext()),
7227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      web_contents, url, ssl);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Print(Browser* browser) {
727a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#if defined(ENABLE_PRINTING)
728a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch  WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
729a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#if defined(ENABLE_FULL_PRINTING)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printing::PrintViewManager* print_view_manager =
731a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch      printing::PrintViewManager::FromWebContents(contents);
732a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch  if (browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled))
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print_view_manager->PrintNow();
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    print_view_manager->PrintPreviewNow(false);
736a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#else
737a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch  printing::PrintViewManagerBasic* print_view_manager =
738a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch      printing::PrintViewManagerBasic::FromWebContents(contents);
739a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch  print_view_manager->PrintNow();
740a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#endif  // defined(ENABLE_FULL_PRINTING)
741a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#endif  // defined(ENABLE_PRINTING)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanPrint(const Browser* browser) {
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not print when printing is disabled via pref or policy.
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not print when a constrained window is showing. It's confusing.
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !(IsShowingWebContentsModalDialog(browser) ||
749ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AdvancedPrint(Browser* browser) {
753a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#if defined(ENABLE_FULL_PRINTING)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printing::PrintViewManager* print_view_manager =
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printing::PrintViewManager::FromWebContents(
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          browser->tab_strip_model()->GetActiveWebContents());
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  print_view_manager->AdvancedPrintNow();
758a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#endif
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanAdvancedPrint(const Browser* browser) {
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If printing is not disabled via pref or policy, it is always possible to
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // advanced print when the print preview is visible.
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (PrintPreviewShowing(browser) || CanPrint(browser));
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintToDestination(Browser* browser) {
769a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#if defined(ENABLE_FULL_PRINTING)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printing::PrintViewManager* print_view_manager =
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printing::PrintViewManager::FromWebContents(
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          browser->tab_strip_model()->GetActiveWebContents());
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  print_view_manager->PrintToDestination();
774a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#endif
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EmailPageLocation(Browser* browser) {
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("EmailPageLocation"));
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* wc = browser->tab_strip_model()->GetActiveWebContents();
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(wc);
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string title = net::EscapeQueryParamValue(
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UTF16ToUTF8(wc->GetTitle()), false);
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string mailto = std::string("mailto:?subject=Fwd:%20") +
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      title + "&body=%0A%0A" + page_url;
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  platform_util::OpenExternal(GURL(mailto));
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanEmailPageLocation(const Browser* browser) {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser->toolbar_model()->ShouldDisplayURL() &&
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetActiveWebContents()->GetURL().is_valid();
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Cut(Browser* browser) {
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Cut"));
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->Cut();
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Copy(Browser* browser) {
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Copy"));
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->Copy();
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Paste(Browser* browser) {
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Paste"));
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->Paste();
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Find(Browser* browser) {
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Find"));
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindInPage(browser, false, false);
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindNext(Browser* browser) {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("FindNext"));
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindInPage(browser, true, true);
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindPrevious(Browser* browser) {
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("FindPrevious"));
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindInPage(browser, true, false);
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShowFindBar(browser);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (find_next) {
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 find_text;
8297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    FindTabHelper* find_helper = FindTabHelper::FromWebContents(
8307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        browser->tab_strip_model()->GetActiveWebContents());
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We always want to search for the contents of the find pasteboard on OS X.
8337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // But Incognito window doesn't write to the find pboard. Therefore, its own
8347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // find text has higher priority.
8357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!browser->profile()->IsOffTheRecord() ||
8367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        find_helper->find_text().empty())
8377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      find_text = GetFindPboardText();
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    find_helper->StartFinding(find_text, forward_direction, false);
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Zoom(Browser* browser, content::PageZoom zoom) {
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser->is_devtools())
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome_page_zoom::Zoom(browser->tab_strip_model()->GetActiveWebContents(),
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         zoom);
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FocusToolbar(Browser* browser) {
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("FocusToolbar"));
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->FocusToolbar();
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FocusLocationBar(Browser* browser) {
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("FocusLocation"));
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->SetFocusToLocationBar(true);
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FocusSearch(Browser* browser) {
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(beng): replace this with FocusLocationBar
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("FocusSearch"));
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->GetLocationBar()->FocusSearch();
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FocusAppMenu(Browser* browser) {
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("FocusAppMenu"));
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->FocusAppMenu();
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FocusBookmarksToolbar(Browser* browser) {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->FocusBookmarksToolbar();
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FocusInfobars(Browser* browser) {
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::RecordAction(UserMetricsAction("FocusInfobars"));
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  browser->window()->FocusInfobars();
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FocusNextPane(Browser* browser) {
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("FocusNextPane"));
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->RotatePaneFocus(true);
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FocusPreviousPane(Browser* browser) {
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("FocusPreviousPane"));
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->RotatePaneFocus(false);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ToggleDevToolsWindow(Browser* browser, DevToolsToggleAction action) {
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (action == DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevToolsWindow::ToggleDevToolsWindow(browser, action);
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanOpenTaskManager() {
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In metro we can't display the task manager, as it is a native window.
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !win8::IsSingleWindowMetroMode();
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
909eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OpenTaskManager(Browser* browser) {
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("TaskManager"));
911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  chrome::ShowTaskManager(browser);
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OpenFeedbackDialog(Browser* browser) {
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Feedback"));
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::ShowFeedbackPage(browser, std::string(), std::string());
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ToggleBookmarkBar(Browser* browser) {
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->ToggleBookmarkBar();
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowAppMenu(Browser* browser) {
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We record the user metric for this event in WrenchMenu::RunMenu.
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->ShowAppMenu();
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowAvatarMenu(Browser* browser) {
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->window()->ShowAvatarBubbleFromAvatarButton();
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OpenUpdateChromeDialog(Browser* browser) {
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (UpgradeDetector::GetInstance()->is_outdated_install()) {
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::NotificationService::current()->Notify(
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        chrome::NOTIFICATION_OUTDATED_INSTALL,
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::NotificationService::AllSources(),
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::NotificationService::NoDetails());
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::RecordAction(UserMetricsAction("UpdateChrome"));
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser->window()->ShowUpdateChromeDialog();
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ToggleSpeechInput(Browser* browser) {
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser->tab_strip_model()->GetActiveWebContents()->
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetRenderViewHost()->ToggleSpeechInput();
948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (browser->instant_controller())
949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    browser->instant_controller()->ToggleVoiceSearch();
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanRequestTabletSite(WebContents* current_tab) {
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!current_tab)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return current_tab->GetController().GetActiveEntry() != NULL;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsRequestingTabletSite(Browser* browser) {
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!current_tab)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NavigationEntry* entry =
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_tab->GetController().GetActiveEntry();
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return entry->GetIsOverridingUserAgent();
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ToggleRequestTabletSite(Browser* browser) {
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!current_tab)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController& controller = current_tab->GetController();
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller.GetActiveEntry();
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry)
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry->GetIsOverridingUserAgent()) {
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry->SetIsOverridingUserAgent(false);
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry->SetIsOverridingUserAgent(true);
981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    chrome::VersionInfo version_info;
982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string product;
983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (version_info.is_valid())
984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      product = version_info.ProductNameAndVersionForUserAgent();
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_tab->SetUserAgentOverride(
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        webkit_glue::BuildUserAgentFromOSAndProduct(
987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            kOsOverrideForTabletSite, product));
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.ReloadOriginalRequestURL(true);
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ToggleFullscreenMode(Browser* browser) {
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->fullscreen_controller()->ToggleFullscreenMode();
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClearCache(Browser* browser) {
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowsingDataRemover* remover =
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  BrowsingDataHelper::UNPROTECTED_WEB);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BrowsingDataRemover takes care of deleting itself when done.
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return contents ?
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::DevToolsAgentHost::IsDebuggerAttached(contents) : false;
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ViewSource(Browser* browser, WebContents* contents) {
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(contents);
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the last committed entry, since the pending entry hasn't loaded yet and
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // won't be copied into the cloned tab.
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationEntry* entry = contents->GetController().GetLastCommittedEntry();
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ViewSource(browser, contents, entry->GetURL(), entry->GetPageState());
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewSource(Browser* browser,
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                WebContents* contents,
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                const GURL& url,
102590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                const content::PageState& page_state) {
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("ViewSource"));
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(contents);
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that Clone does not copy the pending or transient entries, so the
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // active entry in view_source_contents will be the last committed entry.
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* view_source_contents = contents->Clone();
1032868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(view_source_contents->GetController().CanPruneAllButVisible());
1033868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  view_source_contents->GetController().PruneAllButVisible();
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* active_entry =
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      view_source_contents->GetController().GetActiveEntry();
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!active_entry)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1039868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL view_source_url =
1040868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GURL(content::kViewSourceScheme + std::string(":") + url.spec());
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  active_entry->SetVirtualURL(view_source_url);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not restore scroller position.
104490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  active_entry->SetPageState(page_state.RemoveScrollOffset());
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not restore title, derive it from the url.
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  active_entry->SetTitle(string16());
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now show view-source entry.
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If this is a tabbed browser, just create a duplicate tab inside the same
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // window next to the tab being duplicated.
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int add_types = TabStripModel::ADD_ACTIVE |
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TabStripModel::ADD_INHERIT_GROUP;
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser->tab_strip_model()->InsertWebContentsAt(
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        index + 1,
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        view_source_contents,
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        add_types);
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* b = new Browser(
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Browser::CreateParams(Browser::TYPE_TABBED, browser->profile(),
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              browser->host_desktop_type()));
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Preserve the size of the original window. The new window has already
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // been given an offset by the OS, so we shouldn't copy the old bounds.
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* new_window = b->window();
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          browser->window()->GetRestoredBounds().size()));
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We need to show the browser now. Otherwise ContainerWin assumes the
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // WebContents is invisible and won't size it.
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    b->window()->Show();
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The page transition below is only for the purpose of inserting the tab.
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    b->tab_strip_model()->AddWebContents(view_source_contents, -1,
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         content::PAGE_TRANSITION_LINK,
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         TabStripModel::ADD_ACTIVE);
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SessionService* session_service =
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SessionServiceFactory::GetForProfileIfExisting(browser->profile());
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (session_service)
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_service->TabRestored(view_source_contents, false);
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewSelectedSource(Browser* browser) {
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ViewSource(browser, browser->tab_strip_model()->GetActiveWebContents());
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanViewSource(const Browser* browser) {
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return browser->tab_strip_model()->GetActiveWebContents()->
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetController().CanViewSource();
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateApplicationShortcuts(Browser* browser) {
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("CreateShortcut"));
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::TabHelper::FromWebContents(
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetActiveWebContents())->
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CreateApplicationShortcuts();
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanCreateApplicationShortcuts(const Browser* browser) {
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return extensions::TabHelper::FromWebContents(
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetActiveWebContents())->
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CanCreateApplicationShortcuts();
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConvertTabToAppWindow(Browser* browser,
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           content::WebContents* contents) {
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& url = contents->GetController().GetActiveEntry()->GetURL();
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string app_name = web_app::GenerateApplicationNameFromURL(url);
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (index >= 0)
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser->tab_strip_model()->DetachWebContentsAt(index);
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* app_browser = new Browser(
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Browser::CreateParams::CreateForApp(
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          Browser::TYPE_POPUP, app_name, gfx::Rect(), browser->profile(),
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          browser->host_desktop_type()));
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  app_browser->tab_strip_model()->AppendWebContents(contents, true);
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents->GetRenderViewHost()->SyncRendererPrefs();
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  app_browser->window()->Show();
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
1130