| Index: chrome/browser/ui/search/search.cc
|
| diff --git a/chrome/browser/ui/search/search.cc b/chrome/browser/ui/search/search.cc
|
| deleted file mode 100644
|
| index 6544bd1423f326f6311f8b8561ca1cc0404ec09f..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/ui/search/search.cc
|
| +++ /dev/null
|
| @@ -1,530 +0,0 @@
|
| -// Copyright 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/ui/search/search.h"
|
| -
|
| -#include "base/command_line.h"
|
| -#include "base/metrics/field_trial.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/prefs/pref_service.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/string_split.h"
|
| -#include "chrome/browser/instant/instant_service.h"
|
| -#include "chrome/browser/instant/instant_service_factory.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/search_engines/template_url_service.h"
|
| -#include "chrome/browser/search_engines/template_url_service_factory.h"
|
| -#include "chrome/common/chrome_switches.h"
|
| -#include "chrome/common/pref_names.h"
|
| -#include "chrome/common/url_constants.h"
|
| -#include "components/user_prefs/pref_registry_syncable.h"
|
| -#include "content/public/browser/navigation_entry.h"
|
| -#include "content/public/browser/render_process_host.h"
|
| -#include "content/public/browser/web_contents.h"
|
| -
|
| -namespace chrome {
|
| -namespace search {
|
| -
|
| -namespace {
|
| -
|
| -// The default value we should assign to the instant_extended.enabled pref. As
|
| -// with other prefs, the default is used only when the user hasn't toggled the
|
| -// pref explicitly.
|
| -enum InstantExtendedDefault {
|
| - INSTANT_DEFAULT_ON, // Default the pref to be enabled.
|
| - INSTANT_USE_EXISTING, // Use the current value of the instant.enabled pref.
|
| - INSTANT_DEFAULT_OFF, // Default the pref to be disabled.
|
| -};
|
| -
|
| -// Configuration options for Embedded Search.
|
| -// InstantExtended field trials are named in such a way that we can parse out
|
| -// the experiment configuration from the trial's group name in order to give
|
| -// us maximum flexability in running experiments.
|
| -// Field trial groups should be named things like "Group7 espv:2 instant:1".
|
| -// The first token is always GroupN for some integer N, followed by a
|
| -// space-delimited list of key:value pairs which correspond to these flags:
|
| -const char kEmbeddedPageVersionFlagName[] = "espv";
|
| -const uint64 kEmbeddedPageVersionDisabled = 0;
|
| -const uint64 kEmbeddedPageVersionDefault = 2;
|
| -
|
| -const char kInstantExtendedActivationName[] = "instant";
|
| -const InstantExtendedDefault kInstantExtendedActivationDefault =
|
| - INSTANT_DEFAULT_ON;
|
| -
|
| -// Constants for the field trial name and group prefix.
|
| -const char kInstantExtendedFieldTrialName[] = "InstantExtended";
|
| -const char kGroupNumberPrefix[] = "Group";
|
| -
|
| -// If the field trial's group name ends with this string its configuration will
|
| -// be ignored and Instant Extended will not be enabled by default.
|
| -const char kDisablingSuffix[] = "DISABLED";
|
| -
|
| -TemplateURL* GetDefaultSearchProviderTemplateURL(Profile* profile) {
|
| - TemplateURLService* template_url_service =
|
| - TemplateURLServiceFactory::GetForProfile(profile);
|
| - if (template_url_service)
|
| - return template_url_service->GetDefaultSearchProvider();
|
| - return NULL;
|
| -}
|
| -
|
| -GURL TemplateURLRefToGURL(const TemplateURLRef& ref) {
|
| - return GURL(
|
| - ref.ReplaceSearchTerms(TemplateURLRef::SearchTermsArgs(string16())));
|
| -}
|
| -
|
| -bool MatchesOriginAndPath(const GURL& my_url, const GURL& other_url) {
|
| - return my_url.host() == other_url.host() &&
|
| - my_url.port() == other_url.port() &&
|
| - my_url.path() == other_url.path() &&
|
| - (my_url.scheme() == other_url.scheme() ||
|
| - (my_url.SchemeIs(chrome::kHttpsScheme) &&
|
| - other_url.SchemeIs(chrome::kHttpScheme)));
|
| -}
|
| -
|
| -bool IsCommandLineInstantURL(const GURL& url) {
|
| - const CommandLine* cl = CommandLine::ForCurrentProcess();
|
| - const GURL instant_url(cl->GetSwitchValueASCII(switches::kInstantURL));
|
| - return instant_url.is_valid() && MatchesOriginAndPath(url, instant_url);
|
| -}
|
| -
|
| -bool MatchesAnySearchURL(const GURL& url, TemplateURL* template_url) {
|
| - GURL search_url = TemplateURLRefToGURL(template_url->url_ref());
|
| - if (search_url.is_valid() && MatchesOriginAndPath(url, search_url))
|
| - return true;
|
| -
|
| - // "URLCount() - 1" because we already tested url_ref above.
|
| - for (size_t i = 0; i < template_url->URLCount() - 1; ++i) {
|
| - TemplateURLRef ref(template_url, i);
|
| - search_url = TemplateURLRefToGURL(ref);
|
| - if (search_url.is_valid() && MatchesOriginAndPath(url, search_url))
|
| - return true;
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| -enum OptInState {
|
| - NOT_SET, // The user has not manually opted into or out of InstantExtended.
|
| - OPT_IN, // The user has opted-in to InstantExtended.
|
| - OPT_OUT, // The user has opted-out of InstantExtended.
|
| - OPT_IN_STATE_ENUM_COUNT,
|
| -};
|
| -
|
| -void RecordInstantExtendedOptInState(OptInState state) {
|
| - static bool recorded = false;
|
| - if (!recorded) {
|
| - recorded = true;
|
| - UMA_HISTOGRAM_ENUMERATION("InstantExtended.OptInState", state,
|
| - OPT_IN_STATE_ENUM_COUNT);
|
| - }
|
| -}
|
| -
|
| -// Returns true if |contents| is rendered inside the Instant process for
|
| -// |profile|.
|
| -bool IsRenderedInInstantProcess(const content::WebContents* contents,
|
| - Profile* profile) {
|
| - const content::RenderProcessHost* process_host =
|
| - contents->GetRenderProcessHost();
|
| - if (!process_host)
|
| - return false;
|
| -
|
| - const InstantService* instant_service =
|
| - InstantServiceFactory::GetForProfile(profile);
|
| - if (!instant_service)
|
| - return false;
|
| -
|
| - return instant_service->IsInstantProcess(process_host->GetID());
|
| -}
|
| -
|
| -// Returns true if |url| can be used as an Instant URL for |profile|.
|
| -bool IsInstantURL(const GURL& url, Profile* profile) {
|
| - TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
|
| - if (!template_url)
|
| - return false;
|
| -
|
| - const TemplateURLRef& instant_url_ref = template_url->instant_url_ref();
|
| - const bool extended_api_enabled = IsInstantExtendedAPIEnabled();
|
| - GURL effective_url = url;
|
| -
|
| - if (IsCommandLineInstantURL(url))
|
| - effective_url = CoerceCommandLineURLToTemplateURL(url, instant_url_ref);
|
| -
|
| - if (!effective_url.is_valid())
|
| - return false;
|
| -
|
| - if (extended_api_enabled && !effective_url.SchemeIsSecure())
|
| - return false;
|
| -
|
| - if (extended_api_enabled &&
|
| - !template_url->HasSearchTermsReplacementKey(effective_url))
|
| - return false;
|
| -
|
| - const GURL instant_url = TemplateURLRefToGURL(instant_url_ref);
|
| - if (!instant_url.is_valid())
|
| - return false;
|
| -
|
| - if (MatchesOriginAndPath(effective_url, instant_url))
|
| - return true;
|
| -
|
| - if (extended_api_enabled && MatchesAnySearchURL(effective_url, template_url))
|
| - return true;
|
| -
|
| - return false;
|
| -}
|
| -
|
| -string16 GetSearchTermsImpl(const content::WebContents* contents,
|
| - const content::NavigationEntry* entry) {
|
| - if (!IsQueryExtractionEnabled())
|
| - return string16();
|
| -
|
| - // For security reasons, don't extract search terms if the page is not being
|
| - // rendered in the privileged Instant renderer process. This is to protect
|
| - // against a malicious page somehow scripting the search results page and
|
| - // faking search terms in the URL. Random pages can't get into the Instant
|
| - // renderer and scripting doesn't work cross-process, so if the page is in
|
| - // the Instant process, we know it isn't being exploited.
|
| - Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
|
| - if (!IsRenderedInInstantProcess(contents, profile))
|
| - return string16();
|
| -
|
| - // Check to see if search terms have already been extracted.
|
| - string16 search_terms = GetSearchTermsFromNavigationEntry(entry);
|
| - if (!search_terms.empty())
|
| - return search_terms;
|
| -
|
| - // Otherwise, extract from the URL.
|
| - TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
|
| - if (!template_url)
|
| - return string16();
|
| -
|
| - GURL url = entry->GetVirtualURL();
|
| -
|
| - if (IsCommandLineInstantURL(url))
|
| - url = CoerceCommandLineURLToTemplateURL(url, template_url->url_ref());
|
| -
|
| - if (url.SchemeIsSecure() && template_url->HasSearchTermsReplacementKey(url))
|
| - template_url->ExtractSearchTermsFromURL(url, &search_terms);
|
| -
|
| - return search_terms;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -const char kInstantExtendedSearchTermsKey[] = "search_terms";
|
| -
|
| -const char kLocalOmniboxPopupURL[] =
|
| - "chrome://local-omnibox-popup/local-omnibox-popup.html";
|
| -
|
| -bool IsInstantExtendedAPIEnabled() {
|
| - return EmbeddedSearchPageVersion() != kEmbeddedPageVersionDisabled;
|
| -}
|
| -
|
| -// Determine what embedded search page version to request from the user's
|
| -// default search provider. If 0, the embedded search UI should not be enabled.
|
| -uint64 EmbeddedSearchPageVersion() {
|
| - // Check the command-line/about:flags setting first, which should have
|
| - // precedence and allows the trial to not be reported (if it's never queried).
|
| - const CommandLine* command_line = CommandLine::ForCurrentProcess();
|
| - if (command_line->HasSwitch(switches::kDisableInstantExtendedAPI)) {
|
| - RecordInstantExtendedOptInState(OPT_OUT);
|
| - return kEmbeddedPageVersionDisabled;
|
| - }
|
| - if (command_line->HasSwitch(switches::kEnableInstantExtendedAPI)) {
|
| - // The user has set the about:flags switch to Enabled - give the default
|
| - // UI version.
|
| - RecordInstantExtendedOptInState(OPT_IN);
|
| - return kEmbeddedPageVersionDefault;
|
| - }
|
| -
|
| - RecordInstantExtendedOptInState(NOT_SET);
|
| - FieldTrialFlags flags;
|
| - if (GetFieldTrialInfo(
|
| - base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName),
|
| - &flags, NULL)) {
|
| - return GetUInt64ValueForFlagWithDefault(kEmbeddedPageVersionFlagName,
|
| - kEmbeddedPageVersionDefault,
|
| - flags);
|
| - }
|
| -
|
| - return kEmbeddedPageVersionDisabled;
|
| -}
|
| -
|
| -bool IsQueryExtractionEnabled() {
|
| -#if defined(OS_IOS)
|
| - const CommandLine* cl = CommandLine::ForCurrentProcess();
|
| - return cl->HasSwitch(switches::kEnableQueryExtraction);
|
| -#else
|
| - // On desktop, query extraction is controlled by the instant-extended-api
|
| - // flag.
|
| - return IsInstantExtendedAPIEnabled();
|
| -#endif
|
| -}
|
| -
|
| -string16 GetSearchTermsFromNavigationEntry(
|
| - const content::NavigationEntry* entry) {
|
| - string16 search_terms;
|
| - if (entry)
|
| - entry->GetExtraData(kInstantExtendedSearchTermsKey, &search_terms);
|
| - return search_terms;
|
| -}
|
| -
|
| -string16 GetSearchTerms(const content::WebContents* contents) {
|
| - if (!contents)
|
| - return string16();
|
| -
|
| - const content::NavigationEntry* entry =
|
| - contents->GetController().GetVisibleEntry();
|
| - if (!entry)
|
| - return string16();
|
| -
|
| - return GetSearchTermsImpl(contents, entry);
|
| -}
|
| -
|
| -bool IsInstantNTP(const content::WebContents* contents) {
|
| - if (!contents)
|
| - return false;
|
| -
|
| - return NavEntryIsInstantNTP(contents,
|
| - contents->GetController().GetVisibleEntry());
|
| -}
|
| -
|
| -bool NavEntryIsInstantNTP(const content::WebContents* contents,
|
| - const content::NavigationEntry* entry) {
|
| - if (!contents || !entry)
|
| - return false;
|
| -
|
| - Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
|
| - return IsInstantExtendedAPIEnabled() &&
|
| - IsRenderedInInstantProcess(contents, profile) &&
|
| - IsInstantURL(entry->GetVirtualURL(), profile) &&
|
| - GetSearchTermsImpl(contents, entry).empty();
|
| -}
|
| -
|
| -bool ShouldAssignURLToInstantRenderer(const GURL& url, Profile* profile) {
|
| - return url.is_valid() &&
|
| - profile &&
|
| - (url.SchemeIs(chrome::kChromeSearchScheme) ||
|
| - IsInstantURL(url, profile) ||
|
| - (IsInstantExtendedAPIEnabled() &&
|
| - url == GURL(kLocalOmniboxPopupURL)));
|
| -}
|
| -
|
| -void RegisterUserPrefs(PrefRegistrySyncable* registry) {
|
| - registry->RegisterBooleanPref(prefs::kInstantConfirmDialogShown, false,
|
| - PrefRegistrySyncable::SYNCABLE_PREF);
|
| - registry->RegisterBooleanPref(prefs::kInstantEnabled, false,
|
| - PrefRegistrySyncable::SYNCABLE_PREF);
|
| - // This default is overridden by SetInstantExtendedPrefDefault().
|
| - registry->RegisterBooleanPref(prefs::kInstantExtendedEnabled, false,
|
| - PrefRegistrySyncable::SYNCABLE_PREF);
|
| -}
|
| -
|
| -const char* GetInstantPrefName() {
|
| - return IsInstantExtendedAPIEnabled() ? prefs::kInstantExtendedEnabled :
|
| - prefs::kInstantEnabled;
|
| -}
|
| -
|
| -bool IsInstantPrefEnabled(Profile* profile) {
|
| - if (!profile || profile->IsOffTheRecord())
|
| - return false;
|
| -
|
| - const PrefService* prefs = profile->GetPrefs();
|
| - if (!prefs)
|
| - return false;
|
| -
|
| - return prefs->GetBoolean(GetInstantPrefName());
|
| -}
|
| -
|
| -void SetInstantExtendedPrefDefault(Profile* profile) {
|
| - PrefService* prefs = profile ? profile->GetPrefs() : NULL;
|
| - if (!prefs)
|
| - return;
|
| -
|
| - bool pref_default = false;
|
| -
|
| - // Check the command-line/about:flags setting first, which should have
|
| - // precedence and allows the trial to not be reported (if it's never queried).
|
| - const CommandLine* command_line = CommandLine::ForCurrentProcess();
|
| - if (command_line->HasSwitch(switches::kEnableInstantExtendedAPI)) {
|
| - pref_default = true;
|
| - } else if (!command_line->HasSwitch(switches::kDisableInstantExtendedAPI)) {
|
| - uint64 trial_default = kInstantExtendedActivationDefault;
|
| -
|
| - FieldTrialFlags flags;
|
| - if (GetFieldTrialInfo(
|
| - base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName),
|
| - &flags, NULL)) {
|
| - trial_default = GetUInt64ValueForFlagWithDefault(
|
| - kInstantExtendedActivationName,
|
| - kInstantExtendedActivationDefault,
|
| - flags);
|
| - }
|
| -
|
| - if (trial_default == INSTANT_DEFAULT_ON) {
|
| - pref_default = true;
|
| - } else if (trial_default != INSTANT_DEFAULT_OFF) {
|
| - pref_default = prefs->GetBoolean(prefs::kInstantEnabled);
|
| - }
|
| - }
|
| -
|
| - prefs->SetDefaultPrefValue(prefs::kInstantExtendedEnabled,
|
| - Value::CreateBooleanValue(pref_default));
|
| -}
|
| -
|
| -GURL GetInstantURL(Profile* profile) {
|
| - const bool extended_api_enabled = IsInstantExtendedAPIEnabled();
|
| -
|
| - const PrefService* prefs = profile && !profile->IsOffTheRecord() ?
|
| - profile->GetPrefs() : NULL;
|
| - if (!IsInstantPrefEnabled(profile) &&
|
| - !(extended_api_enabled && prefs &&
|
| - prefs->GetBoolean(prefs::kSearchSuggestEnabled)))
|
| - return GURL();
|
| -
|
| - TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
|
| - if (!template_url)
|
| - return GURL();
|
| -
|
| - CommandLine* cl = CommandLine::ForCurrentProcess();
|
| - if (cl->HasSwitch(switches::kInstantURL)) {
|
| - GURL instant_url(cl->GetSwitchValueASCII(switches::kInstantURL));
|
| - if (extended_api_enabled) {
|
| - // Extended mode won't work if the search terms replacement key is absent.
|
| - GURL coerced_url = CoerceCommandLineURLToTemplateURL(
|
| - instant_url, template_url->instant_url_ref());
|
| - if (!template_url->HasSearchTermsReplacementKey(coerced_url))
|
| - return GURL();
|
| - }
|
| - return instant_url;
|
| - }
|
| -
|
| - GURL instant_url = TemplateURLRefToGURL(template_url->instant_url_ref());
|
| -
|
| - if (extended_api_enabled) {
|
| - // Extended mode won't work if the search terms replacement key is absent.
|
| - if (!template_url->HasSearchTermsReplacementKey(instant_url))
|
| - return GURL();
|
| -
|
| - // Extended mode requires HTTPS. Force it if necessary.
|
| - if (!instant_url.SchemeIsSecure()) {
|
| - const std::string secure_scheme = chrome::kHttpsScheme;
|
| - GURL::Replacements replacements;
|
| - replacements.SetSchemeStr(secure_scheme);
|
| - instant_url = instant_url.ReplaceComponents(replacements);
|
| - }
|
| - }
|
| -
|
| - return instant_url;
|
| -}
|
| -
|
| -bool IsInstantEnabled(Profile* profile) {
|
| - return GetInstantURL(profile).is_valid();
|
| -}
|
| -
|
| -void EnableInstantExtendedAPIForTesting() {
|
| - CommandLine* cl = CommandLine::ForCurrentProcess();
|
| - cl->AppendSwitch(switches::kEnableInstantExtendedAPI);
|
| -}
|
| -
|
| -void EnableQueryExtractionForTesting() {
|
| -#if defined(OS_IOS)
|
| - CommandLine* cl = CommandLine::ForCurrentProcess();
|
| - cl->AppendSwitch(switches::kEnableQueryExtraction);
|
| -#else
|
| - EnableInstantExtendedAPIForTesting();
|
| -#endif
|
| -}
|
| -
|
| -bool GetFieldTrialInfo(const std::string& group_name,
|
| - FieldTrialFlags* flags,
|
| - uint64* group_number) {
|
| - if (EndsWith(group_name, kDisablingSuffix, true) ||
|
| - !StartsWithASCII(group_name, kGroupNumberPrefix, true))
|
| - return false;
|
| -
|
| - // We have a valid trial that starts with "Group" and isn't disabled.
|
| - // First extract the flags.
|
| - std::string group_prefix(group_name);
|
| -
|
| - size_t first_space = group_name.find(" ");
|
| - if (first_space != std::string::npos) {
|
| - // There is a flags section of the group name. Split that out and parse it.
|
| - group_prefix = group_name.substr(0, first_space);
|
| - if (!base::SplitStringIntoKeyValuePairs(group_name.substr(first_space),
|
| - ':', ' ', flags)) {
|
| - // Failed to parse the flags section. Assume the whole group name is
|
| - // invalid.
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - // Now extract the group number, making sure we get a non-zero value.
|
| - uint64 temp_group_number = 0;
|
| - std::string group_suffix = group_prefix.substr(strlen(kGroupNumberPrefix));
|
| - if (!base::StringToUint64(group_suffix, &temp_group_number) ||
|
| - temp_group_number == 0)
|
| - return false;
|
| -
|
| - if (group_number)
|
| - *group_number = temp_group_number;
|
| -
|
| - return true;
|
| -}
|
| -
|
| -// Given a FieldTrialFlags object, returns the string value of the provided
|
| -// flag.
|
| -std::string GetStringValueForFlagWithDefault(const std::string& flag,
|
| - const std::string& default_value,
|
| - const FieldTrialFlags& flags) {
|
| - FieldTrialFlags::const_iterator i;
|
| - for (i = flags.begin(); i != flags.end(); i++) {
|
| - if (i->first == flag)
|
| - return i->second;
|
| - }
|
| - return default_value;
|
| -}
|
| -
|
| -// Given a FieldTrialFlags object, returns the uint64 value of the provided
|
| -// flag.
|
| -uint64 GetUInt64ValueForFlagWithDefault(const std::string& flag,
|
| - uint64 default_value,
|
| - const FieldTrialFlags& flags) {
|
| - uint64 value;
|
| - std::string str_value = GetStringValueForFlagWithDefault(flag, "", flags);
|
| - if (base::StringToUint64(str_value, &value))
|
| - return value;
|
| - return default_value;
|
| -}
|
| -
|
| -// Given a FieldTrialFlags object, returns the boolean value of the provided
|
| -// flag.
|
| -bool GetBoolValueForFlagWithDefault(const std::string& flag,
|
| - bool default_value,
|
| - const FieldTrialFlags& flags) {
|
| - return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags);
|
| -}
|
| -
|
| -// Coerces the commandline Instant URL to look like a template URL, so that we
|
| -// can extract search terms from it.
|
| -GURL CoerceCommandLineURLToTemplateURL(const GURL& instant_url,
|
| - const TemplateURLRef& ref) {
|
| - GURL search_url = TemplateURLRefToGURL(ref);
|
| - // NOTE(samarth): GURL returns temporaries which we must save because
|
| - // GURL::Replacements expects the replacements to live until
|
| - // ReplaceComponents is called.
|
| - const std::string search_scheme = chrome::kHttpsScheme;
|
| - const std::string search_host = search_url.host();
|
| - const std::string search_port = search_url.port();
|
| - const std::string search_path = search_url.path();
|
| -
|
| - GURL::Replacements replacements;
|
| - replacements.SetSchemeStr(search_scheme);
|
| - replacements.SetHostStr(search_host);
|
| - replacements.SetPortStr(search_port);
|
| - replacements.SetPathStr(search_path);
|
| - return instant_url.ReplaceComponents(replacements);
|
| -}
|
| -
|
| -} // namespace search
|
| -} // namespace chrome
|
|
|