summaryrefslogtreecommitdiffstats
path: root/chrome/browser/omnibox
diff options
context:
space:
mode:
authormpearson@chromium.org <mpearson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-09 07:37:29 +0000
committermpearson@chromium.org <mpearson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-09 07:37:29 +0000
commitd92134c12f51937ee234731249986ee31adf86bf (patch)
tree07fd386a11f9798105f889732e041287a96e7bfb /chrome/browser/omnibox
parent2541de97ad9b325a0fe4b3ac9b6018675a5c839b (diff)
downloadchromium_src-d92134c12f51937ee234731249986ee31adf86bf.zip
chromium_src-d92134c12f51937ee234731249986ee31adf86bf.tar.gz
chromium_src-d92134c12f51937ee234731249986ee31adf86bf.tar.bz2
Omnibox: Create DemoteByType Experiment
This experiment, which runs as part of the bundled omnibox field trial, uses the field trial parameters to demote results of particular types (e.g., HISTORY_TITLE results), possibly depending on context (e.g., search results page doing search term replacement). It also improves the testing framework for field trial parameters, allowing them to be cleared between consecutive TEST_F()s. Tested via unit tests and by setting up my local variations server with some parameters and making sure results can be demoted or omitted. BUG=264066 Review URL: https://chromiumcodereview.appspot.com/22031002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216633 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/omnibox')
-rw-r--r--chrome/browser/omnibox/omnibox_field_trial.cc31
-rw-r--r--chrome/browser/omnibox/omnibox_field_trial.h19
-rw-r--r--chrome/browser/omnibox/omnibox_field_trial_unittest.cc75
3 files changed, 107 insertions, 18 deletions
diff --git a/chrome/browser/omnibox/omnibox_field_trial.cc b/chrome/browser/omnibox/omnibox_field_trial.cc
index 83b9143..2bec78b 100644
--- a/chrome/browser/omnibox/omnibox_field_trial.cc
+++ b/chrome/browser/omnibox/omnibox_field_trial.cc
@@ -8,6 +8,7 @@
#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/stringprintf.h"
#include "chrome/common/metrics/metrics_util.h"
@@ -26,6 +27,7 @@ const char kBundledExperimentFieldTrialName[] = "OmniboxBundledExperimentV1";
// Rule names used by the bundled experiment.
const char kSearchHistoryRule[] = "SearchHistory";
+const char kDemoteByTypeRule[] = "DemoteByType";
// The autocomplete dynamic field trial name prefix. Each field trial is
// configured dynamically and is retrieved automatically by Chrome during
@@ -233,6 +235,35 @@ bool OmniboxFieldTrial::SearchHistoryDisable(
kSearchHistoryRule, current_page_classification) == "Disable";
}
+void OmniboxFieldTrial::GetDemotionsByType(
+ AutocompleteInput::PageClassification current_page_classification,
+ DemotionMultipliers* demotions_by_type) {
+ demotions_by_type->clear();
+ const std::string demotion_rule =
+ OmniboxFieldTrial::GetValueForRuleInContext(
+ kDemoteByTypeRule,
+ current_page_classification);
+ // The value of the DemoteByType rule is a comma-separated list of
+ // {ResultType + ":" + Number} where ResultType is an AutocompleteMatchType::
+ // Type enum represented as an integer and Number is an integer number
+ // between 0 and 100 inclusive. Relevance scores of matches of that result
+ // type are multiplied by Number / 100. 100 means no change.
+ base::StringPairs kv_pairs;
+ if (base::SplitStringIntoKeyValuePairs(demotion_rule, ':', ',', &kv_pairs)) {
+ for (base::StringPairs::const_iterator it = kv_pairs.begin();
+ it != kv_pairs.end(); ++it) {
+ // This is a best-effort conversion; we trust the hand-crafted parameters
+ // downloaded from the server to be perfect. There's no need for handle
+ // errors smartly.
+ int k, v;
+ base::StringToInt(it->first, &k);
+ base::StringToInt(it->second, &v);
+ (*demotions_by_type)[static_cast<AutocompleteMatchType::Type>(k)] =
+ static_cast<float>(v) / 100.0f;
+ }
+ }
+}
+
// Background and implementation details:
//
// Each experiment group in any field trial can come with an optional set of
diff --git a/chrome/browser/omnibox/omnibox_field_trial.h b/chrome/browser/omnibox/omnibox_field_trial.h
index 1ad3b16..7bfd2d83 100644
--- a/chrome/browser/omnibox/omnibox_field_trial.h
+++ b/chrome/browser/omnibox/omnibox_field_trial.h
@@ -5,16 +5,23 @@
#ifndef CHROME_BROWSER_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_
#define CHROME_BROWSER_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_
+#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "chrome/browser/autocomplete/autocomplete_input.h"
+#include "chrome/common/autocomplete_match_type.h"
// This class manages the Omnibox field trials.
class OmniboxFieldTrial {
public:
+ // A mapping that contains multipliers indicating that matches of the
+ // specified type should have their relevance score multiplied by the
+ // given number. Omitted types are assumed to have multipliers of 1.0.
+ typedef std::map<AutocompleteMatchType::Type, float> DemotionMultipliers;
+
// Creates the static field trial groups.
// *** MUST NOT BE CALLED MORE THAN ONCE. ***
static void ActivateStaticTrials();
@@ -118,6 +125,18 @@ class OmniboxFieldTrial {
static bool SearchHistoryDisable(
AutocompleteInput::PageClassification current_page_classification);
+ // ---------------------------------------------------------
+ // For the DemoteByType experiment that's part of the bundled omnibox field
+ // trial.
+
+ // If the user is in an experiment group that, in the provided
+ // |current_page_classification| context, demotes the relevance scores
+ // of certain types of matches, populates the |demotions_by_type| map
+ // appropriately. Otherwise, clears |demotions_by_type|.
+ static void GetDemotionsByType(
+ AutocompleteInput::PageClassification current_page_classification,
+ DemotionMultipliers* demotions_by_type);
+
private:
FRIEND_TEST_ALL_PREFIXES(OmniboxFieldTrialTest, GetValueForRuleInContext);
diff --git a/chrome/browser/omnibox/omnibox_field_trial_unittest.cc b/chrome/browser/omnibox/omnibox_field_trial_unittest.cc
index 9ccb00f..1d49801 100644
--- a/chrome/browser/omnibox/omnibox_field_trial_unittest.cc
+++ b/chrome/browser/omnibox/omnibox_field_trial_unittest.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/omnibox/omnibox_field_trial.h"
#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string16.h"
#include "chrome/common/metrics/entropy_provider.h"
@@ -13,24 +14,17 @@
class OmniboxFieldTrialTest : public testing::Test {
public:
- OmniboxFieldTrialTest() {}
-
- static void SetUpTestCase() {
+ OmniboxFieldTrialTest() {
ResetFieldTrialList();
}
- static void TearDownTestCase() {
- delete field_trial_list_;
- field_trial_list_ = NULL;
- }
-
- static void ResetFieldTrialList() {
- // It's important to delete the old pointer first which sets
- // FieldTrialList::global_ to NULL.
- if (field_trial_list_)
- delete field_trial_list_;
- field_trial_list_ = new base::FieldTrialList(
- new metrics::SHA1EntropyProvider("foo"));
+ void ResetFieldTrialList() {
+ // Destroy the existing FieldTrialList before creating a new one to avoid
+ // a DCHECK.
+ field_trial_list_.reset();
+ field_trial_list_.reset(new base::FieldTrialList(
+ new metrics::SHA1EntropyProvider("foo")));
+ chrome_variations::testing::ClearAllVariationParams();
OmniboxFieldTrial::ActivateDynamicTrials();
}
@@ -43,15 +37,28 @@ class OmniboxFieldTrialTest : public testing::Test {
return trial;
}
+ // EXPECTS that demotions[match_type] exists with value expected_value.
+ static void VerifyDemotion(
+ const OmniboxFieldTrial::DemotionMultipliers& demotions,
+ AutocompleteMatchType::Type match_type,
+ float expected_value);
+
private:
- // Needed for Activate{Static/Dynamic}Trials().
- static base::FieldTrialList* field_trial_list_;
+ scoped_ptr<base::FieldTrialList> field_trial_list_;
DISALLOW_COPY_AND_ASSIGN(OmniboxFieldTrialTest);
};
// static
-base::FieldTrialList* OmniboxFieldTrialTest::field_trial_list_ = NULL;
+void OmniboxFieldTrialTest::VerifyDemotion(
+ const OmniboxFieldTrial::DemotionMultipliers& demotions,
+ AutocompleteMatchType::Type match_type,
+ float expected_value) {
+ OmniboxFieldTrial::DemotionMultipliers::const_iterator demotion_it =
+ demotions.find(match_type);
+ ASSERT_TRUE(demotion_it != demotions.end());
+ EXPECT_FLOAT_EQ(expected_value, demotion_it->second);
+}
// Test if GetDisabledProviderTypes() properly parses various field trial
// group names.
@@ -131,6 +138,38 @@ TEST_F(OmniboxFieldTrialTest, ZeroSuggestFieldTrial) {
}
}
+TEST_F(OmniboxFieldTrialTest, GetDemotionsByTypeWithFallback) {
+ // Must be the same as kBundledExperimentFieldTrialName
+ // defined in omnibox_field_trial.cc.
+ const std::string kTrialName = "OmniboxBundledExperimentV1";
+ // Must be the same as kDemoteByTypeRule defined in
+ // omnibox_field_trial.cc.
+ const std::string kRuleName = "DemoteByType";
+ {
+ std::map<std::string, std::string> params;
+ params[kRuleName + ":1"] = "1:50,2:0";
+ params[kRuleName + ":3"] = "5:100";
+ params[kRuleName + ":*"] = "1:25";
+ ASSERT_TRUE(chrome_variations::AssociateVariationParams(
+ kTrialName, "A", params));
+ }
+ base::FieldTrialList::CreateFieldTrial(kTrialName, "A");
+ OmniboxFieldTrial::DemotionMultipliers demotions_by_type;
+ OmniboxFieldTrial::GetDemotionsByType(
+ AutocompleteInput::NEW_TAB_PAGE, &demotions_by_type);
+ ASSERT_EQ(2u, demotions_by_type.size());
+ VerifyDemotion(demotions_by_type, AutocompleteMatchType::HISTORY_URL, 0.5);
+ VerifyDemotion(demotions_by_type, AutocompleteMatchType::HISTORY_TITLE, 0.0);
+ OmniboxFieldTrial::GetDemotionsByType(
+ AutocompleteInput::HOMEPAGE, &demotions_by_type);
+ ASSERT_EQ(1u, demotions_by_type.size());
+ VerifyDemotion(demotions_by_type, AutocompleteMatchType::NAVSUGGEST, 1.0);
+ OmniboxFieldTrial::GetDemotionsByType(
+ AutocompleteInput::BLANK, &demotions_by_type);
+ ASSERT_EQ(1u, demotions_by_type.size());
+ VerifyDemotion(demotions_by_type, AutocompleteMatchType::HISTORY_URL, 0.25);
+}
+
TEST_F(OmniboxFieldTrialTest, GetValueForRuleInContext) {
// Must be the same as kBundledExperimentFieldTrialName
// defined in omnibox_field_trial.cc.