summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormukai@chromium.org <mukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-23 08:48:40 +0000
committermukai@chromium.org <mukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-23 08:48:40 +0000
commit720b10490523188c34b012d1ccf2059020cc13e1 (patch)
treeb772fe2125597d0bb8e57dfdbc3b9aa5d9b498c3
parent86487aa3a77b454917b5a1cb0c42b05cb6b22136 (diff)
downloadchromium_src-720b10490523188c34b012d1ccf2059020cc13e1.zip
chromium_src-720b10490523188c34b012d1ccf2059020cc13e1.tar.gz
chromium_src-720b10490523188c34b012d1ccf2059020cc13e1.tar.bz2
Moves some functions in search.h to components.
These functions are simplistic and doesn't depend on chrome's feature, so there's no reason to be under chrome/browser. Moving to components/ would help further componentization task of autocomplete anad omnibox_field_trials. BUG=371538 R=brettw@chromium.org, pkasting@chromium.org, blundell@chromium.org TBR=tedchoc@chromium.org, jhawkins@chromium.org TEST=build Review URL: https://codereview.chromium.org/393173002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284885 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/BUILD.gn1
-rw-r--r--chrome/browser/DEPS1
-rw-r--r--chrome/browser/about_flags.cc1
-rw-r--r--chrome/browser/android/omnibox/autocomplete_controller_android.cc1
-rw-r--r--chrome/browser/autocomplete/search_provider.cc2
-rw-r--r--chrome/browser/omnibox/omnibox_field_trial.cc2
-rw-r--r--chrome/browser/omnibox/omnibox_field_trial_unittest.cc2
-rw-r--r--chrome/browser/search/instant_service_factory.cc2
-rw-r--r--chrome/browser/search/search.cc125
-rw-r--r--chrome/browser/search/search.h40
-rw-r--r--chrome/browser/search/search_android_unittest.cc11
-rw-r--r--chrome/browser/search/search_unittest.cc121
-rw-r--r--chrome/browser/search_engines/ui_thread_search_terms_data.cc1
-rw-r--r--chrome/browser/thumbnails/thumbnail_service_impl.cc2
-rw-r--r--chrome/browser/ui/bookmarks/bookmark_utils.cc1
-rw-r--r--chrome/browser/ui/browser.cc1
-rw-r--r--chrome/browser/ui/extensions/extension_install_ui_default.cc2
-rw-r--r--chrome/browser/ui/omnibox/omnibox_controller.cc1
-rw-r--r--chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc1
-rw-r--r--chrome/browser/ui/search/search_model.cc2
-rw-r--r--chrome/browser/ui/search/search_tab_helper.cc1
-rw-r--r--chrome/browser/ui/webui/history_ui.cc2
-rw-r--r--chrome/chrome_browser.gypi1
-rw-r--r--chrome/chrome_tests_unit.gypi2
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--components/BUILD.gn1
-rw-r--r--components/OWNERS5
-rw-r--r--components/components.gyp1
-rw-r--r--components/components_tests.gyp6
-rw-r--r--components/search.gypi24
-rw-r--r--components/search/BUILD.gn16
-rw-r--r--components/search/DEPS3
-rw-r--r--components/search/OWNERS4
-rw-r--r--components/search/search.cc146
-rw-r--r--components/search/search.h59
-rw-r--r--components/search/search_android_unittest.cc30
-rw-r--r--components/search/search_switches.cc16
-rw-r--r--components/search/search_switches.h18
-rw-r--r--components/search/search_unittest.cc133
40 files changed, 486 insertions, 306 deletions
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 5adfe20..6da60fb 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -59,6 +59,7 @@ static_library("browser") {
"//components/policy:policy_component",
"//components/query_parser",
"//components/rappor",
+ "//components/search",
"//components/signin/core/browser",
"//components/startup_metric_utils",
"//components/strings",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 47890d2..0aa0659 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -46,6 +46,7 @@ include_rules = [
"+components/pref_registry",
"+components/query_parser",
"+components/rappor",
+ "+components/search",
"+components/search_engines",
"+components/search_provider_logos",
"+components/session_manager",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index cc0252b..4a0ce92 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -23,6 +23,7 @@
#include "components/autofill/core/common/autofill_switches.h"
#include "components/cloud_devices/common/cloud_devices_switches.h"
#include "components/nacl/common/nacl_switches.h"
+#include "components/search/search_switches.h"
#include "content/public/browser/user_metrics.h"
#include "extensions/common/switches.h"
#include "grit/chromium_strings.h"
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.cc b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
index 72f20aa..e6be185 100644
--- a/chrome/browser/android/omnibox/autocomplete_controller_android.cc
+++ b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
@@ -37,6 +37,7 @@
#include "components/autocomplete/autocomplete_match_type.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/metrics/proto/omnibox_event.pb.h"
+#include "components/search/search.h"
#include "components/search_engines/template_url_service.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc
index 87e5545..1932639 100644
--- a/chrome/browser/autocomplete/search_provider.cc
+++ b/chrome/browser/autocomplete/search_provider.cc
@@ -30,7 +30,6 @@
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/omnibox/omnibox_field_trial.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search/search.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/search/instant_controller.h"
#include "chrome/common/chrome_switches.h"
@@ -40,6 +39,7 @@
#include "components/history/core/browser/in_memory_database.h"
#include "components/history/core/browser/keyword_search_term.h"
#include "components/metrics/proto/omnibox_input_type.pb.h"
+#include "components/search/search.h"
#include "components/search_engines/template_url_prepopulate_data.h"
#include "components/search_engines/template_url_service.h"
#include "components/variations/variations_http_header_provider.h"
diff --git a/chrome/browser/omnibox/omnibox_field_trial.cc b/chrome/browser/omnibox/omnibox_field_trial.cc
index 3a7a8ec..debbf4a 100644
--- a/chrome/browser/omnibox/omnibox_field_trial.cc
+++ b/chrome/browser/omnibox/omnibox_field_trial.cc
@@ -14,10 +14,10 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
-#include "chrome/browser/search/search.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/variations/variation_ids.h"
#include "components/metrics/proto/omnibox_event.pb.h"
+#include "components/search/search.h"
#include "components/variations/active_field_trials.h"
#include "components/variations/metrics_util.h"
#include "components/variations/variations_associated_data.h"
diff --git a/chrome/browser/omnibox/omnibox_field_trial_unittest.cc b/chrome/browser/omnibox/omnibox_field_trial_unittest.cc
index 0ee60de..e818190 100644
--- a/chrome/browser/omnibox/omnibox_field_trial_unittest.cc
+++ b/chrome/browser/omnibox/omnibox_field_trial_unittest.cc
@@ -9,9 +9,9 @@
#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string16.h"
-#include "chrome/browser/search/search.h"
#include "chrome/common/chrome_switches.h"
#include "components/metrics/proto/omnibox_event.pb.h"
+#include "components/search/search.h"
#include "components/variations/entropy_provider.h"
#include "components/variations/variations_associated_data.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/search/instant_service_factory.cc b/chrome/browser/search/instant_service_factory.cc
index a88402e..0865807 100644
--- a/chrome/browser/search/instant_service_factory.cc
+++ b/chrome/browser/search/instant_service_factory.cc
@@ -7,10 +7,10 @@
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/instant_service.h"
-#include "chrome/browser/search/search.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/search/search.h"
// static
InstantService* InstantServiceFactory::GetForProfile(Profile* profile) {
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc
index 6e0a8dd..75a0015 100644
--- a/chrome/browser/search/search.cc
+++ b/chrome/browser/search/search.cc
@@ -28,6 +28,7 @@
#include "chrome/common/url_constants.h"
#include "components/google/core/browser/google_util.h"
#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/search/search.h"
#include "components/search_engines/template_url_service.h"
#include "components/sessions/serialized_navigation_entry.h"
#include "content/public/browser/navigation_entry.h"
@@ -46,24 +47,6 @@ namespace chrome {
namespace {
-// Configuration options for Embedded Search.
-// EmbeddedSearch field trials are named in such a way that we can parse out
-// the experiment configuration from the trial's group name in order to give
-// us maximum flexability in running experiments.
-// Field trial groups should be named things like "Group7 espv:2 instant:1".
-// The first token is always GroupN for some integer N, followed by a
-// space-delimited list of key:value pairs which correspond to these flags:
-const char kEmbeddedPageVersionFlagName[] = "espv";
-#if defined(OS_IOS)
-const uint64 kEmbeddedPageVersionDefault = 1;
-#elif defined(OS_ANDROID)
-const uint64 kEmbeddedPageVersionDefault = 1;
-// Use this variant to enable EmbeddedSearch SearchBox API in the results page.
-const uint64 kEmbeddedSearchEnabledVersion = 2;
-#else
-const uint64 kEmbeddedPageVersionDefault = 2;
-#endif
-
const char kHideVerbatimFlagName[] = "hide_verbatim";
const char kPrefetchSearchResultsOnSRP[] = "prefetch_results_srp";
const char kAllowPrefetchNonDefaultMatch[] = "allow_prefetch_non_default_match";
@@ -91,20 +74,6 @@ const char kEnableQueryExtractionFlagName[] = "query_extraction";
#endif
const char kShouldShowGoogleLocalNTPFlagName[] = "google_local_ntp";
-// Constants for the field trial name and group prefix.
-// Note in M30 and below this field trial was named "InstantExtended" and in
-// M31 was renamed to EmbeddedSearch for clarity and cleanliness. Since we
-// can't easilly sync up Finch configs with the pushing of this change to
-// Dev & Canary, for now the code accepts both names.
-// TODO(dcblack): Remove the InstantExtended name once M31 hits the Beta
-// channel.
-const char kInstantExtendedFieldTrialName[] = "InstantExtended";
-const char kEmbeddedSearchFieldTrialName[] = "EmbeddedSearch";
-
-// If the field trial's group name ends with this string its configuration will
-// be ignored and Instant Extended will not be enabled by default.
-const char kDisablingSuffix[] = "DISABLED";
-
// Status of the New Tab URL for the default Search provider. NOTE: Used in a
// UMA histogram so values should only be added at the end and not reordered.
enum NewTabURLState {
@@ -344,35 +313,6 @@ struct NewTabURLDetails {
// Negative start-margin values prevent the "es_sm" parameter from being used.
const int kDisableStartMargin = -1;
-bool IsInstantExtendedAPIEnabled() {
-#if defined(OS_IOS)
- return false;
-#elif defined(OS_ANDROID)
- return EmbeddedSearchPageVersion() == kEmbeddedSearchEnabledVersion;
-#else
- return true;
-#endif // defined(OS_IOS)
-}
-
-// Determine what embedded search page version to request from the user's
-// default search provider. If 0, the embedded search UI should not be enabled.
-uint64 EmbeddedSearchPageVersion() {
-#if defined(OS_ANDROID)
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableEmbeddedSearchAPI)) {
- return kEmbeddedSearchEnabledVersion;
- }
-#endif
-
- 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();
@@ -801,69 +741,6 @@ void EnableQueryExtractionForTesting() {
cl->AppendSwitch(switches::kEnableQueryExtraction);
}
-bool GetFieldTrialInfo(FieldTrialFlags* flags) {
- // Get the group name. If the EmbeddedSearch trial doesn't exist, look for
- // the older InstantExtended name.
- 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;
-
- // We have a valid trial that isn't disabled. Extract the flags.
- std::string group_prefix(group_name);
- size_t first_space = group_name.find(" ");
- if (first_space != std::string::npos) {
- // There is a flags section of the group name. Split that out and parse it.
- group_prefix = group_name.substr(0, first_space);
- if (!base::SplitStringIntoKeyValuePairs(group_name.substr(first_space),
- ':', ' ', flags)) {
- // Failed to parse the flags section. Assume the whole group name is
- // invalid.
- return false;
- }
- }
- return true;
-}
-
-// Given a FieldTrialFlags object, returns the string value of the provided
-// flag.
-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;
-}
-
-// Given a FieldTrialFlags object, returns the uint64 value of the provided
-// flag.
-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;
-}
-
-// Given a FieldTrialFlags object, returns the boolean value of the provided
-// flag.
-bool GetBoolValueForFlagWithDefault(const std::string& flag,
- bool default_value,
- const FieldTrialFlags& flags) {
- return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags);
-}
-
bool ShouldUseAltInstantURL() {
FieldTrialFlags flags;
return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault(
diff --git a/chrome/browser/search/search.h b/chrome/browser/search/search.h
index c43d7bb..5c3b014 100644
--- a/chrome/browser/search/search.h
+++ b/chrome/browser/search/search.h
@@ -59,17 +59,9 @@ enum OriginChipCondition {
// being used.
extern const int kDisableStartMargin;
-// Returns whether the Instant Extended API is enabled.
-bool IsInstantExtendedAPIEnabled();
-
// Returns whether the suggest is enabled for the given |profile|.
bool IsSuggestPrefEnabled(Profile* profile);
-// Returns the value to pass to the &espv CGI parameter when loading the
-// embedded search page from the user's default search provider. Returns 0 if
-// the Instant Extended API is not enabled.
-uint64 EmbeddedSearchPageVersion();
-
// Returns a string indicating whether InstantExtended is enabled, suitable
// for adding as a query string param to the homepage or search requests.
// Returns an empty string otherwise.
@@ -256,38 +248,6 @@ bool ShouldPrefetchSearchResultsOnSRP();
// Forces query in the omnibox to be on for tests.
void EnableQueryExtractionForTesting();
-// Type for a collection of experiment configuration parameters.
-typedef std::vector<std::pair<std::string, std::string> > FieldTrialFlags;
-
-// Finds the active field trial group name and parses out the configuration
-// flags. On success, |flags| will be filled with the field trial flags. |flags|
-// must not be NULL. Returns true iff the active field trial is successfully
-// parsed and not disabled.
-// Note that |flags| may be successfully populated in some cases when false is
-// returned - in these cases it should not be used.
-// Exposed for testing only.
-bool GetFieldTrialInfo(FieldTrialFlags* flags);
-
-// Given a FieldTrialFlags object, returns the string value of the provided
-// flag.
-// Exposed for testing only.
-std::string GetStringValueForFlagWithDefault(const std::string& flag,
- const std::string& default_value,
- const FieldTrialFlags& flags);
-
-// Given a FieldTrialFlags object, returns the uint64 value of the provided
-// flag.
-// Exposed for testing only.
-uint64 GetUInt64ValueForFlagWithDefault(const std::string& flag,
- uint64 default_value,
- const FieldTrialFlags& flags);
-
-// Given a FieldTrialFlags object, returns the bool value of the provided flag.
-// Exposed for testing only.
-bool GetBoolValueForFlagWithDefault(const std::string& flag,
- bool default_value,
- const FieldTrialFlags& flags);
-
// Returns the Cacheable New Tab Page URL for the given |profile|.
GURL GetNewTabPageURL(Profile* profile);
diff --git a/chrome/browser/search/search_android_unittest.cc b/chrome/browser/search/search_android_unittest.cc
index 04720db..9d168d1 100644
--- a/chrome/browser/search/search_android_unittest.cc
+++ b/chrome/browser/search/search_android_unittest.cc
@@ -9,6 +9,8 @@
#include "base/metrics/field_trial.h"
#include "base/metrics/statistics_recorder.h"
#include "chrome/common/chrome_switches.h"
+#include "components/search/search.h"
+#include "components/search/search_switches.h"
#include "components/variations/entropy_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -16,15 +18,6 @@ namespace chrome {
namespace {
-TEST(SearchTest, EmbeddedSearchAPIEnabled) {
- EXPECT_EQ(1ul, EmbeddedSearchPageVersion());
- EXPECT_FALSE(IsInstantExtendedAPIEnabled());
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableEmbeddedSearchAPI);
- EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
- EXPECT_TRUE(IsInstantExtendedAPIEnabled());
-}
-
TEST(SearchTest, QueryExtractionEnabled) {
// Query extraction is always enabled on mobile.
EXPECT_TRUE(IsQueryExtractionEnabled());
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc
index ee247a8..4782290 100644
--- a/chrome/browser/search/search_unittest.cc
+++ b/chrome/browser/search/search_unittest.cc
@@ -6,7 +6,6 @@
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_samples.h"
-#include "base/metrics/statistics_recorder.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/search/instant_service.h"
@@ -24,6 +23,7 @@
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/google/core/browser/google_switches.h"
+#include "components/search/search.h"
#include "components/search_engines/search_engines_switches.h"
#include "components/search_engines/template_url_service.h"
#include "components/variations/entropy_provider.h"
@@ -36,125 +36,6 @@
namespace chrome {
-class EmbeddedSearchFieldTrialTest : public testing::Test {
- protected:
- virtual void SetUp() {
- field_trial_list_.reset(new base::FieldTrialList(
- new metrics::SHA1EntropyProvider("42")));
- base::StatisticsRecorder::Initialize();
- }
-
- private:
- scoped_ptr<base::FieldTrialList> field_trial_list_;
-};
-
-TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoEmptyAndValid) {
- FieldTrialFlags flags;
-
- EXPECT_TRUE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(0ul, flags.size());
-
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
- "Group77"));
- EXPECT_TRUE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(0ul, flags.size());
-}
-
-TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidNumber) {
- FieldTrialFlags flags;
-
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
- "Group77.2"));
- EXPECT_TRUE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(0ul, flags.size());
-}
-
-TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidName) {
- FieldTrialFlags flags;
-
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
- "Invalid77"));
- EXPECT_TRUE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(0ul, flags.size());
-}
-
-TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidGroup) {
- FieldTrialFlags flags;
-
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
- "Group77"));
- EXPECT_TRUE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(0ul, flags.size());
-}
-
-TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidFlag) {
- FieldTrialFlags flags;
-
- EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
- "Group77 foo:6"));
- EXPECT_TRUE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(1ul, flags.size());
- EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
-}
-
-TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoNewName) {
- FieldTrialFlags flags;
-
- EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
- "Group77 foo:6"));
- EXPECT_TRUE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(1ul, flags.size());
- EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
-}
-
-TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoNewNameOverridesOld) {
- FieldTrialFlags flags;
-
- EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
- "Group77 foo:6"));
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended",
- "Group78 foo:5"));
- EXPECT_TRUE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(1ul, flags.size());
- EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
-}
-
-TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoLotsOfFlags) {
- FieldTrialFlags flags;
-
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
- "EmbeddedSearch", "Group77 bar:1 baz:7 cat:dogs"));
- EXPECT_TRUE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(3ul, flags.size());
- EXPECT_EQ(true, GetBoolValueForFlagWithDefault("bar", false, flags));
- EXPECT_EQ(7ul, GetUInt64ValueForFlagWithDefault("baz", 0, flags));
- EXPECT_EQ("dogs",
- GetStringValueForFlagWithDefault("cat", std::string(), flags));
- EXPECT_EQ("default",
- GetStringValueForFlagWithDefault("moose", "default", flags));
-}
-
-TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoDisabled) {
- FieldTrialFlags flags;
-
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
- "EmbeddedSearch", "Group77 bar:1 baz:7 cat:dogs DISABLED"));
- EXPECT_FALSE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(0ul, flags.size());
-}
-
-TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoControlFlags) {
- FieldTrialFlags flags;
-
- ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
- "EmbeddedSearch", "Control77 bar:1 baz:7 cat:dogs"));
- EXPECT_TRUE(GetFieldTrialInfo(&flags));
- EXPECT_EQ(3ul, flags.size());
-}
-
class SearchTest : public BrowserWithTestWindowTest {
protected:
virtual void SetUp() OVERRIDE {
diff --git a/chrome/browser/search_engines/ui_thread_search_terms_data.cc b/chrome/browser/search_engines/ui_thread_search_terms_data.cc
index 938b9e2..fba11b9 100644
--- a/chrome/browser/search_engines/ui_thread_search_terms_data.cc
+++ b/chrome/browser/search_engines/ui_thread_search_terms_data.cc
@@ -23,6 +23,7 @@
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
#include "components/google/core/browser/google_util.h"
+#include "components/search/search.h"
#include "content/public/browser/browser_thread.h"
#include "sync/protocol/sync.pb.h"
#include "url/gurl.h"
diff --git a/chrome/browser/thumbnails/thumbnail_service_impl.cc b/chrome/browser/thumbnails/thumbnail_service_impl.cc
index 029b94d..bdcb0fb 100644
--- a/chrome/browser/thumbnails/thumbnail_service_impl.cc
+++ b/chrome/browser/thumbnails/thumbnail_service_impl.cc
@@ -8,11 +8,11 @@
#include "base/memory/ref_counted_memory.h"
#include "base/time/time.h"
#include "chrome/browser/history/history_service.h"
-#include "chrome/browser/search/search.h"
#include "chrome/browser/thumbnails/content_based_thumbnailing_algorithm.h"
#include "chrome/browser/thumbnails/simple_thumbnail_crop.h"
#include "chrome/browser/thumbnails/thumbnailing_context.h"
#include "chrome/common/chrome_switches.h"
+#include "components/search/search.h"
#include "url/gurl.h"
using content::BrowserThread;
diff --git a/chrome/browser/ui/bookmarks/bookmark_utils.cc b/chrome/browser/ui/bookmarks/bookmark_utils.cc
index 72af92d..5cab1b4 100644
--- a/chrome/browser/ui/bookmarks/bookmark_utils.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_utils.cc
@@ -22,6 +22,7 @@
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/search/search.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_registry.h"
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 33af834..c8caf53 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -151,6 +151,7 @@
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_utils.h"
#include "components/google/core/browser/google_url_tracker.h"
+#include "components/search/search.h"
#include "components/startup_metric_utils/startup_metric_utils.h"
#include "components/web_modal/popup_manager.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
diff --git a/chrome/browser/ui/extensions/extension_install_ui_default.cc b/chrome/browser/ui/extensions/extension_install_ui_default.cc
index 74d2664..448756b 100644
--- a/chrome/browser/ui/extensions/extension_install_ui_default.cc
+++ b/chrome/browser/ui/extensions/extension_install_ui_default.cc
@@ -12,7 +12,6 @@
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search/search.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/app_list/app_list_service.h"
@@ -31,6 +30,7 @@
#include "chrome/common/url_constants.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "components/infobars/core/infobar.h"
+#include "components/search/search.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/omnibox/omnibox_controller.cc b/chrome/browser/ui/omnibox/omnibox_controller.cc
index 7c63988..b754eec 100644
--- a/chrome/browser/ui/omnibox/omnibox_controller.cc
+++ b/chrome/browser/ui/omnibox/omnibox_controller.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
#include "chrome/browser/ui/omnibox/omnibox_popup_view.h"
#include "chrome/common/instant_types.h"
+#include "components/search/search.h"
#include "extensions/common/constants.h"
#include "ui/gfx/rect.h"
diff --git a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
index fd92ef6..d972c82 100644
--- a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
+++ b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
#include "chrome/browser/ui/search/instant_search_prerenderer.h"
#include "chrome/browser/ui/search/search_tab_helper.h"
+#include "components/search/search.h"
#include "components/search_engines/template_url_service.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/search/search_model.cc b/chrome/browser/ui/search/search_model.cc
index fac64e6..1d530dd 100644
--- a/chrome/browser/ui/search/search_model.cc
+++ b/chrome/browser/ui/search/search_model.cc
@@ -4,8 +4,8 @@
#include "chrome/browser/ui/search/search_model.h"
-#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/search/search_model_observer.h"
+#include "components/search/search.h"
SearchModel::State::State()
: instant_support(INSTANT_SUPPORT_UNKNOWN),
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
index 8b0f7b3..2071396 100644
--- a/chrome/browser/ui/search/search_tab_helper.cc
+++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -32,6 +32,7 @@
#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h"
#include "chrome/common/url_constants.h"
+#include "components/search/search.h"
#include "components/signin/core/browser/signin_manager.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_details.h"
diff --git a/chrome/browser/ui/webui/history_ui.cc b/chrome/browser/ui/webui/history_ui.cc
index d1f5047..67a9f39 100644
--- a/chrome/browser/ui/webui/history_ui.cc
+++ b/chrome/browser/ui/webui/history_ui.cc
@@ -28,7 +28,6 @@
#include "chrome/browser/history/web_history_service.h"
#include "chrome/browser/history/web_history_service_factory.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search/search.h"
#include "chrome/browser/sync/glue/device_info.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
@@ -41,6 +40,7 @@
#include "chrome/common/url_constants.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_utils.h"
+#include "components/search/search.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/url_data_source.h"
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 5f5246c..3c2128b 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2879,6 +2879,7 @@
'../components/components.gyp:precache_core',
'../components/components.gyp:query_parser',
'../components/components.gyp:rappor',
+ '../components/components.gyp:search',
'../components/components.gyp:search_engines',
'../components/components.gyp:search_provider_logos',
'../components/components.gyp:signin_core_browser',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 5f04b54..05585fd 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1291,8 +1291,8 @@
'browser/search/instant_unittest_base.cc',
'browser/search/instant_unittest_base.h',
'browser/search/most_visited_iframe_source_unittest.cc',
- 'browser/search/search_unittest.cc',
'browser/search/search_android_unittest.cc',
+ 'browser/search/search_unittest.cc',
'browser/search/suggestions/blacklist_store_unittest.cc',
'browser/search/suggestions/suggestions_service_unittest.cc',
'browser/search/suggestions/suggestions_store_unittest.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index a85ae97..bed3ab9 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -1293,9 +1293,6 @@ const char kEnableZeroSuggestPersonalized[] =
// Enables instant search clicks feature.
const char kEnableInstantSearchClicks[] = "enable-instant-search-clicks";
-// Enables EmbeddedSearch API in the search results page.
-const char kEnableEmbeddedSearchAPI[] = "enable-embeddedsearch-api";
-
#endif
#if defined(USE_ASH)
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 7d61423..2ae6ba0 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -368,7 +368,6 @@ extern const char kEnableZeroSuggestEtherNoSerp[];
extern const char kEnableZeroSuggestMostVisited[];
extern const char kEnableZeroSuggestPersonalized[];
extern const char kEnableInstantSearchClicks[];
-extern const char kEnableEmbeddedSearchAPI[];
#endif
#if defined(USE_ASH)
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 14df89e..c6bdb0a 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -61,6 +61,7 @@ group("all_components") {
"//components/query_parser",
"//components/rappor",
"//components/resources:components_resources",
+ "//components/search",
"//components/search_engines",
"//components/search_provider_logos",
"//components/sessions",
diff --git a/components/OWNERS b/components/OWNERS
index 6aeb6c9..acdffd2 100644
--- a/components/OWNERS
+++ b/components/OWNERS
@@ -133,6 +133,11 @@ per-file query_parser.gypi=sky@chromium.org
per-file rappor*=asvitkine@chromium.org
# OWNER-to-be: per-file rappor*=holte@chromium.org
+per-file search.gypi=kmadhusu@chromium.org
+per-file search.gypi=brettw@chromium.org
+per-file search.gypi=jered@chromium.org
+per-file search.gypi=samarth@chromium.org
+
per-file search_engines.gypi=pkasting@chromium.org
per-file search_engines.gypi=stevet@chromium.org
diff --git a/components/components.gyp b/components/components.gyp
index 344b686..6d45444 100644
--- a/components/components.gyp
+++ b/components/components.gyp
@@ -44,6 +44,7 @@
'pref_registry.gypi',
'query_parser.gypi',
'rappor.gypi',
+ 'search.gypi',
'search_provider_logos.gypi',
'signin.gypi',
'startup_metric_utils.gypi',
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index 2c6c371..e655cb8 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -162,6 +162,8 @@
'rappor/log_uploader_unittest.cc',
'rappor/rappor_metric_unittest.cc',
'rappor/rappor_service_unittest.cc',
+ 'search/search_android_unittest.cc',
+ 'search/search_unittest.cc',
'search_engines/default_search_manager_unittest.cc',
'search_engines/default_search_policy_handler_unittest.cc',
'search_engines/search_host_to_urls_map_unittest.cc',
@@ -351,6 +353,9 @@
# Dependencies of rappor
'components.gyp:rappor',
+ # Dependencies of search
+ 'components.gyp:search',
+
# Dependencies of search_engines
'components.gyp:search_engines',
@@ -457,6 +462,7 @@
['include', '^network_time/'],
['include', '^password_manager/'],
['include', '^precache/core/'],
+ ['include', '^search/'],
['include', '^search_engines/'],
['include', '^search_provider_logos/'],
['include', '^signin/'],
diff --git a/components/search.gypi b/components/search.gypi
new file mode 100644
index 0000000..8cb0fe7
--- /dev/null
+++ b/components/search.gypi
@@ -0,0 +1,24 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'search',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base'
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'search/search.cc',
+ 'search/search.h',
+ 'search/search_switches.cc',
+ 'search/search_switches.h',
+ ],
+ },
+ ],
+}
diff --git a/components/search/BUILD.gn b/components/search/BUILD.gn
new file mode 100644
index 0000000..a895701
--- /dev/null
+++ b/components/search/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+static_library("search") {
+ sources = [
+ "search.cc",
+ "search.h",
+ "search_switches.cc",
+ "search_switches.h",
+ ]
+
+ deps = [
+ "//base",
+ ]
+}
diff --git a/components/search/DEPS b/components/search/DEPS
new file mode 100644
index 0000000..80f6f90
--- /dev/null
+++ b/components/search/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+components/variations",
+]
diff --git a/components/search/OWNERS b/components/search/OWNERS
new file mode 100644
index 0000000..a7265f6
--- /dev/null
+++ b/components/search/OWNERS
@@ -0,0 +1,4 @@
+kmadhusu@chromium.org
+brettw@chromium.org
+jered@chromium.org
+samarth@chromium.org
diff --git a/components/search/search.cc b/components/search/search.cc
new file mode 100644
index 0000000..8689e51
--- /dev/null
+++ b/components/search/search.cc
@@ -0,0 +1,146 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/search/search.h"
+
+#include "base/command_line.h"
+#include "base/metrics/field_trial.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/search/search_switches.h"
+
+namespace chrome {
+
+namespace {
+
+// Configuration options for Embedded Search.
+// EmbeddedSearch field trials are named in such a way that we can parse out
+// the experiment configuration from the trial's group name in order to give
+// us maximum flexability in running experiments.
+// Field trial groups should be named things like "Group7 espv:2 instant:1".
+// The first token is always GroupN for some integer N, followed by a
+// space-delimited list of key:value pairs which correspond to these flags:
+const char kEmbeddedPageVersionFlagName[] = "espv";
+
+#if defined(OS_IOS)
+const uint64 kEmbeddedPageVersionDefault = 1;
+#elif defined(OS_ANDROID)
+const uint64 kEmbeddedPageVersionDefault = 1;
+// Use this variant to enable EmbeddedSearch SearchBox API in the results page.
+const uint64 kEmbeddedSearchEnabledVersion = 2;
+#else
+const uint64 kEmbeddedPageVersionDefault = 2;
+#endif
+
+// Constants for the field trial name and group prefix.
+// Note in M30 and below this field trial was named "InstantExtended" and in
+// M31 was renamed to EmbeddedSearch for clarity and cleanliness. Since we
+// can't easilly sync up Finch configs with the pushing of this change to
+// Dev & Canary, for now the code accepts both names.
+// TODO(dcblack): Remove the InstantExtended name once M31 hits the Beta
+// channel.
+const char kInstantExtendedFieldTrialName[] = "InstantExtended";
+const char kEmbeddedSearchFieldTrialName[] = "EmbeddedSearch";
+
+// If the field trial's group name ends with this string its configuration will
+// be ignored and Instant Extended will not be enabled by default.
+const char kDisablingSuffix[] = "DISABLED";
+
+} // namespace
+
+bool IsInstantExtendedAPIEnabled() {
+#if defined(OS_IOS)
+ return false;
+#elif defined(OS_ANDROID)
+ return EmbeddedSearchPageVersion() == kEmbeddedSearchEnabledVersion;
+#else
+ return true;
+#endif // defined(OS_IOS)
+}
+
+// Determine what embedded search page version to request from the user's
+// default search provider. If 0, the embedded search UI should not be enabled.
+uint64 EmbeddedSearchPageVersion() {
+#if defined(OS_ANDROID)
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableEmbeddedSearchAPI)) {
+ return kEmbeddedSearchEnabledVersion;
+ }
+#endif
+
+ FieldTrialFlags flags;
+ if (GetFieldTrialInfo(&flags)) {
+ return GetUInt64ValueForFlagWithDefault(kEmbeddedPageVersionFlagName,
+ kEmbeddedPageVersionDefault,
+ flags);
+ }
+ return kEmbeddedPageVersionDefault;
+}
+
+bool GetFieldTrialInfo(FieldTrialFlags* flags) {
+ // Get the group name. If the EmbeddedSearch trial doesn't exist, look for
+ // the older InstantExtended name.
+ 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;
+
+ // We have a valid trial that isn't disabled. Extract the flags.
+ std::string group_prefix(group_name);
+ size_t first_space = group_name.find(" ");
+ if (first_space != std::string::npos) {
+ // There is a flags section of the group name. Split that out and parse it.
+ group_prefix = group_name.substr(0, first_space);
+ if (!base::SplitStringIntoKeyValuePairs(group_name.substr(first_space),
+ ':', ' ', flags)) {
+ // Failed to parse the flags section. Assume the whole group name is
+ // invalid.
+ return false;
+ }
+ }
+ return true;
+}
+
+// Given a FieldTrialFlags object, returns the string value of the provided
+// flag.
+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;
+}
+
+// Given a FieldTrialFlags object, returns the uint64 value of the provided
+// flag.
+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;
+}
+
+// Given a FieldTrialFlags object, returns the boolean value of the provided
+// flag.
+bool GetBoolValueForFlagWithDefault(const std::string& flag,
+ bool default_value,
+ const FieldTrialFlags& flags) {
+ return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags);
+}
+
+} // namespace chrome
diff --git a/components/search/search.h b/components/search/search.h
new file mode 100644
index 0000000..df27e60
--- /dev/null
+++ b/components/search/search.h
@@ -0,0 +1,59 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SEARCH_SEARCH_H_
+#define COMPONENTS_SEARCH_SEARCH_H_
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/strings/string16.h"
+
+namespace chrome {
+
+// Returns whether the Instant Extended API is enabled.
+bool IsInstantExtendedAPIEnabled();
+
+// Returns the value to pass to the &espv CGI parameter when loading the
+// embedded search page from the user's default search provider. Returns 0 if
+// the Instant Extended API is not enabled.
+uint64 EmbeddedSearchPageVersion();
+
+// Type for a collection of experiment configuration parameters.
+typedef std::vector<std::pair<std::string, std::string> > FieldTrialFlags;
+
+// Finds the active field trial group name and parses out the configuration
+// flags. On success, |flags| will be filled with the field trial flags. |flags|
+// must not be NULL. Returns true iff the active field trial is successfully
+// parsed and not disabled.
+// Note that |flags| may be successfully populated in some cases when false is
+// returned - in these cases it should not be used.
+// Exposed for testing only.
+bool GetFieldTrialInfo(FieldTrialFlags* flags);
+
+// Given a FieldTrialFlags object, returns the string value of the provided
+// flag.
+// Exposed for testing only.
+std::string GetStringValueForFlagWithDefault(const std::string& flag,
+ const std::string& default_value,
+ const FieldTrialFlags& flags);
+
+// Given a FieldTrialFlags object, returns the uint64 value of the provided
+// flag.
+// Exposed for testing only.
+uint64 GetUInt64ValueForFlagWithDefault(const std::string& flag,
+ uint64 default_value,
+ const FieldTrialFlags& flags);
+
+// Given a FieldTrialFlags object, returns the bool value of the provided flag.
+// Exposed for testing only.
+bool GetBoolValueForFlagWithDefault(const std::string& flag,
+ bool default_value,
+ const FieldTrialFlags& flags);
+
+} // namespace chrome
+
+#endif // COMPONENTS_SEARCH_SEARCH_H_
diff --git a/components/search/search_android_unittest.cc b/components/search/search_android_unittest.cc
new file mode 100644
index 0000000..9c67edff
--- /dev/null
+++ b/components/search/search_android_unittest.cc
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/search/search.h"
+
+#include "base/command_line.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/statistics_recorder.h"
+#include "components/search/search_switches.h"
+#include "components/variations/entropy_provider.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chrome {
+
+namespace {
+
+TEST(SearchTest, EmbeddedSearchAPIEnabled) {
+ EXPECT_EQ(1ul, EmbeddedSearchPageVersion());
+ EXPECT_FALSE(IsInstantExtendedAPIEnabled());
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableEmbeddedSearchAPI);
+ EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
+ EXPECT_TRUE(IsInstantExtendedAPIEnabled());
+}
+
+} // namespace
+
+} // namespace chrome
diff --git a/components/search/search_switches.cc b/components/search/search_switches.cc
new file mode 100644
index 0000000..9359725
--- /dev/null
+++ b/components/search/search_switches.cc
@@ -0,0 +1,16 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/search/search_switches.h"
+
+namespace switches {
+
+#if defined(OS_ANDROID)
+
+// Enables EmbeddedSearch API in the search results page.
+const char kEnableEmbeddedSearchAPI[] = "enable-embeddedsearch-api";
+
+#endif
+
+} // namespace switches
diff --git a/components/search/search_switches.h b/components/search/search_switches.h
new file mode 100644
index 0000000..48b50c1
--- /dev/null
+++ b/components/search/search_switches.h
@@ -0,0 +1,18 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SEARCH_SEARCH_SWITCHES_H_
+#define COMPONENTS_SEARCH_SEARCH_SWITCHES_H_
+
+#include "build/build_config.h"
+
+namespace switches {
+
+#if defined(OS_ANDROID)
+extern const char kEnableEmbeddedSearchAPI[];
+#endif
+
+} // namespace switches
+
+#endif // COMPONENTS_SEARCH_SEARCH_SWITCHES_H_
diff --git a/components/search/search_unittest.cc b/components/search/search_unittest.cc
new file mode 100644
index 0000000..b8c4e1d
--- /dev/null
+++ b/components/search/search_unittest.cc
@@ -0,0 +1,133 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/search/search.h"
+
+#include "base/metrics/field_trial.h"
+#include "base/metrics/statistics_recorder.h"
+#include "components/variations/entropy_provider.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chrome {
+
+class EmbeddedSearchFieldTrialTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ field_trial_list_.reset(new base::FieldTrialList(
+ new metrics::SHA1EntropyProvider("42")));
+ base::StatisticsRecorder::Initialize();
+ }
+
+ private:
+ scoped_ptr<base::FieldTrialList> field_trial_list_;
+};
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoEmptyAndValid) {
+ FieldTrialFlags flags;
+
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidNumber) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77.2"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidName) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Invalid77"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidGroup) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidFlag) {
+ FieldTrialFlags flags;
+
+ EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77 foo:6"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(1ul, flags.size());
+ EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoNewName) {
+ FieldTrialFlags flags;
+
+ EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77 foo:6"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(1ul, flags.size());
+ EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoNewNameOverridesOld) {
+ FieldTrialFlags flags;
+
+ EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77 foo:6"));
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended",
+ "Group78 foo:5"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(1ul, flags.size());
+ EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoLotsOfFlags) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
+ "EmbeddedSearch", "Group77 bar:1 baz:7 cat:dogs"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(3ul, flags.size());
+ EXPECT_EQ(true, GetBoolValueForFlagWithDefault("bar", false, flags));
+ EXPECT_EQ(7ul, GetUInt64ValueForFlagWithDefault("baz", 0, flags));
+ EXPECT_EQ("dogs",
+ GetStringValueForFlagWithDefault("cat", std::string(), flags));
+ EXPECT_EQ("default",
+ GetStringValueForFlagWithDefault("moose", "default", flags));
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoDisabled) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
+ "EmbeddedSearch", "Group77 bar:1 baz:7 cat:dogs DISABLED"));
+ EXPECT_FALSE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoControlFlags) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
+ "EmbeddedSearch", "Control77 bar:1 baz:7 cat:dogs"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(3ul, flags.size());
+}
+
+} // namespace chrome