This source file includes following definitions.
- StringToInstantSupportState
- InstantSupportStateToString
- GetDefaultSearchProviderTemplateURL
- TemplateURLRefToGURL
- MatchesAnySearchURL
- IsRenderedInInstantProcess
- IsSuitableURLForInstant
- IsInstantURL
- GetSearchTermsImpl
- IsURLAllowedForSupervisedUser
- IsValidNewTabURL
- IsInstantExtendedAPIEnabled
- EmbeddedSearchPageVersion
- InstantExtendedEnabledParam
- ForceInstantResultsParam
- IsQueryExtractionEnabled
- ExtractSearchTermsFromURL
- IsQueryExtractionAllowedForURL
- GetSearchTermsFromNavigationEntry
- GetSearchTerms
- ShouldAssignURLToInstantRenderer
- ShouldUseProcessPerSiteForInstantURL
- IsNTPURL
- IsInstantNTP
- NavEntryIsInstantNTP
- IsSuggestPrefEnabled
- GetInstantURL
- GetSearchURLs
- GetNewTabPageURL
- GetSearchResultPrefetchBaseURL
- ShouldPrefetchSearchResults
- ShouldReuseInstantSearchBasePage
- GetLocalInstantURL
- ShouldHideTopVerbatimMatch
- GetDisplaySearchButtonConditions
- ShouldDisplayOriginChip
- GetOriginChipPosition
- ShouldDisplayOriginChipV2
- GetOriginChipV2HideTrigger
- ShouldShowGoogleLocalNTP
- GetEffectiveURLForInstant
- HandleNewTabURLRewrite
- HandleNewTabURLReverseRewrite
- SetInstantSupportStateInNavigationEntry
- GetInstantSupportStateFromNavigationEntry
- ShouldPrefetchSearchResultsOnSRP
- EnableQueryExtractionForTesting
- GetFieldTrialInfo
- GetStringValueForFlagWithDefault
- GetUInt64ValueForFlagWithDefault
- GetBoolValueForFlagWithDefault
#include "chrome/browser/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 "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/search/instant_service.h"
#include "chrome/browser/search/instant_service_factory.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_instant_controller.h"
#include "chrome/browser/ui/browser_iterator.h"
#include "chrome/browser/ui/search/instant_search_prerenderer.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/search_urls.h"
#include "chrome/common/url_constants.h"
#include "components/sessions/serialized_navigation_entry.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"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#if defined(ENABLE_MANAGED_USERS)
#include "chrome/browser/managed_mode/managed_mode_url_filter.h"
#include "chrome/browser/managed_mode/managed_user_service.h"
#include "chrome/browser/managed_mode/managed_user_service_factory.h"
#endif
namespace chrome {
namespace {
const char kEmbeddedPageVersionFlagName[] = "espv";
#if defined(OS_IOS) || defined(OS_ANDROID)
const uint64 kEmbeddedPageVersionDefault = 1;
#else
const uint64 kEmbeddedPageVersionDefault = 2;
#endif
const char kHideVerbatimFlagName[] = "hide_verbatim";
const char kPrefetchSearchResultsFlagName[] = "prefetch_results";
const char kPrefetchSearchResultsOnSRP[] = "prefetch_results_srp";
const char kReuseInstantSearchBasePage[] = "reuse_instant_search_base_page";
const char kDisplaySearchButtonFlagName[] = "display_search_button";
const char kOriginChipFlagName[] = "origin_chip";
const char kOriginChipV2FlagName[] = "origin_chip_v2";
#if !defined(OS_IOS) && !defined(OS_ANDROID)
const char kEnableQueryExtractionFlagName[] = "query_extraction";
#endif
const char kShouldShowGoogleLocalNTPFlagName[] = "google_local_ntp";
const char kInstantExtendedFieldTrialName[] = "InstantExtended";
const char kEmbeddedSearchFieldTrialName[] = "EmbeddedSearch";
const char kDisablingSuffix[] = "DISABLED";
enum NewTabURLState {
NEW_TAB_URL_VALID = 0,
NEW_TAB_URL_BAD = 1,
NEW_TAB_URL_INCOGNITO = 2,
NEW_TAB_URL_NOT_SET = 3,
NEW_TAB_URL_INSECURE = 4,
NEW_TAB_URL_BLOCKED = 6,
NEW_TAB_URL_MAX
};
const char kInstantSupportStateKey[] = "instant_support_state";
const char kInstantSupportEnabled[] = "Instant support enabled";
const char kInstantSupportDisabled[] = "Instant support disabled";
const char kInstantSupportUnknown[] = "Instant support unknown";
InstantSupportState StringToInstantSupportState(const base::string16& value) {
if (value == base::ASCIIToUTF16(kInstantSupportEnabled))
return INSTANT_SUPPORT_YES;
else if (value == base::ASCIIToUTF16(kInstantSupportDisabled))
return INSTANT_SUPPORT_NO;
else
return INSTANT_SUPPORT_UNKNOWN;
}
base::string16 InstantSupportStateToString(InstantSupportState state) {
switch (state) {
case INSTANT_SUPPORT_NO:
return base::ASCIIToUTF16(kInstantSupportDisabled);
case INSTANT_SUPPORT_YES:
return base::ASCIIToUTF16(kInstantSupportEnabled);
case INSTANT_SUPPORT_UNKNOWN:
return base::ASCIIToUTF16(kInstantSupportUnknown);
}
return base::ASCIIToUTF16(kInstantSupportUnknown);
}
TemplateURL* GetDefaultSearchProviderTemplateURL(Profile* profile) {
if (profile) {
TemplateURLService* template_url_service =
TemplateURLServiceFactory::GetForProfile(profile);
if (template_url_service)
return template_url_service->GetDefaultSearchProvider();
}
return NULL;
}
GURL TemplateURLRefToGURL(const TemplateURLRef& ref,
int start_margin,
bool append_extra_query_params,
bool force_instant_results) {
TemplateURLRef::SearchTermsArgs search_terms_args =
TemplateURLRef::SearchTermsArgs(base::string16());
search_terms_args.omnibox_start_margin = start_margin;
search_terms_args.append_extra_query_params = append_extra_query_params;
search_terms_args.force_instant_results = force_instant_results;
return GURL(ref.ReplaceSearchTerms(search_terms_args));
}
bool MatchesAnySearchURL(const GURL& url, TemplateURL* template_url) {
GURL search_url =
TemplateURLRefToGURL(template_url->url_ref(), kDisableStartMargin, false,
false);
if (search_url.is_valid() &&
search::MatchesOriginAndPath(url, search_url))
return true;
for (size_t i = 0; i < template_url->URLCount() - 1; ++i) {
TemplateURLRef ref(template_url, i);
search_url = TemplateURLRefToGURL(ref, kDisableStartMargin, false, false);
if (search_url.is_valid() &&
search::MatchesOriginAndPath(url, search_url))
return true;
}
return false;
}
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());
}
bool IsSuitableURLForInstant(const GURL& url, const TemplateURL* template_url) {
return template_url->HasSearchTermsReplacementKey(url) &&
(url.SchemeIsSecure() ||
google_util::StartsWithCommandLineGoogleBaseURL(url));
}
bool IsInstantURL(const GURL& url, Profile* profile) {
if (!IsInstantExtendedAPIEnabled())
return false;
if (!url.is_valid())
return false;
const GURL new_tab_url(GetNewTabPageURL(profile));
if (new_tab_url.is_valid() &&
search::MatchesOriginAndPath(url, new_tab_url))
return true;
TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
if (!template_url)
return false;
if (!IsSuitableURLForInstant(url, template_url))
return false;
const TemplateURLRef& instant_url_ref = template_url->instant_url_ref();
const GURL instant_url =
TemplateURLRefToGURL(instant_url_ref, kDisableStartMargin, false, false);
if (!instant_url.is_valid())
return false;
if (search::MatchesOriginAndPath(url, instant_url))
return true;
return IsQueryExtractionEnabled() && MatchesAnySearchURL(url, template_url);
}
base::string16 GetSearchTermsImpl(const content::WebContents* contents,
const content::NavigationEntry* entry) {
if (!contents || !IsQueryExtractionEnabled())
return base::string16();
Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
#if !defined(OS_IOS) && !defined(OS_ANDROID)
if (!IsRenderedInInstantProcess(contents, profile) &&
((entry == contents->GetController().GetLastCommittedEntry()) ||
!ShouldAssignURLToInstantRenderer(entry->GetURL(), profile)))
return base::string16();
#endif
base::string16 search_terms = GetSearchTermsFromNavigationEntry(entry);
if (!search_terms.empty())
return search_terms;
if (!IsQueryExtractionAllowedForURL(profile, entry->GetVirtualURL()))
return base::string16();
return ExtractSearchTermsFromURL(profile, entry->GetVirtualURL());
}
bool IsURLAllowedForSupervisedUser(const GURL& url, Profile* profile) {
#if defined(ENABLE_MANAGED_USERS)
ManagedUserService* managed_user_service =
ManagedUserServiceFactory::GetForProfile(profile);
ManagedModeURLFilter* url_filter =
managed_user_service->GetURLFilterForUIThread();
if (url_filter->GetFilteringBehaviorForURL(url) ==
ManagedModeURLFilter::BLOCK) {
return false;
}
#endif
return true;
}
NewTabURLState IsValidNewTabURL(Profile* profile, const GURL& new_tab_url) {
if (profile->IsOffTheRecord())
return NEW_TAB_URL_INCOGNITO;
if (!new_tab_url.is_valid())
return NEW_TAB_URL_NOT_SET;
if (!new_tab_url.SchemeIsSecure())
return NEW_TAB_URL_INSECURE;
if (!IsURLAllowedForSupervisedUser(new_tab_url, profile))
return NEW_TAB_URL_BLOCKED;
return NEW_TAB_URL_VALID;
}
struct NewTabURLDetails {
NewTabURLDetails(const GURL& url, NewTabURLState state)
: url(url), state(state) {}
static NewTabURLDetails ForProfile(Profile* profile) {
const GURL local_url(chrome::kChromeSearchLocalNtpUrl);
TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
if (!profile || !template_url)
return NewTabURLDetails(local_url, NEW_TAB_URL_BAD);
GURL search_provider_url = TemplateURLRefToGURL(
template_url->new_tab_url_ref(), kDisableStartMargin, false, false);
NewTabURLState state = IsValidNewTabURL(profile, search_provider_url);
switch (state) {
case NEW_TAB_URL_VALID:
return NewTabURLDetails(search_provider_url, state);
case NEW_TAB_URL_INCOGNITO:
return NewTabURLDetails(GURL(), state);
default:
return NewTabURLDetails(local_url, state);
};
}
GURL url;
NewTabURLState state;
};
}
const int kDisableStartMargin = -1;
bool IsInstantExtendedAPIEnabled() {
#if defined(OS_IOS) || defined(OS_ANDROID)
return false;
#else
return true;
#endif
}
uint64 EmbeddedSearchPageVersion() {
FieldTrialFlags flags;
if (GetFieldTrialInfo(&flags)) {
return GetUInt64ValueForFlagWithDefault(kEmbeddedPageVersionFlagName,
kEmbeddedPageVersionDefault,
flags);
}
return kEmbeddedPageVersionDefault;
}
std::string InstantExtendedEnabledParam(bool for_search) {
if (for_search && !chrome::IsQueryExtractionEnabled())
return std::string();
return std::string(google_util::kInstantExtendedAPIParam) + "=" +
base::Uint64ToString(EmbeddedSearchPageVersion()) + "&";
}
std::string ForceInstantResultsParam(bool for_prerender) {
return (for_prerender || !IsInstantExtendedAPIEnabled()) ?
"ion=1&" : std::string();
}
bool IsQueryExtractionEnabled() {
#if defined(OS_IOS) || defined(OS_ANDROID)
return true;
#else
if (!IsInstantExtendedAPIEnabled())
return false;
const CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kEnableQueryExtraction))
return true;
FieldTrialFlags flags;
return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault(
kEnableQueryExtractionFlagName, false, flags);
#endif
}
base::string16 ExtractSearchTermsFromURL(Profile* profile, const GURL& url) {
if (url.is_valid() && url == GetSearchResultPrefetchBaseURL(profile)) {
InstantSearchPrerenderer* prerenderer =
InstantSearchPrerenderer::GetForProfile(profile);
DCHECK(prerenderer);
return prerenderer->get_last_query();
}
TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
base::string16 search_terms;
if (template_url)
template_url->ExtractSearchTermsFromURL(url, &search_terms);
return search_terms;
}
bool IsQueryExtractionAllowedForURL(Profile* profile, const GURL& url) {
TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
return template_url && IsSuitableURLForInstant(url, template_url);
}
base::string16 GetSearchTermsFromNavigationEntry(
const content::NavigationEntry* entry) {
base::string16 search_terms;
if (entry)
entry->GetExtraData(sessions::kSearchTermsKey, &search_terms);
return search_terms;
}
base::string16 GetSearchTerms(const content::WebContents* contents) {
if (!contents)
return base::string16();
const content::NavigationEntry* entry =
contents->GetController().GetVisibleEntry();
if (!entry)
return base::string16();
#if !defined(OS_IOS) && !defined(OS_ANDROID)
InstantSupportState state = GetInstantSupportStateFromNavigationEntry(*entry);
if (state == INSTANT_SUPPORT_NO)
return base::string16();
#endif
return GetSearchTermsImpl(contents, entry);
}
bool ShouldAssignURLToInstantRenderer(const GURL& url, Profile* profile) {
return url.is_valid() &&
profile &&
IsInstantExtendedAPIEnabled() &&
(url.SchemeIs(chrome::kChromeSearchScheme) ||
IsInstantURL(url, profile));
}
bool ShouldUseProcessPerSiteForInstantURL(const GURL& url, Profile* profile) {
return ShouldAssignURLToInstantRenderer(url, profile) &&
(url.host() == chrome::kChromeSearchLocalNtpHost ||
url.host() == chrome::kChromeSearchRemoteNtpHost);
}
bool IsNTPURL(const GURL& url, Profile* profile) {
if (!url.is_valid())
return false;
if (!IsInstantExtendedAPIEnabled())
return url == GURL(chrome::kChromeUINewTabURL);
const base::string16 search_terms = ExtractSearchTermsFromURL(profile, url);
return profile &&
((IsInstantURL(url, profile) && search_terms.empty()) ||
url == GURL(chrome::kChromeSearchLocalNtpUrl));
}
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 || !IsInstantExtendedAPIEnabled())
return false;
Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
if (!IsRenderedInInstantProcess(contents, profile))
return false;
if (entry->GetURL() == GetLocalInstantURL(profile))
return true;
GURL new_tab_url(GetNewTabPageURL(profile));
return new_tab_url.is_valid() &&
search::MatchesOriginAndPath(entry->GetURL(), new_tab_url);
}
bool IsSuggestPrefEnabled(Profile* profile) {
return profile && !profile->IsOffTheRecord() && profile->GetPrefs() &&
profile->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled);
}
GURL GetInstantURL(Profile* profile, int start_margin,
bool force_instant_results) {
if (!IsInstantExtendedAPIEnabled() || !IsSuggestPrefEnabled(profile))
return GURL();
TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
if (!template_url)
return GURL();
GURL instant_url =
TemplateURLRefToGURL(template_url->instant_url_ref(), start_margin, true,
force_instant_results);
if (!instant_url.is_valid() ||
!template_url->HasSearchTermsReplacementKey(instant_url))
return GURL();
if (!instant_url.SchemeIsSecure() &&
!google_util::StartsWithCommandLineGoogleBaseURL(instant_url)) {
GURL::Replacements replacements;
const std::string secure_scheme(content::kHttpsScheme);
replacements.SetSchemeStr(secure_scheme);
instant_url = instant_url.ReplaceComponents(replacements);
}
if (!IsURLAllowedForSupervisedUser(instant_url, profile))
return GURL();
return instant_url;
}
std::vector<GURL> GetSearchURLs(Profile* profile) {
std::vector<GURL> result;
TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
if (!template_url)
return result;
for (size_t i = 0; i < template_url->URLCount(); ++i) {
TemplateURLRef ref(template_url, i);
result.push_back(TemplateURLRefToGURL(ref, kDisableStartMargin, false,
false));
}
return result;
}
GURL GetNewTabPageURL(Profile* profile) {
return NewTabURLDetails::ForProfile(profile).url;
}
GURL GetSearchResultPrefetchBaseURL(Profile* profile) {
return ShouldPrefetchSearchResults() ?
GetInstantURL(profile, kDisableStartMargin, true) : GURL();
}
bool ShouldPrefetchSearchResults() {
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kPrefetchSearchResults)) {
return true;
}
FieldTrialFlags flags;
return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault(
kPrefetchSearchResultsFlagName, false, flags);
}
bool ShouldReuseInstantSearchBasePage() {
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kPrefetchSearchResults)) {
return true;
}
if (!ShouldPrefetchSearchResults())
return false;
FieldTrialFlags flags;
return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault(
kReuseInstantSearchBasePage, false, flags);
}
GURL GetLocalInstantURL(Profile* profile) {
return GURL(chrome::kChromeSearchLocalNtpUrl);
}
bool ShouldHideTopVerbatimMatch() {
FieldTrialFlags flags;
return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault(
kHideVerbatimFlagName, false, flags);
}
DisplaySearchButtonConditions GetDisplaySearchButtonConditions() {
const CommandLine* cl = CommandLine::ForCurrentProcess();
if (cl->HasSwitch(switches::kDisableSearchButtonInOmnibox))
return DISPLAY_SEARCH_BUTTON_NEVER;
if (cl->HasSwitch(switches::kEnableSearchButtonInOmniboxForStr))
return DISPLAY_SEARCH_BUTTON_FOR_STR;
if (cl->HasSwitch(switches::kEnableSearchButtonInOmniboxForStrOrIip))
return DISPLAY_SEARCH_BUTTON_FOR_STR_OR_IIP;
if (cl->HasSwitch(switches::kEnableSearchButtonInOmniboxAlways))
return DISPLAY_SEARCH_BUTTON_ALWAYS;
FieldTrialFlags flags;
if (!GetFieldTrialInfo(&flags))
return DISPLAY_SEARCH_BUTTON_NEVER;
uint64 value =
GetUInt64ValueForFlagWithDefault(kDisplaySearchButtonFlagName, 0, flags);
return (value < DISPLAY_SEARCH_BUTTON_NUM_VALUES) ?
static_cast<DisplaySearchButtonConditions>(value) :
DISPLAY_SEARCH_BUTTON_NEVER;
}
bool ShouldDisplayOriginChip() {
return GetOriginChipPosition() != ORIGIN_CHIP_DISABLED;
}
OriginChipPosition GetOriginChipPosition() {
if (ShouldDisplayOriginChipV2())
return ORIGIN_CHIP_DISABLED;
const CommandLine* cl = CommandLine::ForCurrentProcess();
if (cl->HasSwitch(switches::kDisableOriginChip))
return ORIGIN_CHIP_DISABLED;
if (cl->HasSwitch(switches::kEnableOriginChipLeadingLocationBar))
return ORIGIN_CHIP_LEADING_LOCATION_BAR;
if (cl->HasSwitch(switches::kEnableOriginChip) ||
cl->HasSwitch(switches::kEnableOriginChipTrailingLocationBar))
return ORIGIN_CHIP_TRAILING_LOCATION_BAR;
if (cl->HasSwitch(switches::kEnableOriginChipLeadingMenuButton))
return ORIGIN_CHIP_LEADING_MENU_BUTTON;
FieldTrialFlags flags;
if (!GetFieldTrialInfo(&flags))
return ORIGIN_CHIP_DISABLED;
uint64 value =
GetUInt64ValueForFlagWithDefault(kOriginChipFlagName, 0, flags);
return (value < ORIGIN_CHIP_NUM_VALUES) ?
static_cast<OriginChipPosition>(value) :
ORIGIN_CHIP_DISABLED;
}
bool ShouldDisplayOriginChipV2() {
return GetOriginChipV2HideTrigger() != ORIGIN_CHIP_V2_DISABLED;
}
OriginChipV2HideTrigger GetOriginChipV2HideTrigger() {
const CommandLine* cl = CommandLine::ForCurrentProcess();
if (cl->HasSwitch(switches::kDisableOriginChipV2))
return ORIGIN_CHIP_V2_DISABLED;
if (cl->HasSwitch(switches::kEnableOriginChipV2HideOnMouseRelease))
return ORIGIN_CHIP_V2_HIDE_ON_MOUSE_RELEASE;
if (cl->HasSwitch(switches::kEnableOriginChipV2HideOnUserInput))
return ORIGIN_CHIP_V2_HIDE_ON_USER_INPUT;
FieldTrialFlags flags;
if (!GetFieldTrialInfo(&flags))
return ORIGIN_CHIP_V2_DISABLED;
uint64 value =
GetUInt64ValueForFlagWithDefault(kOriginChipV2FlagName, 0, flags);
return (value < ORIGIN_CHIP_V2_NUM_VALUES) ?
static_cast<OriginChipV2HideTrigger>(value) :
ORIGIN_CHIP_V2_DISABLED;
}
bool ShouldShowGoogleLocalNTP() {
FieldTrialFlags flags;
return !GetFieldTrialInfo(&flags) || GetBoolValueForFlagWithDefault(
kShouldShowGoogleLocalNTPFlagName, true, flags);
}
GURL GetEffectiveURLForInstant(const GURL& url, Profile* profile) {
CHECK(ShouldAssignURLToInstantRenderer(url, profile))
<< "Error granting Instant access.";
if (url.SchemeIs(chrome::kChromeSearchScheme))
return url;
GURL effective_url(url);
url_canon::Replacements<char> replacements;
std::string search_scheme(chrome::kChromeSearchScheme);
replacements.SetScheme(search_scheme.data(),
url_parse::Component(0, search_scheme.length()));
std::string remote_ntp_host(chrome::kChromeSearchRemoteNtpHost);
NewTabURLDetails details = NewTabURLDetails::ForProfile(profile);
if (details.state == NEW_TAB_URL_VALID &&
search::MatchesOriginAndPath(url, details.url)) {
replacements.SetHost(remote_ntp_host.c_str(),
url_parse::Component(0, remote_ntp_host.length()));
}
effective_url = effective_url.ReplaceComponents(replacements);
return effective_url;
}
bool HandleNewTabURLRewrite(GURL* url,
content::BrowserContext* browser_context) {
if (!IsInstantExtendedAPIEnabled())
return false;
if (!url->SchemeIs(content::kChromeUIScheme) ||
url->host() != chrome::kChromeUINewTabHost)
return false;
Profile* profile = Profile::FromBrowserContext(browser_context);
NewTabURLDetails details(NewTabURLDetails::ForProfile(profile));
UMA_HISTOGRAM_ENUMERATION("NewTabPage.URLState",
details.state, NEW_TAB_URL_MAX);
if (details.url.is_valid()) {
*url = details.url;
return true;
}
return false;
}
bool HandleNewTabURLReverseRewrite(GURL* url,
content::BrowserContext* browser_context) {
if (!IsInstantExtendedAPIEnabled())
return false;
Profile* profile = Profile::FromBrowserContext(browser_context);
if (profile && profile->IsOffTheRecord())
return false;
if (search::MatchesOriginAndPath(
GURL(chrome::kChromeSearchLocalNtpUrl), *url)) {
*url = GURL(chrome::kChromeUINewTabURL);
return true;
}
GURL new_tab_url(GetNewTabPageURL(profile));
if (new_tab_url.is_valid() &&
search::MatchesOriginAndPath(new_tab_url, *url)) {
*url = GURL(chrome::kChromeUINewTabURL);
return true;
}
return false;
}
void SetInstantSupportStateInNavigationEntry(InstantSupportState state,
content::NavigationEntry* entry) {
if (!entry)
return;
entry->SetExtraData(kInstantSupportStateKey,
InstantSupportStateToString(state));
}
InstantSupportState GetInstantSupportStateFromNavigationEntry(
const content::NavigationEntry& entry) {
base::string16 value;
if (!entry.GetExtraData(kInstantSupportStateKey, &value))
return INSTANT_SUPPORT_UNKNOWN;
return StringToInstantSupportState(value);
}
bool ShouldPrefetchSearchResultsOnSRP() {
FieldTrialFlags flags;
return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault(
kPrefetchSearchResultsOnSRP, false, flags);
}
void EnableQueryExtractionForTesting() {
CommandLine* cl = CommandLine::ForCurrentProcess();
cl->AppendSwitch(switches::kEnableQueryExtraction);
}
bool GetFieldTrialInfo(FieldTrialFlags* flags) {
std::string group_name = base::FieldTrialList::FindFullName(
kEmbeddedSearchFieldTrialName);
if (group_name.empty()) {
group_name = base::FieldTrialList::FindFullName(
kInstantExtendedFieldTrialName);
}
if (EndsWith(group_name, kDisablingSuffix, true))
return false;
std::string group_prefix(group_name);
size_t first_space = group_name.find(" ");
if (first_space != std::string::npos) {
group_prefix = group_name.substr(0, first_space);
if (!base::SplitStringIntoKeyValuePairs(group_name.substr(first_space),
':', ' ', flags)) {
return false;
}
}
return true;
}
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;
}
uint64 GetUInt64ValueForFlagWithDefault(const std::string& flag,
uint64 default_value,
const FieldTrialFlags& flags) {
uint64 value;
std::string str_value =
GetStringValueForFlagWithDefault(flag, std::string(), flags);
if (base::StringToUint64(str_value, &value))
return value;
return default_value;
}
bool GetBoolValueForFlagWithDefault(const std::string& flag,
bool default_value,
const FieldTrialFlags& flags) {
return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags);
}
}