browser_navigator.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 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_navigator.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_about_handler.h"
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/google/google_url_tracker.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/incognito_mode_prefs.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager_factory.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/prerender/prerender_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/tab_contents/tab_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_instant_controller.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/location_bar.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/search/instant_search_prerenderer.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/singleton_tabs.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/status_bubble.h"
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/tab_helpers.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_url_handler.h"
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_view.h"
4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "extensions/browser/extension_registry.h"
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "extensions/common/extension_set.h"
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(USE_ASH)
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::GlobalRequestID;
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using content::NavigationController;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BrowserNavigatorWebContentsAdoption {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void AttachTabHelpers(content::WebContents* contents) {
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    TabHelpers::AttachTabHelpers(contents);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the specified Browser can open tabs. Not all Browsers support
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// multiple tabs, such as app frames and popups. This function returns false for
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// those types of Browser.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WindowCanOpenTabs(Browser* browser) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP) ||
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser->tab_strip_model()->empty();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Finds an existing Browser compatible with |profile|, making a new one if no
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// such Browser is located.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Browser* GetOrCreateBrowser(Profile* profile,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            chrome::HostDesktopType host_desktop_type) {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Browser* browser = chrome::FindTabbedBrowser(profile, false,
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               host_desktop_type);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return browser ? browser : new Browser(
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Browser::CreateParams(profile, host_desktop_type));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Change some of the navigation parameters based on the particular URL.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Currently this applies to some chrome:// pages which we always want to open
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in a non-incognito window. Note that even though a ChromeOS guest session is
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// technically an incognito window, these URLs are allowed.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true on success. Otherwise, if changing params leads the browser into
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an erroneous state, returns false.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AdjustNavigateParamsForURL(chrome::NavigateParams* params) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->target_contents != NULL ||
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::IsURLAllowedInIncognito(params->url,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      params->initiating_profile) ||
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params->initiating_profile->IsGuestSession()) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile = params->initiating_profile;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (profile->IsOffTheRecord() || params->disposition == OFF_THE_RECORD) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile = profile->GetOriginalProfile();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If incognito is forced, we punt.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefService* prefs = profile->GetPrefs();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (prefs && IncognitoModePrefs::GetAvailability(prefs) ==
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            IncognitoModePrefs::FORCED) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->disposition = SINGLETON_TAB;
1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    params->browser = GetOrCreateBrowser(profile, params->host_desktop_type);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->window_action = chrome::NavigateParams::SHOW_WINDOW;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a Browser that can host the navigation or tab addition specified in
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |params|. This might just return the same Browser specified in |params|, or
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// some other if that Browser is deemed incompatible.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Browser* GetBrowserForDisposition(chrome::NavigateParams* params) {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If no source WebContents was specified, we use the selected one from
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the target browser. This must happen first, before
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetBrowserForDisposition() has a chance to replace |params->browser| with
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // another one.
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!params->source_contents && params->browser) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params->source_contents =
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        params->browser->tab_strip_model()->GetActiveWebContents();
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile = params->initiating_profile;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (params->disposition) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CURRENT_TAB:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (params->browser)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return params->browser;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Find a compatible window and re-execute this command in it. Otherwise
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // re-run with NEW_WINDOW.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GetOrCreateBrowser(profile, params->host_desktop_type);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SINGLETON_TAB:
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_FOREGROUND_TAB:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_BACKGROUND_TAB:
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // See if we can open the tab in the window this navigator is bound to.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (params->browser && WindowCanOpenTabs(params->browser))
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return params->browser;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Find a compatible window and re-execute this command in it. Otherwise
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // re-run with NEW_WINDOW.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GetOrCreateBrowser(profile, params->host_desktop_type);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_POPUP: {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Make a new popup window.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Coerce app-style if |source| represents an app.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string app_name;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!params->extension_app_id.empty()) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        app_name = web_app::GenerateApplicationNameFromExtensionId(
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            params->extension_app_id);
157558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      } else if (params->browser && !params->browser->app_name().empty()) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        app_name = params->browser->app_name();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (params->source_contents) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        extensions::TabHelper* extensions_tab_helper =
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            extensions::TabHelper::FromWebContents(params->source_contents);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (extensions_tab_helper && extensions_tab_helper->is_app()) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          app_name = web_app::GenerateApplicationNameFromExtensionId(
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              extensions_tab_helper->extension_app()->id());
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (app_name.empty()) {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Browser::CreateParams browser_params(
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            Browser::TYPE_POPUP, profile, params->host_desktop_type);
170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        browser_params.trusted_source = params->trusted_source;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser_params.initial_bounds = params->window_bounds;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return new Browser(browser_params);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return new Browser(Browser::CreateParams::CreateForApp(
176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          app_name,
177a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          params->trusted_source,
178a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          params->window_bounds,
179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          profile,
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          params->host_desktop_type));
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_WINDOW: {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Make a new normal browser window.
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return new Browser(Browser::CreateParams(profile,
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               params->host_desktop_type));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case OFF_THE_RECORD:
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Make or find an incognito window.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GetOrCreateBrowser(profile->GetOffTheRecordProfile(),
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                params->host_desktop_type);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The following types all result in no navigation.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SUPPRESS_OPEN:
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SAVE_TO_DISK:
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IGNORE_ACTION:
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fix disposition and other parameter values depending on prevailing
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// conditions.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NormalizeDisposition(chrome::NavigateParams* params) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calculate the WindowOpenDisposition if necessary.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->browser->tab_strip_model()->empty() &&
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (params->disposition == NEW_BACKGROUND_TAB ||
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       params->disposition == CURRENT_TAB ||
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       params->disposition == SINGLETON_TAB)) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->disposition = NEW_FOREGROUND_TAB;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->browser->profile()->IsOffTheRecord() &&
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params->disposition == OFF_THE_RECORD) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->disposition = NEW_FOREGROUND_TAB;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params->source_contents && params->disposition == CURRENT_TAB)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->disposition = NEW_FOREGROUND_TAB;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (params->disposition) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_BACKGROUND_TAB:
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Disposition trumps add types. ADD_ACTIVE is a default, so we need to
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // remove it if disposition implies the tab is going to open in the
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // background.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params->tabstrip_add_types &= ~TabStripModel::ADD_ACTIVE;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_WINDOW:
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_POPUP:
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Code that wants to open a new window typically expects it to be shown
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // automatically.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (params->window_action == chrome::NavigateParams::NO_ACTION)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        params->window_action = chrome::NavigateParams::SHOW_WINDOW;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Fall-through.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NEW_FOREGROUND_TAB:
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SINGLETON_TAB:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params->tabstrip_add_types |= TabStripModel::ADD_ACTIVE;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Obtain the profile used by the code that originated the Navigate() request.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Profile* GetSourceProfile(chrome::NavigateParams* params) {
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params->source_contents) {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return Profile::FromBrowserContext(
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        params->source_contents->GetBrowserContext());
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return params->initiating_profile;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoadURLInContents(WebContents* target_contents,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const GURL& url,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       chrome::NavigateParams* params) {
257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  NavigationController::LoadURLParams load_url_params(url);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_url_params.referrer = params->referrer;
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  load_url_params.frame_tree_node_id = params->frame_tree_node_id;
2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  load_url_params.redirect_chain = params->redirect_chain;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_url_params.transition_type = params->transition;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_url_params.extra_headers = params->extra_headers;
263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  load_url_params.should_replace_current_entry =
264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      params->should_replace_current_entry;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->transferred_global_request_id != GlobalRequestID()) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    load_url_params.is_renderer_initiated = params->is_renderer_initiated;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    load_url_params.transferred_global_request_id =
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        params->transferred_global_request_id;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (params->is_renderer_initiated) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    load_url_params.is_renderer_initiated = true;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Only allows the browser-initiated navigation to use POST.
275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (params->uses_post && !params->is_renderer_initiated) {
276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    load_url_params.load_type =
277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        NavigationController::LOAD_TYPE_BROWSER_INITIATED_HTTP_POST;
278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    load_url_params.browser_initiated_post_data =
279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        params->browser_initiated_post_data;
280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_contents->GetController().LoadURLWithParams(load_url_params);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class makes sure the Browser object held in |params| is made visible
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by the time it goes out of scope, provided |params| wants it to be shown.
2860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class ScopedBrowserShower {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  explicit ScopedBrowserShower(chrome::NavigateParams* params)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : params_(params) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ~ScopedBrowserShower() {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (params_->window_action == chrome::NavigateParams::SHOW_WINDOW_INACTIVE)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params_->browser->window()->ShowInactive();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (params_->window_action == chrome::NavigateParams::SHOW_WINDOW)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params_->browser->window()->Show();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NavigateParams* params_;
2990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedBrowserShower);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class manages the lifetime of a WebContents created by the
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Navigate() function. When Navigate() creates a WebContents for a URL,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an instance of this class takes ownership of it via TakeOwnership() until the
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WebContents is added to a tab strip at which time ownership is
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// relinquished via ReleaseOwnership(). If this object goes out of scope without
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// being added to a tab strip, the created WebContents is deleted to
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// avoid a leak and the params->target_contents field is set to NULL.
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedTargetContentsOwner {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ScopedTargetContentsOwner(chrome::NavigateParams* params)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : params_(params) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedTargetContentsOwner() {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (target_contents_owner_.get())
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params_->target_contents = NULL;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assumes ownership of |params_|' target_contents until ReleaseOwnership
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is called.
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TakeOwnership() {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target_contents_owner_.reset(params_->target_contents);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Relinquishes ownership of |params_|' target_contents.
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* ReleaseOwnership() {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return target_contents_owner_.release();
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NavigateParams* params_;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WebContents> target_contents_owner_;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedTargetContentsOwner);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::WebContents* CreateTargetContents(const chrome::NavigateParams& params,
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const GURL& url) {
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents::CreateParams create_params(
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params.browser->profile(),
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tab_util::GetSiteInstanceForNewTab(params.browser->profile(), url));
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params.source_contents) {
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    create_params.initial_size =
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        params.source_contents->GetView()->GetContainerSize();
344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (params.should_set_opener)
345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      create_params.opener = params.source_contents;
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (params.disposition == NEW_BACKGROUND_TAB)
3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    create_params.initially_hidden = true;
3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA)
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params.browser->window() &&
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params.browser->window()->GetNativeWindow()) {
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    create_params.context =
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        params.browser->window()->GetNativeWindow();
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  WebContents* target_contents = WebContents::Create(create_params);
359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // New tabs can have WebUI URLs that will make calls back to arbitrary
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // tab helpers, so the entire set of tab helpers needs to be set up
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // immediately.
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserNavigatorWebContentsAdoption::AttachTabHelpers(target_contents);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::TabHelper::FromWebContents(target_contents)->
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetExtensionAppById(params.extension_app_id);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return target_contents;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// If a prerendered page exists for |url|, replace the page at
3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// |params->target_contents| with it and update to point to the swapped-in
3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// WebContents.
3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SwapInPrerender(const GURL& url, chrome::NavigateParams* params) {
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Profile* profile =
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Profile::FromBrowserContext(params->target_contents->GetBrowserContext());
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InstantSearchPrerenderer* prerenderer =
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      InstantSearchPrerenderer::GetForProfile(profile);
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (prerenderer && prerenderer->UsePrerenderedPage(url, params))
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prerender::PrerenderManager* prerender_manager =
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      prerender::PrerenderManagerFactory::GetForProfile(profile);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return prerender_manager &&
3838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      prerender_manager->MaybeUsePrerenderedPage(url, params);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochchrome::HostDesktopType GetHostDesktop(Browser* browser) {
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (browser)
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return browser->host_desktop_type();
389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return chrome::GetActiveDesktop();
390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NavigateParams::NavigateParams(Browser* a_browser,
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const GURL& a_url,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               content::PageTransition a_transition)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : url(a_url),
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      frame_tree_node_id(-1),
401a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      uses_post(false),
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target_contents(NULL),
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      source_contents(NULL),
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disposition(CURRENT_TAB),
405a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      trusted_source(false),
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transition(a_transition),
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_renderer_initiated(false),
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tabstrip_index(-1),
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tabstrip_add_types(TabStripModel::ADD_ACTIVE),
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_action(NO_ACTION),
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      user_gesture(true),
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path_behavior(RESPECT),
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ref_behavior(IGNORE_REF),
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(a_browser),
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      initiating_profile(NULL),
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      host_desktop_type(GetHostDesktop(a_browser)),
417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      should_replace_current_entry(false),
418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      should_set_opener(false) {
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NavigateParams::NavigateParams(Browser* a_browser,
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               WebContents* a_target_contents)
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : frame_tree_node_id(-1),
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      uses_post(false),
425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      target_contents(a_target_contents),
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      source_contents(NULL),
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disposition(CURRENT_TAB),
428a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      trusted_source(false),
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transition(content::PAGE_TRANSITION_LINK),
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_renderer_initiated(false),
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tabstrip_index(-1),
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tabstrip_add_types(TabStripModel::ADD_ACTIVE),
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_action(NO_ACTION),
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      user_gesture(true),
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path_behavior(RESPECT),
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ref_behavior(IGNORE_REF),
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(a_browser),
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      initiating_profile(NULL),
439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      host_desktop_type(GetHostDesktop(a_browser)),
440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      should_replace_current_entry(false),
441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      should_set_opener(false) {
442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NavigateParams::NavigateParams(Profile* a_profile,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const GURL& a_url,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               content::PageTransition a_transition)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : url(a_url),
448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      frame_tree_node_id(-1),
449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      uses_post(false),
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target_contents(NULL),
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      source_contents(NULL),
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disposition(NEW_FOREGROUND_TAB),
453a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      trusted_source(false),
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transition(a_transition),
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_renderer_initiated(false),
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tabstrip_index(-1),
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tabstrip_add_types(TabStripModel::ADD_ACTIVE),
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_action(SHOW_WINDOW),
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      user_gesture(true),
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path_behavior(RESPECT),
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ref_behavior(IGNORE_REF),
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(NULL),
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      initiating_profile(a_profile),
464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      host_desktop_type(chrome::GetActiveDesktop()),
465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      should_replace_current_entry(false),
466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      should_set_opener(false) {
467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NavigateParams::~NavigateParams() {}
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FillNavigateParamsFromOpenURLParams(chrome::NavigateParams* nav_params,
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const content::OpenURLParams& params) {
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nav_params->referrer = params.referrer;
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  nav_params->frame_tree_node_id = params.frame_tree_node_id;
4751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  nav_params->redirect_chain = params.redirect_chain;
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nav_params->extra_headers = params.extra_headers;
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nav_params->disposition = params.disposition;
478a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  nav_params->trusted_source = false;
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nav_params->is_renderer_initiated = params.is_renderer_initiated;
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nav_params->transferred_global_request_id =
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params.transferred_global_request_id;
482ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  nav_params->should_replace_current_entry =
483ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      params.should_replace_current_entry;
484a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  nav_params->uses_post = params.uses_post;
485a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  nav_params->browser_initiated_post_data = params.browser_initiated_post_data;
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Navigate(NavigateParams* params) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* source_browser = params->browser;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (source_browser)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->initiating_profile = source_browser->profile();
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(params->initiating_profile);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!AdjustNavigateParamsForURL(params))
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const extensions::Extension* extension =
49823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    extensions::ExtensionRegistry::Get(params->initiating_profile)->
49923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        enabled_extensions().GetExtensionOrAppByURL(params->url);
50023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Platform apps cannot navigate. Block the request.
50123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (extension && extension->is_platform_app())
50223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    params->url = GURL(chrome::kExtensionInvalidRequestURL);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The browser window may want to adjust the disposition.
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->disposition == NEW_POPUP &&
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      source_browser &&
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      source_browser->window()) {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->disposition =
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        source_browser->window()->GetDispositionForPopupBounds(
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            params->window_bounds);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params->browser = GetBrowserForDisposition(params);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params->browser)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(USE_ASH)
518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (source_browser && source_browser != params->browser) {
519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // When the newly created browser was spawned by a browser which visits
520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // another user's desktop, it should be shown on the same desktop as the
521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // originating one. (This is part of the desktop separation per profile).
522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    MultiUserWindowManager* manager = MultiUserWindowManager::GetInstance();
523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Some unit tests have no manager instantiated.
524a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (manager) {
525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      aura::Window* src_window = source_browser->window()->GetNativeWindow();
526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      aura::Window* new_window = params->browser->window()->GetNativeWindow();
527a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const std::string& src_user =
528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          manager->GetUserPresentingWindow(src_window);
529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (src_user != manager->GetUserPresentingWindow(new_window)) {
530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Once the window gets presented, it should be shown on the same
531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // desktop as the desktop of the creating browser. Note that this
532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // command will not show the window if it wasn't shown yet by the
533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // browser creation.
534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        manager->ShowWindowForUser(new_window, src_user);
535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
538a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate() must not return early after this point.
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetSourceProfile(params) != params->browser->profile()) {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A tab is being opened from a link from a different profile, we must reset
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // source information that may cause state to be shared.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->source_contents = NULL;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->referrer = content::Referrer();
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the Browser is shown if params call for it.
5500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ScopedBrowserShower shower(params);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Makes sure any WebContents created by this function is destroyed if
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not properly added to a tab strip.
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedTargetContentsOwner target_contents_owner(params);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Some dispositions need coercion to base types.
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NormalizeDisposition(params);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // If a new window has been created, it needs to be shown.
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->window_action == NavigateParams::NO_ACTION &&
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      source_browser != params->browser &&
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params->browser->tab_strip_model()->empty()) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->window_action = NavigateParams::SHOW_WINDOW;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we create a popup window from a non user-gesture, don't activate it.
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->window_action == NavigateParams::SHOW_WINDOW &&
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params->disposition == NEW_POPUP &&
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params->user_gesture == false) {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->window_action = NavigateParams::SHOW_WINDOW_INACTIVE;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Determine if the navigation was user initiated. If it was, we need to
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // inform the target WebContents, and we may need to update the UI.
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::PageTransition base_transition =
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PageTransitionStripQualifier(params->transition);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool user_initiated =
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params->transition & content::PAGE_TRANSITION_FROM_ADDRESS_BAR ||
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_transition == content::PAGE_TRANSITION_TYPED ||
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_transition == content::PAGE_TRANSITION_AUTO_BOOKMARK ||
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_transition == content::PAGE_TRANSITION_GENERATED ||
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_transition == content::PAGE_TRANSITION_AUTO_TOPLEVEL ||
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_transition == content::PAGE_TRANSITION_RELOAD ||
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_transition == content::PAGE_TRANSITION_KEYWORD;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if this is a singleton tab that already exists
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int singleton_index = chrome::GetIndexOfSingletonTab(params);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Did we use a prerender?
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool swapped_in_prerender = false;
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If no target WebContents was specified, we need to construct one if
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we are supposed to target a new tab; unless it's a singleton that already
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // exists.
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params->target_contents && singleton_index < 0) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (params->url.is_empty()) {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url = params->browser->profile()->GetHomePage();
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params->transition = content::PageTransitionFromInt(
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          params->transition | content::PAGE_TRANSITION_HOME_PAGE);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url = params->url;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (params->disposition != CURRENT_TAB) {
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      params->target_contents = CreateTargetContents(*params, url);
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This function takes ownership of |params->target_contents| until it
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // is added to a TabStripModel.
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target_contents_owner.TakeOwnership();
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ... otherwise if we're loading in the current tab, the target is the
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // same as the source.
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK(params->source_contents);
6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      params->target_contents = params->source_contents;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(params->target_contents);
6178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      // Prerender expects |params->target_contents| to be attached to a browser
6188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      // window, so only call for CURRENT_TAB navigations. (Others are currently
6198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      // unsupported because of session storage namespaces anyway.)
620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Notice that this includes middle-clicking, since middle clicking
621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // translates into a chrome::Navigate call with no URL followed by a
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // CURRENT_TAB navigation.
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // TODO(tburkard): We can actually swap in in non-CURRENT_TAB cases, as
624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // long as the WebContents we swap into is part of a TabStrip model.
625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Therefore, we should swap in regardless of CURRENT_TAB, and instead,
626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // check in the swapin function whether the WebContents is not in a
627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // TabStrip model, in which case we must not swap in.
6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      swapped_in_prerender = SwapInPrerender(url, params);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (user_initiated)
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params->target_contents->UserGestureDone();
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!swapped_in_prerender) {
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Try to handle non-navigational URLs that popup dialogs and such, these
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // should not actually navigate.
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!HandleNonNavigationAboutURL(url)) {
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // Perform the actual navigation, tracking whether it came from the
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // renderer.
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LoadURLInContents(params->target_contents, url, params);
642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // For prerender bookkeeping purposes, record that this pending navigate
643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // originated from chrome::Navigate.
644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        content::NavigationEntry* entry =
645a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            params->target_contents->GetController().GetPendingEntry();
646a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        if (entry)
647a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          entry->SetExtraData(prerender::kChromeNavigateExtraDataKey,
648a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              base::string16());
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // |target_contents| was specified non-NULL, and so we assume it has already
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // been navigated appropriately. We need to do nothing more other than
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // add it to the appropriate tabstrip.
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the user navigated from the omnibox, and the selected tab is going to
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // lose focus, then make sure the focus for the source tab goes away from the
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // omnibox.
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->source_contents &&
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (params->disposition == NEW_FOREGROUND_TAB ||
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       params->disposition == NEW_WINDOW) &&
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (params->tabstrip_add_types & TabStripModel::ADD_INHERIT_OPENER))
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params->source_contents->GetView()->Focus();
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params->source_contents == params->target_contents ||
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      (swapped_in_prerender && params->disposition == CURRENT_TAB)) {
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The navigation occurred in the source tab.
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params->browser->UpdateUIForNavigationInTab(params->target_contents,
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                params->transition,
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                user_initiated);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (singleton_index == -1) {
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If some non-default value is set for the index, we should tell the
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TabStripModel to respect it.
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (params->tabstrip_index != -1)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params->tabstrip_add_types |= TabStripModel::ADD_FORCE_INDEX;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The navigation should insert a new tab into the target Browser.
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params->browser->tab_strip_model()->AddWebContents(
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        params->target_contents,
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        params->tabstrip_index,
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        params->transition,
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        params->tabstrip_add_types);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now that the |params->target_contents| is safely owned by the target
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Browser's TabStripModel, we can release ownership.
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target_contents_owner.ReleaseOwnership();
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (singleton_index >= 0) {
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents* target =
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        params->browser->tab_strip_model()->GetWebContentsAt(singleton_index);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (target->IsCrashed()) {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target->GetController().Reload(true);
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (params->path_behavior == NavigateParams::IGNORE_AND_NAVIGATE &&
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        target->GetURL() != params->url) {
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadURLInContents(target, params->url, params);
698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // For prerender bookkeeping purposes, record that this pending navigate
699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // originated from chrome::Navigate.
700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      content::NavigationEntry* entry =
701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          target->GetController().GetPendingEntry();
702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (entry)
703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        entry->SetExtraData(prerender::kChromeNavigateExtraDataKey,
704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            base::string16());
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the singleton tab isn't already selected, select it.
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (params->source_contents != params->target_contents) {
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params->browser->tab_strip_model()->ActivateTabAt(singleton_index,
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        user_initiated);
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->disposition != CURRENT_TAB) {
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::NotificationService::current()->Notify(
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome::NOTIFICATION_TAB_ADDED,
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<content::WebContentsDelegate>(params->browser),
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Details<WebContents>(params->target_contents));
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsURLAllowedInIncognito(const GURL& url,
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             content::BrowserContext* browser_context) {
724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (url.scheme() == content::kViewSourceScheme) {
725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // A view-source URL is allowed in incognito mode only if the URL itself
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // is allowed in incognito mode. Remove the "view-source:" from the start
727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // of the URL and validate the rest.
728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string stripped_spec = url.spec();
729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK_GT(stripped_spec.size(), strlen(content::kViewSourceScheme));
730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    stripped_spec.erase(0, strlen(content::kViewSourceScheme) + 1);
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GURL stripped_url(stripped_spec);
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return stripped_url.is_valid() &&
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        IsURLAllowedInIncognito(stripped_url, browser_context);
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Most URLs are allowed in incognito; the following are exceptions.
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chrome://extensions is on the list because it redirects to
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chrome://settings.
7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (url.scheme() == content::kChromeUIScheme &&
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (url.host() == chrome::kChromeUISettingsHost ||
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       url.host() == chrome::kChromeUISettingsFrameHost ||
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       url.host() == chrome::kChromeUIExtensionsHost ||
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       url.host() == chrome::kChromeUIBookmarksHost ||
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(OS_CHROMEOS)
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       url.host() == chrome::kChromeUIChromeSigninHost ||
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       url.host() == chrome::kChromeUIUberHost ||
7471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       url.host() == chrome::kChromeUIThumbnailHost ||
7481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       url.host() == chrome::kChromeUIThumbnailHost2 ||
749a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       url.host() == chrome::kChromeUIThumbnailListHost ||
750a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch       url.host() == chrome::kChromeUISuggestionsHost ||
751a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch       url.host() == chrome::kChromeUIDevicesHost)) {
7521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
7541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (url.scheme() == chrome::kChromeSearchScheme &&
7561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      (url.host() == chrome::kChromeUIThumbnailHost ||
7571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       url.host() == chrome::kChromeUIThumbnailHost2 ||
758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       url.host() == chrome::kChromeUIThumbnailListHost ||
759a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       url.host() == chrome::kChromeUISuggestionsHost)) {
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL rewritten_url = url;
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool reverse_on_redirect = false;
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserURLHandler::GetInstance()->RewriteURLIfNecessary(
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &rewritten_url, browser_context, &reverse_on_redirect);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Some URLs are mapped to uber subpages. Do not allow them in incognito.
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return !(rewritten_url.scheme() == content::kChromeUIScheme &&
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           rewritten_url.host() == chrome::kChromeUIUberHost);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
774