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_MANAGED_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 const char kDisplaySearchButtonFlagName
[] = "display_search_button";
69 const char kOriginChipFlagName
[] = "origin_chip";
70 #if !defined(OS_IOS) && !defined(OS_ANDROID)
71 const char kEnableQueryExtractionFlagName
[] = "query_extraction";
73 const char kShouldShowGoogleLocalNTPFlagName
[] = "google_local_ntp";
75 // Status of the New Tab URL for the default Search provider. NOTE: Used in a
76 // UMA histogram so values should only be added at the end and not reordered.
78 // Valid URL that should be used.
79 NEW_TAB_URL_VALID
= 0,
81 // Corrupt state (e.g. no profile or template url).
84 // URL should not be used because in incognito window.
85 NEW_TAB_URL_INCOGNITO
= 2,
87 // No New Tab URL set for provider.
88 NEW_TAB_URL_NOT_SET
= 3,
91 NEW_TAB_URL_INSECURE
= 4,
93 // URL should not be used because Suggest is disabled.
94 // Not used anymore, see crbug.com/340424.
95 // NEW_TAB_URL_SUGGEST_OFF = 5,
97 // URL should not be used because it is blocked for a supervised user.
98 NEW_TAB_URL_BLOCKED
= 6,
103 // Used to set the Instant support state of the Navigation entry.
104 const char kInstantSupportStateKey
[] = "instant_support_state";
106 const char kInstantSupportEnabled
[] = "Instant support enabled";
107 const char kInstantSupportDisabled
[] = "Instant support disabled";
108 const char kInstantSupportUnknown
[] = "Instant support unknown";
110 InstantSupportState
StringToInstantSupportState(const base::string16
& value
) {
111 if (value
== base::ASCIIToUTF16(kInstantSupportEnabled
))
112 return INSTANT_SUPPORT_YES
;
113 else if (value
== base::ASCIIToUTF16(kInstantSupportDisabled
))
114 return INSTANT_SUPPORT_NO
;
116 return INSTANT_SUPPORT_UNKNOWN
;
119 base::string16
InstantSupportStateToString(InstantSupportState state
) {
121 case INSTANT_SUPPORT_NO
:
122 return base::ASCIIToUTF16(kInstantSupportDisabled
);
123 case INSTANT_SUPPORT_YES
:
124 return base::ASCIIToUTF16(kInstantSupportEnabled
);
125 case INSTANT_SUPPORT_UNKNOWN
:
126 return base::ASCIIToUTF16(kInstantSupportUnknown
);
128 return base::ASCIIToUTF16(kInstantSupportUnknown
);
131 TemplateURL
* GetDefaultSearchProviderTemplateURL(Profile
* profile
) {
133 TemplateURLService
* template_url_service
=
134 TemplateURLServiceFactory::GetForProfile(profile
);
135 if (template_url_service
)
136 return template_url_service
->GetDefaultSearchProvider();
141 GURL
TemplateURLRefToGURL(const TemplateURLRef
& ref
,
142 const SearchTermsData
& search_terms_data
,
143 bool append_extra_query_params
,
144 bool force_instant_results
) {
145 TemplateURLRef::SearchTermsArgs search_terms_args
=
146 TemplateURLRef::SearchTermsArgs(base::string16());
147 search_terms_args
.append_extra_query_params
= append_extra_query_params
;
148 search_terms_args
.force_instant_results
= force_instant_results
;
149 return GURL(ref
.ReplaceSearchTerms(search_terms_args
, search_terms_data
));
152 bool MatchesAnySearchURL(const GURL
& url
,
153 TemplateURL
* template_url
,
154 const SearchTermsData
& search_terms_data
) {
155 GURL search_url
= TemplateURLRefToGURL(template_url
->url_ref(),
156 search_terms_data
, false, false);
157 if (search_url
.is_valid() &&
158 search::MatchesOriginAndPath(url
, search_url
))
161 // "URLCount() - 1" because we already tested url_ref above.
162 for (size_t i
= 0; i
< template_url
->URLCount() - 1; ++i
) {
163 TemplateURLRef
ref(template_url
, i
);
164 search_url
= TemplateURLRefToGURL(ref
, search_terms_data
, false, false);
165 if (search_url
.is_valid() &&
166 search::MatchesOriginAndPath(url
, search_url
))
175 // |url| should either have a secure scheme or have a non-HTTPS base URL that
176 // the user specified using --google-base-url. (This allows testers to use
177 // --google-base-url to point at non-HTTPS servers, which eases testing.)
178 bool IsSuitableURLForInstant(const GURL
& url
, const TemplateURL
* template_url
) {
179 return template_url
->HasSearchTermsReplacementKey(url
) &&
180 (url
.SchemeIsSecure() ||
181 google_util::StartsWithCommandLineGoogleBaseURL(url
));
184 // Returns true if |url| can be used as an Instant URL for |profile|.
185 bool IsInstantURL(const GURL
& url
, Profile
* profile
) {
186 if (!IsInstantExtendedAPIEnabled())
192 const GURL
new_tab_url(GetNewTabPageURL(profile
));
193 if (new_tab_url
.is_valid() &&
194 search::MatchesOriginAndPath(url
, new_tab_url
))
197 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
201 if (!IsSuitableURLForInstant(url
, template_url
))
204 const TemplateURLRef
& instant_url_ref
= template_url
->instant_url_ref();
205 UIThreadSearchTermsData
search_terms_data(profile
);
206 const GURL instant_url
= TemplateURLRefToGURL(
207 instant_url_ref
, search_terms_data
, false, false);
208 if (!instant_url
.is_valid())
211 if (search::MatchesOriginAndPath(url
, instant_url
))
214 return IsQueryExtractionEnabled() &&
215 MatchesAnySearchURL(url
, template_url
, search_terms_data
);
218 base::string16
GetSearchTermsImpl(const content::WebContents
* contents
,
219 const content::NavigationEntry
* entry
) {
220 if (!contents
|| !IsQueryExtractionEnabled())
221 return base::string16();
223 // For security reasons, don't extract search terms if the page is not being
224 // rendered in the privileged Instant renderer process. This is to protect
225 // against a malicious page somehow scripting the search results page and
226 // faking search terms in the URL. Random pages can't get into the Instant
227 // renderer and scripting doesn't work cross-process, so if the page is in
228 // the Instant process, we know it isn't being exploited.
229 Profile
* profile
= Profile::FromBrowserContext(contents
->GetBrowserContext());
230 if (IsInstantExtendedAPIEnabled() &&
231 !IsRenderedInInstantProcess(contents
, profile
) &&
232 ((entry
== contents
->GetController().GetLastCommittedEntry()) ||
233 !ShouldAssignURLToInstantRenderer(entry
->GetURL(), profile
)))
234 return base::string16();
236 // Check to see if search terms have already been extracted.
237 base::string16 search_terms
= GetSearchTermsFromNavigationEntry(entry
);
238 if (!search_terms
.empty())
241 if (!IsQueryExtractionAllowedForURL(profile
, entry
->GetVirtualURL()))
242 return base::string16();
244 // Otherwise, extract from the URL.
245 return ExtractSearchTermsFromURL(profile
, entry
->GetVirtualURL());
248 bool IsURLAllowedForSupervisedUser(const GURL
& url
, Profile
* profile
) {
249 #if defined(ENABLE_MANAGED_USERS)
250 SupervisedUserService
* supervised_user_service
=
251 SupervisedUserServiceFactory::GetForProfile(profile
);
252 SupervisedUserURLFilter
* url_filter
=
253 supervised_user_service
->GetURLFilterForUIThread();
254 if (url_filter
->GetFilteringBehaviorForURL(url
) ==
255 SupervisedUserURLFilter::BLOCK
) {
262 // Returns whether |new_tab_url| can be used as a URL for the New Tab page.
263 // NEW_TAB_URL_VALID means a valid URL; other enum values imply an invalid URL.
264 NewTabURLState
IsValidNewTabURL(Profile
* profile
, const GURL
& new_tab_url
) {
265 if (profile
->IsOffTheRecord())
266 return NEW_TAB_URL_INCOGNITO
;
267 if (!new_tab_url
.is_valid())
268 return NEW_TAB_URL_NOT_SET
;
269 if (!new_tab_url
.SchemeIsSecure())
270 return NEW_TAB_URL_INSECURE
;
271 if (!IsURLAllowedForSupervisedUser(new_tab_url
, profile
))
272 return NEW_TAB_URL_BLOCKED
;
273 return NEW_TAB_URL_VALID
;
276 // Used to look up the URL to use for the New Tab page. Also tracks how we
277 // arrived at that URL so it can be logged with UMA.
278 struct NewTabURLDetails
{
279 NewTabURLDetails(const GURL
& url
, NewTabURLState state
)
280 : url(url
), state(state
) {}
282 static NewTabURLDetails
ForProfile(Profile
* profile
) {
283 const GURL
local_url(chrome::kChromeSearchLocalNtpUrl
);
284 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
285 if (!profile
|| !template_url
)
286 return NewTabURLDetails(local_url
, NEW_TAB_URL_BAD
);
288 GURL search_provider_url
= TemplateURLRefToGURL(
289 template_url
->new_tab_url_ref(), UIThreadSearchTermsData(profile
),
291 NewTabURLState state
= IsValidNewTabURL(profile
, search_provider_url
);
293 case NEW_TAB_URL_VALID
:
294 // We can use the search provider's page.
295 return NewTabURLDetails(search_provider_url
, state
);
296 case NEW_TAB_URL_INCOGNITO
:
297 // Incognito has its own New Tab.
298 return NewTabURLDetails(GURL(), state
);
300 // Use the local New Tab otherwise.
301 return NewTabURLDetails(local_url
, state
);
306 NewTabURLState state
;
311 // Negative start-margin values prevent the "es_sm" parameter from being used.
312 const int kDisableStartMargin
= -1;
314 std::string
InstantExtendedEnabledParam(bool for_search
) {
315 if (for_search
&& !chrome::IsQueryExtractionEnabled())
316 return std::string();
317 return std::string(google_util::kInstantExtendedAPIParam
) + "=" +
318 base::Uint64ToString(EmbeddedSearchPageVersion()) + "&";
321 std::string
ForceInstantResultsParam(bool for_prerender
) {
322 return (for_prerender
|| !IsInstantExtendedAPIEnabled()) ?
323 "ion=1&" : std::string();
326 bool IsQueryExtractionEnabled() {
327 #if defined(OS_IOS) || defined(OS_ANDROID)
330 if (!IsInstantExtendedAPIEnabled())
333 const CommandLine
* command_line
= CommandLine::ForCurrentProcess();
334 if (command_line
->HasSwitch(switches::kEnableQueryExtraction
))
337 FieldTrialFlags flags
;
338 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
339 kEnableQueryExtractionFlagName
, false, flags
);
340 #endif // defined(OS_IOS) || defined(OS_ANDROID)
343 base::string16
ExtractSearchTermsFromURL(Profile
* profile
, const GURL
& url
) {
344 if (url
.is_valid() && url
== GetSearchResultPrefetchBaseURL(profile
)) {
345 // InstantSearchPrerenderer has the search query for the Instant search base
347 InstantSearchPrerenderer
* prerenderer
=
348 InstantSearchPrerenderer::GetForProfile(profile
);
349 // TODO(kmadhusu): Remove this CHECK after the investigation of
352 return prerenderer
->get_last_query();
355 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
356 base::string16 search_terms
;
358 template_url
->ExtractSearchTermsFromURL(
359 url
, UIThreadSearchTermsData(profile
), &search_terms
);
363 bool IsQueryExtractionAllowedForURL(Profile
* profile
, const GURL
& url
) {
364 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
365 return template_url
&& IsSuitableURLForInstant(url
, template_url
);
368 base::string16
GetSearchTermsFromNavigationEntry(
369 const content::NavigationEntry
* entry
) {
370 base::string16 search_terms
;
372 entry
->GetExtraData(sessions::kSearchTermsKey
, &search_terms
);
376 base::string16
GetSearchTerms(const content::WebContents
* contents
) {
378 return base::string16();
380 const content::NavigationEntry
* entry
=
381 contents
->GetController().GetVisibleEntry();
383 return base::string16();
385 if (IsInstantExtendedAPIEnabled()) {
386 InstantSupportState state
=
387 GetInstantSupportStateFromNavigationEntry(*entry
);
388 if (state
== INSTANT_SUPPORT_NO
)
389 return base::string16();
392 return GetSearchTermsImpl(contents
, entry
);
395 bool ShouldAssignURLToInstantRenderer(const GURL
& url
, Profile
* profile
) {
396 return url
.is_valid() &&
398 IsInstantExtendedAPIEnabled() &&
399 (url
.SchemeIs(chrome::kChromeSearchScheme
) ||
400 IsInstantURL(url
, profile
));
403 bool IsRenderedInInstantProcess(const content::WebContents
* contents
,
405 const content::RenderProcessHost
* process_host
=
406 contents
->GetRenderProcessHost();
410 const InstantService
* instant_service
=
411 InstantServiceFactory::GetForProfile(profile
);
412 if (!instant_service
)
415 return instant_service
->IsInstantProcess(process_host
->GetID());
418 bool ShouldUseProcessPerSiteForInstantURL(const GURL
& url
, Profile
* profile
) {
419 return ShouldAssignURLToInstantRenderer(url
, profile
) &&
420 (url
.host() == chrome::kChromeSearchLocalNtpHost
||
421 url
.host() == chrome::kChromeSearchRemoteNtpHost
);
424 bool IsNTPURL(const GURL
& url
, Profile
* profile
) {
428 if (!IsInstantExtendedAPIEnabled())
429 return url
== GURL(chrome::kChromeUINewTabURL
);
431 const base::string16 search_terms
= ExtractSearchTermsFromURL(profile
, url
);
433 ((IsInstantURL(url
, profile
) && search_terms
.empty()) ||
434 url
== GURL(chrome::kChromeSearchLocalNtpUrl
));
437 bool IsInstantNTP(const content::WebContents
* contents
) {
441 return NavEntryIsInstantNTP(contents
,
442 contents
->GetController().GetVisibleEntry());
445 bool NavEntryIsInstantNTP(const content::WebContents
* contents
,
446 const content::NavigationEntry
* entry
) {
447 if (!contents
|| !entry
|| !IsInstantExtendedAPIEnabled())
450 Profile
* profile
= Profile::FromBrowserContext(contents
->GetBrowserContext());
451 if (!IsRenderedInInstantProcess(contents
, profile
))
454 if (entry
->GetURL() == GetLocalInstantURL(profile
))
457 GURL
new_tab_url(GetNewTabPageURL(profile
));
458 return new_tab_url
.is_valid() &&
459 search::MatchesOriginAndPath(entry
->GetURL(), new_tab_url
);
462 bool IsSuggestPrefEnabled(Profile
* profile
) {
463 return profile
&& !profile
->IsOffTheRecord() && profile
->GetPrefs() &&
464 profile
->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled
);
467 GURL
GetInstantURL(Profile
* profile
, bool force_instant_results
) {
468 if (!IsInstantExtendedAPIEnabled() || !IsSuggestPrefEnabled(profile
))
471 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
475 GURL instant_url
= TemplateURLRefToGURL(
476 template_url
->instant_url_ref(), UIThreadSearchTermsData(profile
),
477 true, force_instant_results
);
478 if (!instant_url
.is_valid() ||
479 !template_url
->HasSearchTermsReplacementKey(instant_url
))
482 // Extended mode requires HTTPS. Force it unless the base URL was overridden
483 // on the command line, in which case we allow HTTP (see comments on
484 // IsSuitableURLForInstant()).
485 if (!instant_url
.SchemeIsSecure() &&
486 !google_util::StartsWithCommandLineGoogleBaseURL(instant_url
)) {
487 GURL::Replacements replacements
;
488 const std::string
secure_scheme(url::kHttpsScheme
);
489 replacements
.SetSchemeStr(secure_scheme
);
490 instant_url
= instant_url
.ReplaceComponents(replacements
);
493 if (!IsURLAllowedForSupervisedUser(instant_url
, profile
))
496 if (ShouldUseAltInstantURL()) {
497 GURL::Replacements replacements
;
498 const std::string
path(
499 ShouldUseSearchPathForInstant() ? kAltInstantURLPath
: std::string());
501 replacements
.SetPathStr(path
);
502 const std::string
query(
503 instant_url
.query() + std::string(kAltInstantURLQueryParams
));
504 replacements
.SetQueryStr(query
);
505 instant_url
= instant_url
.ReplaceComponents(replacements
);
510 // Returns URLs associated with the default search engine for |profile|.
511 std::vector
<GURL
> GetSearchURLs(Profile
* profile
) {
512 std::vector
<GURL
> result
;
513 TemplateURL
* template_url
= GetDefaultSearchProviderTemplateURL(profile
);
516 for (size_t i
= 0; i
< template_url
->URLCount(); ++i
) {
517 TemplateURLRef
ref(template_url
, i
);
518 result
.push_back(TemplateURLRefToGURL(ref
, UIThreadSearchTermsData(profile
),
524 GURL
GetNewTabPageURL(Profile
* profile
) {
525 return NewTabURLDetails::ForProfile(profile
).url
;
528 GURL
GetSearchResultPrefetchBaseURL(Profile
* profile
) {
529 return ShouldPrefetchSearchResults() ? GetInstantURL(profile
, true) : GURL();
532 bool ShouldPrefetchSearchResults() {
533 if (!IsInstantExtendedAPIEnabled())
536 #if defined(OS_ANDROID)
537 if (CommandLine::ForCurrentProcess()->HasSwitch(
538 switches::kPrefetchSearchResults
)) {
542 FieldTrialFlags flags
;
543 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
544 kPrefetchSearchResultsFlagName
, false, flags
);
550 bool ShouldAllowPrefetchNonDefaultMatch() {
551 if (!ShouldPrefetchSearchResults())
554 FieldTrialFlags flags
;
555 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
556 kAllowPrefetchNonDefaultMatch
, false, flags
);
559 bool ShouldPrerenderInstantUrlOnOmniboxFocus() {
560 if (!ShouldPrefetchSearchResults())
563 FieldTrialFlags flags
;
564 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
565 kPrerenderInstantUrlOnOmniboxFocus
, false, flags
);
568 bool ShouldReuseInstantSearchBasePage() {
569 if (!ShouldPrefetchSearchResults())
572 #if defined(OS_ANDROID)
573 FieldTrialFlags flags
;
574 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
575 kReuseInstantSearchBasePage
, false, flags
);
581 GURL
GetLocalInstantURL(Profile
* profile
) {
582 return GURL(chrome::kChromeSearchLocalNtpUrl
);
585 DisplaySearchButtonConditions
GetDisplaySearchButtonConditions() {
586 const CommandLine
* cl
= CommandLine::ForCurrentProcess();
587 if (cl
->HasSwitch(switches::kDisableSearchButtonInOmnibox
))
588 return DISPLAY_SEARCH_BUTTON_NEVER
;
589 if (cl
->HasSwitch(switches::kEnableSearchButtonInOmniboxForStr
))
590 return DISPLAY_SEARCH_BUTTON_FOR_STR
;
591 if (cl
->HasSwitch(switches::kEnableSearchButtonInOmniboxForStrOrIip
))
592 return DISPLAY_SEARCH_BUTTON_FOR_STR_OR_IIP
;
593 if (cl
->HasSwitch(switches::kEnableSearchButtonInOmniboxAlways
))
594 return DISPLAY_SEARCH_BUTTON_ALWAYS
;
596 FieldTrialFlags flags
;
597 if (!GetFieldTrialInfo(&flags
))
598 return DISPLAY_SEARCH_BUTTON_NEVER
;
600 GetUInt64ValueForFlagWithDefault(kDisplaySearchButtonFlagName
, 0, flags
);
601 return (value
< DISPLAY_SEARCH_BUTTON_NUM_VALUES
) ?
602 static_cast<DisplaySearchButtonConditions
>(value
) :
603 DISPLAY_SEARCH_BUTTON_NEVER
;
606 bool ShouldDisplayOriginChip() {
607 return GetOriginChipCondition() != ORIGIN_CHIP_DISABLED
;
610 OriginChipCondition
GetOriginChipCondition() {
611 const CommandLine
* cl
= CommandLine::ForCurrentProcess();
612 if (cl
->HasSwitch(switches::kDisableOriginChip
))
613 return ORIGIN_CHIP_DISABLED
;
614 if (cl
->HasSwitch(switches::kEnableOriginChipAlways
))
615 return ORIGIN_CHIP_ALWAYS
;
616 if (cl
->HasSwitch(switches::kEnableOriginChipOnSrp
))
617 return ORIGIN_CHIP_ON_SRP
;
619 FieldTrialFlags flags
;
620 if (!GetFieldTrialInfo(&flags
))
621 return ORIGIN_CHIP_DISABLED
;
623 GetUInt64ValueForFlagWithDefault(kOriginChipFlagName
, 0, flags
);
624 return (value
< ORIGIN_CHIP_NUM_VALUES
) ?
625 static_cast<OriginChipCondition
>(value
) : ORIGIN_CHIP_DISABLED
;
628 bool ShouldShowGoogleLocalNTP() {
629 FieldTrialFlags flags
;
630 return !GetFieldTrialInfo(&flags
) || GetBoolValueForFlagWithDefault(
631 kShouldShowGoogleLocalNTPFlagName
, true, flags
);
634 GURL
GetEffectiveURLForInstant(const GURL
& url
, Profile
* profile
) {
635 CHECK(ShouldAssignURLToInstantRenderer(url
, profile
))
636 << "Error granting Instant access.";
638 if (url
.SchemeIs(chrome::kChromeSearchScheme
))
641 GURL
effective_url(url
);
643 // Replace the scheme with "chrome-search:".
644 url::Replacements
<char> replacements
;
645 std::string
search_scheme(chrome::kChromeSearchScheme
);
646 replacements
.SetScheme(search_scheme
.data(),
647 url::Component(0, search_scheme
.length()));
649 // If this is the URL for a server-provided NTP, replace the host with
651 std::string
remote_ntp_host(chrome::kChromeSearchRemoteNtpHost
);
652 NewTabURLDetails details
= NewTabURLDetails::ForProfile(profile
);
653 if (details
.state
== NEW_TAB_URL_VALID
&&
654 search::MatchesOriginAndPath(url
, details
.url
)) {
655 replacements
.SetHost(remote_ntp_host
.c_str(),
656 url::Component(0, remote_ntp_host
.length()));
659 effective_url
= effective_url
.ReplaceComponents(replacements
);
660 return effective_url
;
663 bool HandleNewTabURLRewrite(GURL
* url
,
664 content::BrowserContext
* browser_context
) {
665 if (!IsInstantExtendedAPIEnabled())
668 if (!url
->SchemeIs(content::kChromeUIScheme
) ||
669 url
->host() != chrome::kChromeUINewTabHost
)
672 Profile
* profile
= Profile::FromBrowserContext(browser_context
);
673 NewTabURLDetails
details(NewTabURLDetails::ForProfile(profile
));
674 UMA_HISTOGRAM_ENUMERATION("NewTabPage.URLState",
675 details
.state
, NEW_TAB_URL_MAX
);
676 if (details
.url
.is_valid()) {
683 bool HandleNewTabURLReverseRewrite(GURL
* url
,
684 content::BrowserContext
* browser_context
) {
685 if (!IsInstantExtendedAPIEnabled())
688 // Do nothing in incognito.
689 Profile
* profile
= Profile::FromBrowserContext(browser_context
);
690 if (profile
&& profile
->IsOffTheRecord())
693 if (search::MatchesOriginAndPath(
694 GURL(chrome::kChromeSearchLocalNtpUrl
), *url
)) {
695 *url
= GURL(chrome::kChromeUINewTabURL
);
699 GURL
new_tab_url(GetNewTabPageURL(profile
));
700 if (new_tab_url
.is_valid() &&
701 search::MatchesOriginAndPath(new_tab_url
, *url
)) {
702 *url
= GURL(chrome::kChromeUINewTabURL
);
709 void SetInstantSupportStateInNavigationEntry(InstantSupportState state
,
710 content::NavigationEntry
* entry
) {
714 entry
->SetExtraData(kInstantSupportStateKey
,
715 InstantSupportStateToString(state
));
718 InstantSupportState
GetInstantSupportStateFromNavigationEntry(
719 const content::NavigationEntry
& entry
) {
720 base::string16 value
;
721 if (!entry
.GetExtraData(kInstantSupportStateKey
, &value
))
722 return INSTANT_SUPPORT_UNKNOWN
;
724 return StringToInstantSupportState(value
);
727 bool ShouldPrefetchSearchResultsOnSRP() {
728 FieldTrialFlags flags
;
729 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
730 kPrefetchSearchResultsOnSRP
, false, flags
);
733 void EnableQueryExtractionForTesting() {
734 CommandLine
* cl
= CommandLine::ForCurrentProcess();
735 cl
->AppendSwitch(switches::kEnableQueryExtraction
);
738 bool ShouldUseAltInstantURL() {
739 FieldTrialFlags flags
;
740 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
741 kUseAltInstantURL
, false, flags
);
744 bool ShouldUseSearchPathForInstant() {
745 FieldTrialFlags flags
;
746 return GetFieldTrialInfo(&flags
) && GetBoolValueForFlagWithDefault(
747 kUseSearchPathForInstant
, false, flags
);
750 } // namespace chrome