1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/search/search.h"
7 #include "base/command_line.h"
8 #include "base/metrics/field_trial.h"
9 #include "base/metrics/histogram.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/search/instant_service.h"
18 #include "chrome/browser/search/instant_service_factory.h"
19 #include "chrome/browser/search_engines/template_url_service_factory.h"
20 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_instant_controller.h"
23 #include "chrome/browser/ui/browser_iterator.h"
24 #include "chrome/browser/ui/search/instant_search_prerenderer.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/common/search_urls.h"
28 #include "chrome/common/url_constants.h"
29 #include "components/google/core/browser/google_util.h"
30 #include "components/pref_registry/pref_registry_syncable.h"
31 #include "components/search/search.h"
32 #include "components/search_engines/template_url_service.h"
33 #include "components/sessions/serialized_navigation_entry.h"
34 #include "content/public/browser/navigation_entry.h"
35 #include "content/public/browser/render_process_host.h"
36 #include "content/public/browser/web_contents.h"
38 #if defined(ENABLE_SUPERVISED_USERS)
39 #include "chrome/browser/supervised_user/supervised_user_service.h"
40 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
41 #include "chrome/browser/supervised_user/supervised_user_url_filter.h"
48 const char kPrefetchSearchResultsOnSRP
[] = "prefetch_results_srp";
49 const char kAllowPrefetchNonDefaultMatch
[] = "allow_prefetch_non_default_match";
50 const char kPrerenderInstantUrlOnOmniboxFocus
[] =
51 "prerender_instant_url_on_omnibox_focus";
53 #if defined(OS_ANDROID)
54 const char kPrefetchSearchResultsFlagName
[] = "prefetch_results";
56 // Controls whether to reuse prerendered Instant Search base page to commit any
58 const char kReuseInstantSearchBasePage
[] = "reuse_instant_search_base_page";
61 // Controls whether to use the alternate Instant search base URL. This allows
62 // experimentation of Instant search.
63 const char kUseAltInstantURL
[] = "use_alternate_instant_url";
64 const char kUseSearchPathForInstant
[] = "use_search_path_for_instant";
65 const char kAltInstantURLPath
[] = "search";
66 const char kAltInstantURLQueryParams
[] = "&qbp=1";
68 #if !defined(OS_IOS) && !defined(OS_ANDROID)
69 const char kEnableQueryExtractionFlagName
[] = "query_extraction";
71 const char kShouldShowGoogleLocalNTPFlagName
[] = "google_local_ntp";
73 // Status of the New Tab URL for the default Search provider. NOTE: Used in a
74 // UMA histogram so values should only be added at the end and not reordered.
76 // Valid URL that should be used.
77 NEW_TAB_URL_VALID
= 0,
79 // Corrupt state (e.g. no profile or template url).
82 // URL should not be used because in incognito window.
83 NEW_TAB_URL_INCOGNITO
= 2,
85 // No New Tab URL set for provider.
86 NEW_TAB_URL_NOT_SET
= 3,
89 NEW_TAB_URL_INSECURE
= 4,
91 // URL should not be used because Suggest is disabled.
92 // Not used anymore, see crbug.com/340424.
93 // NEW_TAB_URL_SUGGEST_OFF = 5,
95 // URL should not be used because it is blocked for a supervised user.
96 NEW_TAB_URL_BLOCKED
= 6,
101 // Used to set the Instant support state of the Navigation entry.
102 const char kInstantSupportStateKey
[] = "instant_support_state";
104 const char kInstantSupportEnabled
[] = "Instant support enabled";
105 const char kInstantSupportDisabled
[] = "Instant support disabled";
106 const char kInstantSupportUnknown
[] = "Instant support unknown";
108 InstantSupportState
StringToInstantSupportState(const base::string16
& value
) {
109 if (value
== base::ASCIIToUTF16(kInstantSupportEnabled
))
110 return INSTANT_SUPPORT_YES
;
111 else if (value
== base::ASCIIToUTF16(kInstantSupportDisabled
))
112 return INSTANT_SUPPORT_NO
;
114 return INSTANT_SUPPORT_UNKNOWN
;
117 base::string16
InstantSupportStateToString(InstantSupportState state
) {
119 case INSTANT_SUPPORT_NO
:
120 return base::ASCIIToUTF16(kInstantSupportDisabled
);
121 case INSTANT_SUPPORT_YES
:
122 return base::ASCIIToUTF16(kInstantSupportEnabled
);
123 case INSTANT_SUPPORT_UNKNOWN
:
124 return base::ASCIIToUTF16(kInstantSupportUnknown
);
126 return base::ASCIIToUTF16(kInstantSupportUnknown
);
129 TemplateURL
* GetDefaultSearchProviderTemplateURL(Profile
* profile
) {
131 TemplateURLService
* template_url_service
=
132 TemplateURLServiceFactory::GetForProfile(profile
);
133 if (template_url_service
)
134 return template_url_service
->GetDefaultSearchProvider();
139 GURL
TemplateURLRefToGURL(const TemplateURLRef
& ref
,
140 const SearchTermsData
& search_terms_data
,
141 bool append_extra_query_params
,
142 bool force_instant_results
) {
143 TemplateURLRef::SearchTermsArgs search_terms_args
=
144 TemplateURLRef::SearchTermsArgs(base::string16());
145 search_terms_args
.append_extra_query_params
= append_extra_query_params
;
146 search_terms_args
.force_instant_results
= force_instant_results
;
147 return GURL(ref
.ReplaceSearchTerms(search_terms_args
, search_terms_data
));
150 bool MatchesAnySearchURL(const GURL
& url
,
151 TemplateURL
* template_url
,
152 const SearchTermsData
& search_terms_data
) {
153 GURL search_url
= TemplateURLRefToGURL(template_url
->url_ref(),
154 search_terms_data
, false, false);
155 if (search_url
.is_valid() &&
156 search::MatchesOriginAndPath(url
, search_url
))
159 // "URLCount() - 1" because we already tested url_ref above.
160 for (size_t i
= 0; i
< template_url
->URLCount() - 1; ++i
) {
161 TemplateURLRef
ref(template_url
, i
);
162 search_url
= TemplateURLRefToGURL(ref
, search_terms_data
, false, false);
163 if (search_url
.is_valid() &&
164 search::MatchesOriginAndPath(url
, search_url
))
173 // |url| should either have a secure scheme or have a non-HTTPS base URL that
174 // the user specified using --google-base-url. (This allows testers to use
175 // --google-base-url to point at non-HTTPS servers, which eases testing.)
176 bool IsSuitableURLForInstant(const GURL
& url
, const TemplateURL
* template_url
) {
177 return template_url
->HasSearchTermsReplacementKey(url
) &&
178 (url
.SchemeIsSecure() ||
179 google_util::StartsWithCommandLineGoogleBaseURL(url
));
182 // Returns true if |url| can be used as an Instant URL for |profile|.
183 bool IsInstantURL(const GURL
& url
, Profile
* profile
) {
184 if (!IsInstantExtendedAPIEnabled())
190 const GURL
new_tab_url(GetNewTabPageURL(profile
));
191 if (new_tab_url
.is_valid() &&
192 search::MatchesOriginAndPath(url
, new_tab_url
))
195 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
199 if (!IsSuitableURLForInstant(url
, template_url
))
202 const TemplateURLRef
& instant_url_ref
= template_url
->instant_url_ref();
203 UIThreadSearchTermsData
search_terms_data(profile
);
204 const GURL instant_url
= TemplateURLRefToGURL(
205 instant_url_ref
, search_terms_data
, false, false);
206 if (!instant_url
.is_valid())
209 if (search::MatchesOriginAndPath(url
, instant_url
))
212 return IsQueryExtractionEnabled() &&
213 MatchesAnySearchURL(url
, template_url
, search_terms_data
);
216 base::string16
GetSearchTermsImpl(const content::WebContents
* contents
,
217 const content::NavigationEntry
* entry
) {
218 if (!contents
|| !IsQueryExtractionEnabled())
219 return base::string16();
221 // For security reasons, don't extract search terms if the page is not being
222 // rendered in the privileged Instant renderer process. This is to protect
223 // against a malicious page somehow scripting the search results page and
224 // faking search terms in the URL. Random pages can't get into the Instant
225 // renderer and scripting doesn't work cross-process, so if the page is in
226 // the Instant process, we know it isn't being exploited.
227 Profile
* profile
= Profile::FromBrowserContext(contents
->GetBrowserContext());
228 if (IsInstantExtendedAPIEnabled() &&
229 !IsRenderedInInstantProcess(contents
, profile
) &&
230 ((entry
== contents
->GetController().GetLastCommittedEntry()) ||
231 !ShouldAssignURLToInstantRenderer(entry
->GetURL(), profile
)))
232 return base::string16();
234 // Check to see if search terms have already been extracted.
235 base::string16 search_terms
= GetSearchTermsFromNavigationEntry(entry
);
236 if (!search_terms
.empty())
239 if (!IsQueryExtractionAllowedForURL(profile
, entry
->GetVirtualURL()))
240 return base::string16();
242 // Otherwise, extract from the URL.
243 return ExtractSearchTermsFromURL(profile
, entry
->GetVirtualURL());
246 bool IsURLAllowedForSupervisedUser(const GURL
& url
, Profile
* profile
) {
247 #if defined(ENABLE_SUPERVISED_USERS)
248 SupervisedUserService
* supervised_user_service
=
249 SupervisedUserServiceFactory::GetForProfile(profile
);
250 SupervisedUserURLFilter
* url_filter
=
251 supervised_user_service
->GetURLFilterForUIThread();
252 if (url_filter
->GetFilteringBehaviorForURL(url
) ==
253 SupervisedUserURLFilter::BLOCK
) {
260 // Returns whether |new_tab_url| can be used as a URL for the New Tab page.
261 // NEW_TAB_URL_VALID means a valid URL; other enum values imply an invalid URL.
262 NewTabURLState
IsValidNewTabURL(Profile
* profile
, const GURL
& new_tab_url
) {
263 if (profile
->IsOffTheRecord())
264 return NEW_TAB_URL_INCOGNITO
;
265 if (!new_tab_url
.is_valid())
266 return NEW_TAB_URL_NOT_SET
;
267 if (!new_tab_url
.SchemeIsSecure())
268 return NEW_TAB_URL_INSECURE
;
269 if (!IsURLAllowedForSupervisedUser(new_tab_url
, profile
))
270 return NEW_TAB_URL_BLOCKED
;
271 return NEW_TAB_URL_VALID
;
274 // Used to look up the URL to use for the New Tab page. Also tracks how we
275 // arrived at that URL so it can be logged with UMA.
276 struct NewTabURLDetails
{
277 NewTabURLDetails(const GURL
& url
, NewTabURLState state
)
278 : url(url
), state(state
) {}
280 static NewTabURLDetails
ForProfile(Profile
* profile
) {
281 const GURL
local_url(chrome::kChromeSearchLocalNtpUrl
);
282 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
283 if (!profile
|| !template_url
)
284 return NewTabURLDetails(local_url
, NEW_TAB_URL_BAD
);
286 GURL search_provider_url
= TemplateURLRefToGURL(
287 template_url
->new_tab_url_ref(), UIThreadSearchTermsData(profile
),
289 NewTabURLState state
= IsValidNewTabURL(profile
, search_provider_url
);
291 case NEW_TAB_URL_VALID
:
292 // We can use the search provider's page.
293 return NewTabURLDetails(search_provider_url
, state
);
294 case NEW_TAB_URL_INCOGNITO
:
295 // Incognito has its own New Tab.
296 return NewTabURLDetails(GURL(), state
);
298 // Use the local New Tab otherwise.
299 return NewTabURLDetails(local_url
, state
);
304 NewTabURLState state
;
309 // Negative start-margin values prevent the "es_sm" parameter from being used.
310 const int kDisableStartMargin
= -1;
312 std::string
InstantExtendedEnabledParam(bool for_search
) {
313 if (for_search
&& !chrome::IsQueryExtractionEnabled())
314 return std::string();
315 return std::string(google_util::kInstantExtendedAPIParam
) + "=" +
316 base::Uint64ToString(EmbeddedSearchPageVersion()) + "&";
319 std::string
ForceInstantResultsParam(bool for_prerender
) {
320 return (for_prerender
|| !IsInstantExtendedAPIEnabled()) ?
321 "ion=1&" : std::string();
324 bool IsQueryExtractionEnabled() {
325 #if defined(OS_IOS) || defined(OS_ANDROID)
328 if (!IsInstantExtendedAPIEnabled())
331 const base::CommandLine
* command_line
=
332 base::CommandLine::ForCurrentProcess();
333 if (command_line
->HasSwitch(switches::kEnableQueryExtraction
))
336 FieldTrialFlags flags
;
337 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
338 kEnableQueryExtractionFlagName
, false, flags
);
339 #endif // defined(OS_IOS) || defined(OS_ANDROID)
342 base::string16
ExtractSearchTermsFromURL(Profile
* profile
, const GURL
& url
) {
343 if (url
.is_valid() && url
== GetSearchResultPrefetchBaseURL(profile
)) {
344 // InstantSearchPrerenderer has the search query for the Instant search base
346 InstantSearchPrerenderer
* prerenderer
=
347 InstantSearchPrerenderer::GetForProfile(profile
);
348 // TODO(kmadhusu): Remove this CHECK after the investigation of
351 return prerenderer
->get_last_query();
354 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
355 base::string16 search_terms
;
357 template_url
->ExtractSearchTermsFromURL(
358 url
, UIThreadSearchTermsData(profile
), &search_terms
);
362 bool IsQueryExtractionAllowedForURL(Profile
* profile
, const GURL
& url
) {
363 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
364 return template_url
&& IsSuitableURLForInstant(url
, template_url
);
367 base::string16
GetSearchTermsFromNavigationEntry(
368 const content::NavigationEntry
* entry
) {
369 base::string16 search_terms
;
371 entry
->GetExtraData(sessions::kSearchTermsKey
, &search_terms
);
375 base::string16
GetSearchTerms(const content::WebContents
* contents
) {
377 return base::string16();
379 const content::NavigationEntry
* entry
=
380 contents
->GetController().GetVisibleEntry();
382 return base::string16();
384 if (IsInstantExtendedAPIEnabled()) {
385 InstantSupportState state
=
386 GetInstantSupportStateFromNavigationEntry(*entry
);
387 if (state
== INSTANT_SUPPORT_NO
)
388 return base::string16();
391 return GetSearchTermsImpl(contents
, entry
);
394 bool ShouldAssignURLToInstantRenderer(const GURL
& url
, Profile
* profile
) {
395 return url
.is_valid() &&
397 IsInstantExtendedAPIEnabled() &&
398 (url
.SchemeIs(chrome::kChromeSearchScheme
) ||
399 IsInstantURL(url
, profile
));
402 bool IsRenderedInInstantProcess(const content::WebContents
* contents
,
404 const content::RenderProcessHost
* process_host
=
405 contents
->GetRenderProcessHost();
409 const InstantService
* instant_service
=
410 InstantServiceFactory::GetForProfile(profile
);
411 if (!instant_service
)
414 return instant_service
->IsInstantProcess(process_host
->GetID());
417 bool ShouldUseProcessPerSiteForInstantURL(const GURL
& url
, Profile
* profile
) {
418 return ShouldAssignURLToInstantRenderer(url
, profile
) &&
419 (url
.host() == chrome::kChromeSearchLocalNtpHost
||
420 url
.host() == chrome::kChromeSearchRemoteNtpHost
);
423 bool IsNTPURL(const GURL
& url
, Profile
* profile
) {
427 if (!IsInstantExtendedAPIEnabled())
428 return url
== GURL(chrome::kChromeUINewTabURL
);
430 const base::string16 search_terms
= ExtractSearchTermsFromURL(profile
, url
);
432 ((IsInstantURL(url
, profile
) && search_terms
.empty()) ||
433 url
== GURL(chrome::kChromeSearchLocalNtpUrl
));
436 bool IsInstantNTP(const content::WebContents
* contents
) {
440 return NavEntryIsInstantNTP(contents
,
441 contents
->GetController().GetVisibleEntry());
444 bool NavEntryIsInstantNTP(const content::WebContents
* contents
,
445 const content::NavigationEntry
* entry
) {
446 if (!contents
|| !entry
|| !IsInstantExtendedAPIEnabled())
449 Profile
* profile
= Profile::FromBrowserContext(contents
->GetBrowserContext());
450 if (!IsRenderedInInstantProcess(contents
, profile
))
453 if (entry
->GetURL() == GetLocalInstantURL(profile
))
456 GURL
new_tab_url(GetNewTabPageURL(profile
));
457 return new_tab_url
.is_valid() &&
458 search::MatchesOriginAndPath(entry
->GetURL(), new_tab_url
);
461 bool IsSuggestPrefEnabled(Profile
* profile
) {
462 return profile
&& !profile
->IsOffTheRecord() && profile
->GetPrefs() &&
463 profile
->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled
);
466 GURL
GetInstantURL(Profile
* profile
, bool force_instant_results
) {
467 if (!IsInstantExtendedAPIEnabled() || !IsSuggestPrefEnabled(profile
))
470 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
474 GURL instant_url
= TemplateURLRefToGURL(
475 template_url
->instant_url_ref(), UIThreadSearchTermsData(profile
),
476 true, force_instant_results
);
477 if (!instant_url
.is_valid() ||
478 !template_url
->HasSearchTermsReplacementKey(instant_url
))
481 // Extended mode requires HTTPS. Force it unless the base URL was overridden
482 // on the command line, in which case we allow HTTP (see comments on
483 // IsSuitableURLForInstant()).
484 if (!instant_url
.SchemeIsSecure() &&
485 !google_util::StartsWithCommandLineGoogleBaseURL(instant_url
)) {
486 GURL::Replacements replacements
;
487 replacements
.SetSchemeStr(url::kHttpsScheme
);
488 instant_url
= instant_url
.ReplaceComponents(replacements
);
491 if (!IsURLAllowedForSupervisedUser(instant_url
, profile
))
494 if (ShouldUseAltInstantURL()) {
495 GURL::Replacements replacements
;
496 const std::string
path(
497 ShouldUseSearchPathForInstant() ? kAltInstantURLPath
: std::string());
499 replacements
.SetPathStr(path
);
500 const std::string
query(
501 instant_url
.query() + std::string(kAltInstantURLQueryParams
));
502 replacements
.SetQueryStr(query
);
503 instant_url
= instant_url
.ReplaceComponents(replacements
);
508 // Returns URLs associated with the default search engine for |profile|.
509 std::vector
<GURL
> GetSearchURLs(Profile
* profile
) {
510 std::vector
<GURL
> result
;
511 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
514 for (size_t i
= 0; i
< template_url
->URLCount(); ++i
) {
515 TemplateURLRef
ref(template_url
, i
);
516 result
.push_back(TemplateURLRefToGURL(ref
, UIThreadSearchTermsData(profile
),
522 GURL
GetNewTabPageURL(Profile
* profile
) {
523 return NewTabURLDetails::ForProfile(profile
).url
;
526 GURL
GetSearchResultPrefetchBaseURL(Profile
* profile
) {
527 return ShouldPrefetchSearchResults() ? GetInstantURL(profile
, true) : GURL();
530 bool ShouldPrefetchSearchResults() {
531 if (!IsInstantExtendedAPIEnabled())
534 #if defined(OS_ANDROID)
535 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
536 switches::kPrefetchSearchResults
)) {
540 FieldTrialFlags flags
;
541 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
542 kPrefetchSearchResultsFlagName
, false, flags
);
548 bool ShouldAllowPrefetchNonDefaultMatch() {
549 if (!ShouldPrefetchSearchResults())
552 FieldTrialFlags flags
;
553 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
554 kAllowPrefetchNonDefaultMatch
, false, flags
);
557 bool ShouldPrerenderInstantUrlOnOmniboxFocus() {
558 if (!ShouldPrefetchSearchResults())
561 FieldTrialFlags flags
;
562 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
563 kPrerenderInstantUrlOnOmniboxFocus
, false, flags
);
566 bool ShouldReuseInstantSearchBasePage() {
567 if (!ShouldPrefetchSearchResults())
570 #if defined(OS_ANDROID)
571 FieldTrialFlags flags
;
572 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
573 kReuseInstantSearchBasePage
, false, flags
);
579 GURL
GetLocalInstantURL(Profile
* profile
) {
580 return GURL(chrome::kChromeSearchLocalNtpUrl
);
583 bool ShouldShowGoogleLocalNTP() {
584 FieldTrialFlags flags
;
585 return !GetFieldTrialInfo(&flags
) || GetBoolValueForFlagWithDefault(
586 kShouldShowGoogleLocalNTPFlagName
, true, flags
);
589 GURL
GetEffectiveURLForInstant(const GURL
& url
, Profile
* profile
) {
590 CHECK(ShouldAssignURLToInstantRenderer(url
, profile
))
591 << "Error granting Instant access.";
593 if (url
.SchemeIs(chrome::kChromeSearchScheme
))
596 GURL
effective_url(url
);
598 // Replace the scheme with "chrome-search:".
599 url::Replacements
<char> replacements
;
600 std::string
search_scheme(chrome::kChromeSearchScheme
);
601 replacements
.SetScheme(search_scheme
.data(),
602 url::Component(0, search_scheme
.length()));
604 // If this is the URL for a server-provided NTP, replace the host with
606 std::string
remote_ntp_host(chrome::kChromeSearchRemoteNtpHost
);
607 NewTabURLDetails details
= NewTabURLDetails::ForProfile(profile
);
608 if (details
.state
== NEW_TAB_URL_VALID
&&
609 search::MatchesOriginAndPath(url
, details
.url
)) {
610 replacements
.SetHost(remote_ntp_host
.c_str(),
611 url::Component(0, remote_ntp_host
.length()));
614 effective_url
= effective_url
.ReplaceComponents(replacements
);
615 return effective_url
;
618 bool HandleNewTabURLRewrite(GURL
* url
,
619 content::BrowserContext
* browser_context
) {
620 if (!IsInstantExtendedAPIEnabled())
623 if (!url
->SchemeIs(content::kChromeUIScheme
) ||
624 url
->host() != chrome::kChromeUINewTabHost
)
627 Profile
* profile
= Profile::FromBrowserContext(browser_context
);
628 NewTabURLDetails
details(NewTabURLDetails::ForProfile(profile
));
629 UMA_HISTOGRAM_ENUMERATION("NewTabPage.URLState",
630 details
.state
, NEW_TAB_URL_MAX
);
631 if (details
.url
.is_valid()) {
638 bool HandleNewTabURLReverseRewrite(GURL
* url
,
639 content::BrowserContext
* browser_context
) {
640 if (!IsInstantExtendedAPIEnabled())
643 // Do nothing in incognito.
644 Profile
* profile
= Profile::FromBrowserContext(browser_context
);
645 if (profile
&& profile
->IsOffTheRecord())
648 if (search::MatchesOriginAndPath(
649 GURL(chrome::kChromeSearchLocalNtpUrl
), *url
)) {
650 *url
= GURL(chrome::kChromeUINewTabURL
);
654 GURL
new_tab_url(GetNewTabPageURL(profile
));
655 if (new_tab_url
.is_valid() &&
656 search::MatchesOriginAndPath(new_tab_url
, *url
)) {
657 *url
= GURL(chrome::kChromeUINewTabURL
);
664 void SetInstantSupportStateInNavigationEntry(InstantSupportState state
,
665 content::NavigationEntry
* entry
) {
669 entry
->SetExtraData(kInstantSupportStateKey
,
670 InstantSupportStateToString(state
));
673 InstantSupportState
GetInstantSupportStateFromNavigationEntry(
674 const content::NavigationEntry
& entry
) {
675 base::string16 value
;
676 if (!entry
.GetExtraData(kInstantSupportStateKey
, &value
))
677 return INSTANT_SUPPORT_UNKNOWN
;
679 return StringToInstantSupportState(value
);
682 bool ShouldPrefetchSearchResultsOnSRP() {
683 FieldTrialFlags flags
;
684 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
685 kPrefetchSearchResultsOnSRP
, false, flags
);
688 void EnableQueryExtractionForTesting() {
689 base::CommandLine
* cl
= base::CommandLine::ForCurrentProcess();
690 cl
->AppendSwitch(switches::kEnableQueryExtraction
);
693 bool ShouldUseAltInstantURL() {
694 FieldTrialFlags flags
;
695 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
696 kUseAltInstantURL
, false, flags
);
699 bool ShouldUseSearchPathForInstant() {
700 FieldTrialFlags flags
;
701 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
702 kUseSearchPathForInstant
, false, flags
);
705 } // namespace chrome