| 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/metrics/histogram.h" |
| 10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "chrome/browser/ui/browser.h" | 21 #include "chrome/browser/ui/browser.h" |
| 22 #include "chrome/browser/ui/browser_instant_controller.h" | 22 #include "chrome/browser/ui/browser_instant_controller.h" |
| 23 #include "chrome/browser/ui/browser_iterator.h" | 23 #include "chrome/browser/ui/browser_iterator.h" |
| 24 #include "chrome/browser/ui/search/instant_search_prerenderer.h" | 24 #include "chrome/browser/ui/search/instant_search_prerenderer.h" |
| 25 #include "chrome/common/chrome_switches.h" | 25 #include "chrome/common/chrome_switches.h" |
| 26 #include "chrome/common/pref_names.h" | 26 #include "chrome/common/pref_names.h" |
| 27 #include "chrome/common/search_urls.h" | 27 #include "chrome/common/search_urls.h" |
| 28 #include "chrome/common/url_constants.h" | 28 #include "chrome/common/url_constants.h" |
| 29 #include "components/google/core/browser/google_util.h" | 29 #include "components/google/core/browser/google_util.h" |
| 30 #include "components/pref_registry/pref_registry_syncable.h" | 30 #include "components/pref_registry/pref_registry_syncable.h" |
| 31 #include "components/search/search.h" |
| 31 #include "components/search_engines/template_url_service.h" | 32 #include "components/search_engines/template_url_service.h" |
| 32 #include "components/sessions/serialized_navigation_entry.h" | 33 #include "components/sessions/serialized_navigation_entry.h" |
| 33 #include "content/public/browser/navigation_entry.h" | 34 #include "content/public/browser/navigation_entry.h" |
| 34 #include "content/public/browser/render_process_host.h" | 35 #include "content/public/browser/render_process_host.h" |
| 35 #include "content/public/browser/web_contents.h" | 36 #include "content/public/browser/web_contents.h" |
| 36 #include "grit/generated_resources.h" | 37 #include "grit/generated_resources.h" |
| 37 #include "ui/base/l10n/l10n_util.h" | 38 #include "ui/base/l10n/l10n_util.h" |
| 38 | 39 |
| 39 #if defined(ENABLE_MANAGED_USERS) | 40 #if defined(ENABLE_MANAGED_USERS) |
| 40 #include "chrome/browser/supervised_user/supervised_user_service.h" | 41 #include "chrome/browser/supervised_user/supervised_user_service.h" |
| 41 #include "chrome/browser/supervised_user/supervised_user_service_factory.h" | 42 #include "chrome/browser/supervised_user/supervised_user_service_factory.h" |
| 42 #include "chrome/browser/supervised_user/supervised_user_url_filter.h" | 43 #include "chrome/browser/supervised_user/supervised_user_url_filter.h" |
| 43 #endif | 44 #endif |
| 44 | 45 |
| 45 namespace chrome { | 46 namespace chrome { |
| 46 | 47 |
| 47 namespace { | 48 namespace { |
| 48 | 49 |
| 49 // Configuration options for Embedded Search. | |
| 50 // EmbeddedSearch field trials are named in such a way that we can parse out | |
| 51 // the experiment configuration from the trial's group name in order to give | |
| 52 // us maximum flexability in running experiments. | |
| 53 // Field trial groups should be named things like "Group7 espv:2 instant:1". | |
| 54 // The first token is always GroupN for some integer N, followed by a | |
| 55 // space-delimited list of key:value pairs which correspond to these flags: | |
| 56 const char kEmbeddedPageVersionFlagName[] = "espv"; | |
| 57 #if defined(OS_IOS) | |
| 58 const uint64 kEmbeddedPageVersionDefault = 1; | |
| 59 #elif defined(OS_ANDROID) | |
| 60 const uint64 kEmbeddedPageVersionDefault = 1; | |
| 61 // Use this variant to enable EmbeddedSearch SearchBox API in the results page. | |
| 62 const uint64 kEmbeddedSearchEnabledVersion = 2; | |
| 63 #else | |
| 64 const uint64 kEmbeddedPageVersionDefault = 2; | |
| 65 #endif | |
| 66 | |
| 67 const char kHideVerbatimFlagName[] = "hide_verbatim"; | 50 const char kHideVerbatimFlagName[] = "hide_verbatim"; |
| 68 const char kPrefetchSearchResultsOnSRP[] = "prefetch_results_srp"; | 51 const char kPrefetchSearchResultsOnSRP[] = "prefetch_results_srp"; |
| 69 const char kAllowPrefetchNonDefaultMatch[] = "allow_prefetch_non_default_match"; | 52 const char kAllowPrefetchNonDefaultMatch[] = "allow_prefetch_non_default_match"; |
| 70 const char kPrerenderInstantUrlOnOmniboxFocus[] = | 53 const char kPrerenderInstantUrlOnOmniboxFocus[] = |
| 71 "prerender_instant_url_on_omnibox_focus"; | 54 "prerender_instant_url_on_omnibox_focus"; |
| 72 | 55 |
| 73 #if defined(OS_ANDROID) | 56 #if defined(OS_ANDROID) |
| 74 const char kPrefetchSearchResultsFlagName[] = "prefetch_results"; | 57 const char kPrefetchSearchResultsFlagName[] = "prefetch_results"; |
| 75 | 58 |
| 76 // Controls whether to reuse prerendered Instant Search base page to commit any | 59 // Controls whether to reuse prerendered Instant Search base page to commit any |
| 77 // search query. | 60 // search query. |
| 78 const char kReuseInstantSearchBasePage[] = "reuse_instant_search_base_page"; | 61 const char kReuseInstantSearchBasePage[] = "reuse_instant_search_base_page"; |
| 79 #endif | 62 #endif |
| 80 | 63 |
| 81 // Controls whether to use the alternate Instant search base URL. This allows | 64 // Controls whether to use the alternate Instant search base URL. This allows |
| 82 // experimentation of Instant search. | 65 // experimentation of Instant search. |
| 83 const char kUseAltInstantURL[] = "use_alternate_instant_url"; | 66 const char kUseAltInstantURL[] = "use_alternate_instant_url"; |
| 84 const char kAltInstantURLPath[] = "search"; | 67 const char kAltInstantURLPath[] = "search"; |
| 85 const char kAltInstantURLQueryParams[] = "&qbp=1"; | 68 const char kAltInstantURLQueryParams[] = "&qbp=1"; |
| 86 | 69 |
| 87 const char kDisplaySearchButtonFlagName[] = "display_search_button"; | 70 const char kDisplaySearchButtonFlagName[] = "display_search_button"; |
| 88 const char kOriginChipFlagName[] = "origin_chip"; | 71 const char kOriginChipFlagName[] = "origin_chip"; |
| 89 #if !defined(OS_IOS) && !defined(OS_ANDROID) | 72 #if !defined(OS_IOS) && !defined(OS_ANDROID) |
| 90 const char kEnableQueryExtractionFlagName[] = "query_extraction"; | 73 const char kEnableQueryExtractionFlagName[] = "query_extraction"; |
| 91 #endif | 74 #endif |
| 92 const char kShouldShowGoogleLocalNTPFlagName[] = "google_local_ntp"; | 75 const char kShouldShowGoogleLocalNTPFlagName[] = "google_local_ntp"; |
| 93 | 76 |
| 94 // Constants for the field trial name and group prefix. | |
| 95 // Note in M30 and below this field trial was named "InstantExtended" and in | |
| 96 // M31 was renamed to EmbeddedSearch for clarity and cleanliness. Since we | |
| 97 // can't easilly sync up Finch configs with the pushing of this change to | |
| 98 // Dev & Canary, for now the code accepts both names. | |
| 99 // TODO(dcblack): Remove the InstantExtended name once M31 hits the Beta | |
| 100 // channel. | |
| 101 const char kInstantExtendedFieldTrialName[] = "InstantExtended"; | |
| 102 const char kEmbeddedSearchFieldTrialName[] = "EmbeddedSearch"; | |
| 103 | |
| 104 // If the field trial's group name ends with this string its configuration will | |
| 105 // be ignored and Instant Extended will not be enabled by default. | |
| 106 const char kDisablingSuffix[] = "DISABLED"; | |
| 107 | |
| 108 // Status of the New Tab URL for the default Search provider. NOTE: Used in a | 77 // Status of the New Tab URL for the default Search provider. NOTE: Used in a |
| 109 // UMA histogram so values should only be added at the end and not reordered. | 78 // UMA histogram so values should only be added at the end and not reordered. |
| 110 enum NewTabURLState { | 79 enum NewTabURLState { |
| 111 // Valid URL that should be used. | 80 // Valid URL that should be used. |
| 112 NEW_TAB_URL_VALID = 0, | 81 NEW_TAB_URL_VALID = 0, |
| 113 | 82 |
| 114 // Corrupt state (e.g. no profile or template url). | 83 // Corrupt state (e.g. no profile or template url). |
| 115 NEW_TAB_URL_BAD = 1, | 84 NEW_TAB_URL_BAD = 1, |
| 116 | 85 |
| 117 // URL should not be used because in incognito window. | 86 // URL should not be used because in incognito window. |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 310 |
| 342 GURL url; | 311 GURL url; |
| 343 NewTabURLState state; | 312 NewTabURLState state; |
| 344 }; | 313 }; |
| 345 | 314 |
| 346 } // namespace | 315 } // namespace |
| 347 | 316 |
| 348 // Negative start-margin values prevent the "es_sm" parameter from being used. | 317 // Negative start-margin values prevent the "es_sm" parameter from being used. |
| 349 const int kDisableStartMargin = -1; | 318 const int kDisableStartMargin = -1; |
| 350 | 319 |
| 351 bool IsInstantExtendedAPIEnabled() { | |
| 352 #if defined(OS_IOS) | |
| 353 return false; | |
| 354 #elif defined(OS_ANDROID) | |
| 355 return EmbeddedSearchPageVersion() == kEmbeddedSearchEnabledVersion; | |
| 356 #else | |
| 357 return true; | |
| 358 #endif // defined(OS_IOS) | |
| 359 } | |
| 360 | |
| 361 // Determine what embedded search page version to request from the user's | |
| 362 // default search provider. If 0, the embedded search UI should not be enabled. | |
| 363 uint64 EmbeddedSearchPageVersion() { | |
| 364 #if defined(OS_ANDROID) | |
| 365 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 366 switches::kEnableEmbeddedSearchAPI)) { | |
| 367 return kEmbeddedSearchEnabledVersion; | |
| 368 } | |
| 369 #endif | |
| 370 | |
| 371 FieldTrialFlags flags; | |
| 372 if (GetFieldTrialInfo(&flags)) { | |
| 373 return GetUInt64ValueForFlagWithDefault(kEmbeddedPageVersionFlagName, | |
| 374 kEmbeddedPageVersionDefault, | |
| 375 flags); | |
| 376 } | |
| 377 return kEmbeddedPageVersionDefault; | |
| 378 } | |
| 379 | |
| 380 std::string InstantExtendedEnabledParam(bool for_search) { | 320 std::string InstantExtendedEnabledParam(bool for_search) { |
| 381 if (for_search && !chrome::IsQueryExtractionEnabled()) | 321 if (for_search && !chrome::IsQueryExtractionEnabled()) |
| 382 return std::string(); | 322 return std::string(); |
| 383 return std::string(google_util::kInstantExtendedAPIParam) + "=" + | 323 return std::string(google_util::kInstantExtendedAPIParam) + "=" + |
| 384 base::Uint64ToString(EmbeddedSearchPageVersion()) + "&"; | 324 base::Uint64ToString(EmbeddedSearchPageVersion()) + "&"; |
| 385 } | 325 } |
| 386 | 326 |
| 387 std::string ForceInstantResultsParam(bool for_prerender) { | 327 std::string ForceInstantResultsParam(bool for_prerender) { |
| 388 return (for_prerender || !IsInstantExtendedAPIEnabled()) ? | 328 return (for_prerender || !IsInstantExtendedAPIEnabled()) ? |
| 389 "ion=1&" : std::string(); | 329 "ion=1&" : std::string(); |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 FieldTrialFlags flags; | 740 FieldTrialFlags flags; |
| 801 return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault( | 741 return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault( |
| 802 kPrefetchSearchResultsOnSRP, false, flags); | 742 kPrefetchSearchResultsOnSRP, false, flags); |
| 803 } | 743 } |
| 804 | 744 |
| 805 void EnableQueryExtractionForTesting() { | 745 void EnableQueryExtractionForTesting() { |
| 806 CommandLine* cl = CommandLine::ForCurrentProcess(); | 746 CommandLine* cl = CommandLine::ForCurrentProcess(); |
| 807 cl->AppendSwitch(switches::kEnableQueryExtraction); | 747 cl->AppendSwitch(switches::kEnableQueryExtraction); |
| 808 } | 748 } |
| 809 | 749 |
| 810 bool GetFieldTrialInfo(FieldTrialFlags* flags) { | |
| 811 // Get the group name. If the EmbeddedSearch trial doesn't exist, look for | |
| 812 // the older InstantExtended name. | |
| 813 std::string group_name = base::FieldTrialList::FindFullName( | |
| 814 kEmbeddedSearchFieldTrialName); | |
| 815 if (group_name.empty()) { | |
| 816 group_name = base::FieldTrialList::FindFullName( | |
| 817 kInstantExtendedFieldTrialName); | |
| 818 } | |
| 819 | |
| 820 if (EndsWith(group_name, kDisablingSuffix, true)) | |
| 821 return false; | |
| 822 | |
| 823 // We have a valid trial that isn't disabled. Extract the flags. | |
| 824 std::string group_prefix(group_name); | |
| 825 size_t first_space = group_name.find(" "); | |
| 826 if (first_space != std::string::npos) { | |
| 827 // There is a flags section of the group name. Split that out and parse it. | |
| 828 group_prefix = group_name.substr(0, first_space); | |
| 829 if (!base::SplitStringIntoKeyValuePairs(group_name.substr(first_space), | |
| 830 ':', ' ', flags)) { | |
| 831 // Failed to parse the flags section. Assume the whole group name is | |
| 832 // invalid. | |
| 833 return false; | |
| 834 } | |
| 835 } | |
| 836 return true; | |
| 837 } | |
| 838 | |
| 839 // Given a FieldTrialFlags object, returns the string value of the provided | |
| 840 // flag. | |
| 841 std::string GetStringValueForFlagWithDefault(const std::string& flag, | |
| 842 const std::string& default_value, | |
| 843 const FieldTrialFlags& flags) { | |
| 844 FieldTrialFlags::const_iterator i; | |
| 845 for (i = flags.begin(); i != flags.end(); i++) { | |
| 846 if (i->first == flag) | |
| 847 return i->second; | |
| 848 } | |
| 849 return default_value; | |
| 850 } | |
| 851 | |
| 852 // Given a FieldTrialFlags object, returns the uint64 value of the provided | |
| 853 // flag. | |
| 854 uint64 GetUInt64ValueForFlagWithDefault(const std::string& flag, | |
| 855 uint64 default_value, | |
| 856 const FieldTrialFlags& flags) { | |
| 857 uint64 value; | |
| 858 std::string str_value = | |
| 859 GetStringValueForFlagWithDefault(flag, std::string(), flags); | |
| 860 if (base::StringToUint64(str_value, &value)) | |
| 861 return value; | |
| 862 return default_value; | |
| 863 } | |
| 864 | |
| 865 // Given a FieldTrialFlags object, returns the boolean value of the provided | |
| 866 // flag. | |
| 867 bool GetBoolValueForFlagWithDefault(const std::string& flag, | |
| 868 bool default_value, | |
| 869 const FieldTrialFlags& flags) { | |
| 870 return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags); | |
| 871 } | |
| 872 | |
| 873 bool ShouldUseAltInstantURL() { | 750 bool ShouldUseAltInstantURL() { |
| 874 FieldTrialFlags flags; | 751 FieldTrialFlags flags; |
| 875 return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault( | 752 return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault( |
| 876 kUseAltInstantURL, false, flags); | 753 kUseAltInstantURL, false, flags); |
| 877 } | 754 } |
| 878 | 755 |
| 879 } // namespace chrome | 756 } // namespace chrome |
| OLD | NEW |