OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/search/search.h" | 5 #include "chrome/browser/search/search.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
| 9 #include "base/metrics/histogram.h" |
9 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
10 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
11 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
12 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
13 #include "chrome/browser/browser_process.h" | 14 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/google/google_util.h" | 15 #include "chrome/browser/google/google_util.h" |
15 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/profiles/profile_manager.h" | 17 #include "chrome/browser/profiles/profile_manager.h" |
17 #include "chrome/browser/search/instant_service.h" | 18 #include "chrome/browser/search/instant_service.h" |
18 #include "chrome/browser/search/instant_service_factory.h" | 19 #include "chrome/browser/search/instant_service_factory.h" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 // Dev & Canary, for now the code accepts both names. | 80 // Dev & Canary, for now the code accepts both names. |
80 // TODO(dcblack): Remove the InstantExtended name once M31 hits the Beta | 81 // TODO(dcblack): Remove the InstantExtended name once M31 hits the Beta |
81 // channel. | 82 // channel. |
82 const char kInstantExtendedFieldTrialName[] = "InstantExtended"; | 83 const char kInstantExtendedFieldTrialName[] = "InstantExtended"; |
83 const char kEmbeddedSearchFieldTrialName[] = "EmbeddedSearch"; | 84 const char kEmbeddedSearchFieldTrialName[] = "EmbeddedSearch"; |
84 | 85 |
85 // If the field trial's group name ends with this string its configuration will | 86 // If the field trial's group name ends with this string its configuration will |
86 // be ignored and Instant Extended will not be enabled by default. | 87 // be ignored and Instant Extended will not be enabled by default. |
87 const char kDisablingSuffix[] = "DISABLED"; | 88 const char kDisablingSuffix[] = "DISABLED"; |
88 | 89 |
| 90 // Status of the New Tab URL for the default Search provider. NOTE: Used in a |
| 91 // UMA histogram so values should only be added at the end and not reordered. |
| 92 enum NewTabURLState { |
| 93 // Valid URL that should be used. |
| 94 NEW_TAB_URL_VALID = 0, |
| 95 |
| 96 // Corrupt state (e.g. no profile or template url). |
| 97 NEW_TAB_URL_BAD = 1, |
| 98 |
| 99 // URL should not be used because in incognito window. |
| 100 NEW_TAB_URL_INCOGNITO = 2, |
| 101 |
| 102 // No New Tab URL set for provider. |
| 103 NEW_TAB_URL_NOT_SET = 3, |
| 104 |
| 105 // URL is not secure. |
| 106 NEW_TAB_URL_INSECURE = 4, |
| 107 |
| 108 // URL should not be used because Suggest is disabled. |
| 109 NEW_TAB_URL_SUGGEST_OFF = 5, |
| 110 |
| 111 // URL should not be used because it is blocked for a supervised user. |
| 112 NEW_TAB_URL_BLOCKED = 6, |
| 113 |
| 114 NEW_TAB_URL_MAX |
| 115 }; |
| 116 |
89 // Used to set the Instant support state of the Navigation entry. | 117 // Used to set the Instant support state of the Navigation entry. |
90 const char kInstantSupportStateKey[] = "instant_support_state"; | 118 const char kInstantSupportStateKey[] = "instant_support_state"; |
91 | 119 |
92 const char kInstantSupportEnabled[] = "Instant support enabled"; | 120 const char kInstantSupportEnabled[] = "Instant support enabled"; |
93 const char kInstantSupportDisabled[] = "Instant support disabled"; | 121 const char kInstantSupportDisabled[] = "Instant support disabled"; |
94 const char kInstantSupportUnknown[] = "Instant support unknown"; | 122 const char kInstantSupportUnknown[] = "Instant support unknown"; |
95 | 123 |
96 InstantSupportState StringToInstantSupportState(const base::string16& value) { | 124 InstantSupportState StringToInstantSupportState(const base::string16& value) { |
97 if (value == base::ASCIIToUTF16(kInstantSupportEnabled)) | 125 if (value == base::ASCIIToUTF16(kInstantSupportEnabled)) |
98 return INSTANT_SUPPORT_YES; | 126 return INSTANT_SUPPORT_YES; |
99 else if (value == base::ASCIIToUTF16(kInstantSupportDisabled)) | 127 else if (value == base::ASCIIToUTF16(kInstantSupportDisabled)) |
100 return INSTANT_SUPPORT_NO; | 128 return INSTANT_SUPPORT_NO; |
101 else | 129 else |
102 return INSTANT_SUPPORT_UNKNOWN; | 130 return INSTANT_SUPPORT_UNKNOWN; |
103 } | 131 } |
104 | 132 |
105 base::string16 InstantSupportStateToString(InstantSupportState state) { | 133 base::string16 InstantSupportStateToString(InstantSupportState state) { |
106 switch (state) { | 134 switch (state) { |
107 case INSTANT_SUPPORT_NO: | 135 case INSTANT_SUPPORT_NO: |
108 return base::ASCIIToUTF16(kInstantSupportDisabled); | 136 return base::ASCIIToUTF16(kInstantSupportDisabled); |
109 case INSTANT_SUPPORT_YES: | 137 case INSTANT_SUPPORT_YES: |
110 return base::ASCIIToUTF16(kInstantSupportEnabled); | 138 return base::ASCIIToUTF16(kInstantSupportEnabled); |
111 case INSTANT_SUPPORT_UNKNOWN: | 139 case INSTANT_SUPPORT_UNKNOWN: |
112 return base::ASCIIToUTF16(kInstantSupportUnknown); | 140 return base::ASCIIToUTF16(kInstantSupportUnknown); |
113 } | 141 } |
114 return base::ASCIIToUTF16(kInstantSupportUnknown); | 142 return base::ASCIIToUTF16(kInstantSupportUnknown); |
115 } | 143 } |
116 | 144 |
117 TemplateURL* GetDefaultSearchProviderTemplateURL(Profile* profile) { | 145 TemplateURL* GetDefaultSearchProviderTemplateURL(Profile* profile) { |
118 TemplateURLService* template_url_service = | 146 if (profile) { |
119 TemplateURLServiceFactory::GetForProfile(profile); | 147 TemplateURLService* template_url_service = |
120 if (template_url_service) | 148 TemplateURLServiceFactory::GetForProfile(profile); |
121 return template_url_service->GetDefaultSearchProvider(); | 149 if (template_url_service) |
| 150 return template_url_service->GetDefaultSearchProvider(); |
| 151 } |
122 return NULL; | 152 return NULL; |
123 } | 153 } |
124 | 154 |
125 GURL TemplateURLRefToGURL(const TemplateURLRef& ref, | 155 GURL TemplateURLRefToGURL(const TemplateURLRef& ref, |
126 int start_margin, | 156 int start_margin, |
127 bool append_extra_query_params, | 157 bool append_extra_query_params, |
128 bool force_instant_results) { | 158 bool force_instant_results) { |
129 TemplateURLRef::SearchTermsArgs search_terms_args = | 159 TemplateURLRef::SearchTermsArgs search_terms_args = |
130 TemplateURLRef::SearchTermsArgs(base::string16()); | 160 TemplateURLRef::SearchTermsArgs(base::string16()); |
131 search_terms_args.omnibox_start_margin = start_margin; | 161 search_terms_args.omnibox_start_margin = start_margin; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 ManagedModeURLFilter* url_filter = | 282 ManagedModeURLFilter* url_filter = |
253 managed_user_service->GetURLFilterForUIThread(); | 283 managed_user_service->GetURLFilterForUIThread(); |
254 if (url_filter->GetFilteringBehaviorForURL(url) == | 284 if (url_filter->GetFilteringBehaviorForURL(url) == |
255 ManagedModeURLFilter::BLOCK) { | 285 ManagedModeURLFilter::BLOCK) { |
256 return false; | 286 return false; |
257 } | 287 } |
258 #endif | 288 #endif |
259 return true; | 289 return true; |
260 } | 290 } |
261 | 291 |
| 292 // Returns whether |new_tab_url| can be used as a URL for the New Tab page. |
| 293 // NEW_TAB_URL_VALID means a valid URL; other enum values imply an invalid URL. |
| 294 NewTabURLState IsValidNewTabURL(Profile* profile, const GURL& new_tab_url) { |
| 295 if (profile->IsOffTheRecord()) |
| 296 return NEW_TAB_URL_INCOGNITO; |
| 297 if (!new_tab_url.is_valid()) |
| 298 return NEW_TAB_URL_NOT_SET; |
| 299 if (!new_tab_url.SchemeIsSecure()) |
| 300 return NEW_TAB_URL_INSECURE; |
| 301 if (!IsSuggestPrefEnabled(profile)) |
| 302 return NEW_TAB_URL_SUGGEST_OFF; |
| 303 if (!IsURLAllowedForSupervisedUser(new_tab_url, profile)) |
| 304 return NEW_TAB_URL_BLOCKED; |
| 305 return NEW_TAB_URL_VALID; |
| 306 } |
| 307 |
| 308 // Used to look up the URL to use for the New Tab page. Also tracks how we |
| 309 // arrived at that URL so it can be logged with UMA. |
| 310 struct NewTabURLDetails { |
| 311 NewTabURLDetails(const GURL& url, NewTabURLState state) |
| 312 : url(url), state(state) {} |
| 313 |
| 314 static NewTabURLDetails ForProfile(Profile* profile) { |
| 315 const GURL local_url(chrome::kChromeSearchLocalNtpUrl); |
| 316 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile); |
| 317 if (!profile || !template_url) |
| 318 return NewTabURLDetails(local_url, NEW_TAB_URL_BAD); |
| 319 |
| 320 GURL search_provider_url = TemplateURLRefToGURL( |
| 321 template_url->new_tab_url_ref(), kDisableStartMargin, false, false); |
| 322 NewTabURLState state = IsValidNewTabURL(profile, search_provider_url); |
| 323 switch (state) { |
| 324 case NEW_TAB_URL_VALID: |
| 325 // We can use the search provider's page. |
| 326 return NewTabURLDetails(search_provider_url, state); |
| 327 case NEW_TAB_URL_INCOGNITO: |
| 328 // Incognito has its own New Tab. |
| 329 return NewTabURLDetails(GURL(), state); |
| 330 default: |
| 331 // Use the local New Tab otherwise. |
| 332 return NewTabURLDetails(local_url, state); |
| 333 }; |
| 334 } |
| 335 |
| 336 GURL url; |
| 337 NewTabURLState state; |
| 338 }; |
| 339 |
262 } // namespace | 340 } // namespace |
263 | 341 |
264 // Negative start-margin values prevent the "es_sm" parameter from being used. | 342 // Negative start-margin values prevent the "es_sm" parameter from being used. |
265 const int kDisableStartMargin = -1; | 343 const int kDisableStartMargin = -1; |
266 | 344 |
267 bool IsInstantExtendedAPIEnabled() { | 345 bool IsInstantExtendedAPIEnabled() { |
268 #if defined(OS_IOS) || defined(OS_ANDROID) | 346 #if defined(OS_IOS) || defined(OS_ANDROID) |
269 return false; | 347 return false; |
270 #else | 348 #else |
271 return true; | 349 return true; |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 return result; | 522 return result; |
445 for (size_t i = 0; i < template_url->URLCount(); ++i) { | 523 for (size_t i = 0; i < template_url->URLCount(); ++i) { |
446 TemplateURLRef ref(template_url, i); | 524 TemplateURLRef ref(template_url, i); |
447 result.push_back(TemplateURLRefToGURL(ref, kDisableStartMargin, false, | 525 result.push_back(TemplateURLRefToGURL(ref, kDisableStartMargin, false, |
448 false)); | 526 false)); |
449 } | 527 } |
450 return result; | 528 return result; |
451 } | 529 } |
452 | 530 |
453 GURL GetNewTabPageURL(Profile* profile) { | 531 GURL GetNewTabPageURL(Profile* profile) { |
454 if (!profile || profile->IsOffTheRecord()) | 532 return NewTabURLDetails::ForProfile(profile).url; |
455 return GURL(); | |
456 | |
457 if (!IsSuggestPrefEnabled(profile)) | |
458 return GURL(chrome::kChromeSearchLocalNtpUrl); | |
459 | |
460 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile); | |
461 if (!template_url) | |
462 return GURL(chrome::kChromeSearchLocalNtpUrl); | |
463 | |
464 GURL url(TemplateURLRefToGURL(template_url->new_tab_url_ref(), | |
465 kDisableStartMargin, false, false)); | |
466 if (!url.is_valid() || !url.SchemeIsSecure()) | |
467 return GURL(chrome::kChromeSearchLocalNtpUrl); | |
468 | |
469 if (!IsURLAllowedForSupervisedUser(url, profile)) | |
470 return GURL(chrome::kChromeSearchLocalNtpUrl); | |
471 | |
472 return url; | |
473 } | 533 } |
474 | 534 |
475 GURL GetSearchResultPrefetchBaseURL(Profile* profile) { | 535 GURL GetSearchResultPrefetchBaseURL(Profile* profile) { |
476 return ShouldPrefetchSearchResults() ? | 536 return ShouldPrefetchSearchResults() ? |
477 GetInstantURL(profile, kDisableStartMargin, true) : GURL(); | 537 GetInstantURL(profile, kDisableStartMargin, true) : GURL(); |
478 } | 538 } |
479 | 539 |
480 bool ShouldPrefetchSearchResults() { | 540 bool ShouldPrefetchSearchResults() { |
481 FieldTrialFlags flags; | 541 FieldTrialFlags flags; |
482 return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault( | 542 return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault( |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 bool HandleNewTabURLRewrite(GURL* url, | 647 bool HandleNewTabURLRewrite(GURL* url, |
588 content::BrowserContext* browser_context) { | 648 content::BrowserContext* browser_context) { |
589 if (!IsInstantExtendedAPIEnabled()) | 649 if (!IsInstantExtendedAPIEnabled()) |
590 return false; | 650 return false; |
591 | 651 |
592 if (!url->SchemeIs(chrome::kChromeUIScheme) || | 652 if (!url->SchemeIs(chrome::kChromeUIScheme) || |
593 url->host() != chrome::kChromeUINewTabHost) | 653 url->host() != chrome::kChromeUINewTabHost) |
594 return false; | 654 return false; |
595 | 655 |
596 Profile* profile = Profile::FromBrowserContext(browser_context); | 656 Profile* profile = Profile::FromBrowserContext(browser_context); |
597 GURL new_tab_url(GetNewTabPageURL(profile)); | 657 NewTabURLDetails details(NewTabURLDetails::ForProfile(profile)); |
598 if (!new_tab_url.is_valid()) | 658 UMA_HISTOGRAM_ENUMERATION("NewTabPage.URLState", |
599 return false; | 659 details.state, NEW_TAB_URL_MAX); |
600 | 660 if (details.url.is_valid()) { |
601 *url = new_tab_url; | 661 *url = details.url; |
602 return true; | 662 return true; |
| 663 } |
| 664 return false; |
603 } | 665 } |
604 | 666 |
605 bool HandleNewTabURLReverseRewrite(GURL* url, | 667 bool HandleNewTabURLReverseRewrite(GURL* url, |
606 content::BrowserContext* browser_context) { | 668 content::BrowserContext* browser_context) { |
607 if (!IsInstantExtendedAPIEnabled()) | 669 if (!IsInstantExtendedAPIEnabled()) |
608 return false; | 670 return false; |
609 | 671 |
| 672 // Do nothing in incognito. |
610 Profile* profile = Profile::FromBrowserContext(browser_context); | 673 Profile* profile = Profile::FromBrowserContext(browser_context); |
611 GURL new_tab_url(GetNewTabPageURL(profile)); | 674 if (profile && profile->IsOffTheRecord()) |
612 if (!new_tab_url.is_valid() || | |
613 !search::MatchesOriginAndPath(new_tab_url, *url)) | |
614 return false; | 675 return false; |
615 | 676 |
616 *url = GURL(chrome::kChromeUINewTabURL); | 677 if (search::MatchesOriginAndPath( |
617 return true; | 678 GURL(chrome::kChromeSearchLocalNtpUrl), *url)) { |
| 679 *url = GURL(chrome::kChromeUINewTabURL); |
| 680 return true; |
| 681 } |
| 682 |
| 683 GURL new_tab_url(GetNewTabPageURL(profile)); |
| 684 if (new_tab_url.is_valid() && |
| 685 search::MatchesOriginAndPath(new_tab_url, *url)) { |
| 686 *url = GURL(chrome::kChromeUINewTabURL); |
| 687 return true; |
| 688 } |
| 689 |
| 690 return false; |
618 } | 691 } |
619 | 692 |
620 void SetInstantSupportStateInNavigationEntry(InstantSupportState state, | 693 void SetInstantSupportStateInNavigationEntry(InstantSupportState state, |
621 content::NavigationEntry* entry) { | 694 content::NavigationEntry* entry) { |
622 if (!entry) | 695 if (!entry) |
623 return; | 696 return; |
624 | 697 |
625 entry->SetExtraData(kInstantSupportStateKey, | 698 entry->SetExtraData(kInstantSupportStateKey, |
626 InstantSupportStateToString(state)); | 699 InstantSupportStateToString(state)); |
627 } | 700 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 | 776 |
704 // Given a FieldTrialFlags object, returns the boolean value of the provided | 777 // Given a FieldTrialFlags object, returns the boolean value of the provided |
705 // flag. | 778 // flag. |
706 bool GetBoolValueForFlagWithDefault(const std::string& flag, | 779 bool GetBoolValueForFlagWithDefault(const std::string& flag, |
707 bool default_value, | 780 bool default_value, |
708 const FieldTrialFlags& flags) { | 781 const FieldTrialFlags& flags) { |
709 return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags); | 782 return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags); |
710 } | 783 } |
711 | 784 |
712 } // namespace chrome | 785 } // namespace chrome |
OLD | NEW |