OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef COMPONENTS_VARIATIONS_VARIATIONS_ASSOCIATED_DATA_H_ |
| 6 #define COMPONENTS_VARIATIONS_VARIATIONS_ASSOCIATED_DATA_H_ |
| 7 |
| 8 #include <map> |
| 9 #include <string> |
| 10 |
| 11 #include "base/metrics/field_trial.h" |
| 12 |
| 13 // This file provides various helpers that extend the functionality around |
| 14 // base::FieldTrial. |
| 15 // |
| 16 // This includes several simple APIs to handle getting and setting additional |
| 17 // data related to Chrome variations, such as parameters and Google variation |
| 18 // IDs. These APIs are meant to extend the base::FieldTrial APIs to offer extra |
| 19 // functionality that is not offered by the simpler base::FieldTrial APIs. |
| 20 // |
| 21 // The AssociateGoogleVariationID and AssociateVariationParams functions are |
| 22 // generally meant to be called by the VariationsService based on server-side |
| 23 // variation configs, but may also be used for client-only field trials by |
| 24 // invoking them directly after appending all the groups to a FieldTrial. |
| 25 // |
| 26 // Experiment code can then use the getter APIs to retrieve variation parameters |
| 27 // or IDs: |
| 28 // |
| 29 // std::map<std::string, std::string> params; |
| 30 // if (GetVariationParams("trial", ¶ms)) { |
| 31 // // use |params| |
| 32 // } |
| 33 // |
| 34 // std::string value = GetVariationParamValue("trial", "param_x"); |
| 35 // // use |value|, which will be "" if it does not exist |
| 36 // |
| 37 // VariationID id = GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, "trial", |
| 38 // "group1"); |
| 39 // if (id != chrome_variations::kEmptyID) { |
| 40 // // use |id| |
| 41 // } |
| 42 |
| 43 namespace chrome_variations { |
| 44 |
| 45 typedef int VariationID; |
| 46 |
| 47 const VariationID EMPTY_ID = 0; |
| 48 |
| 49 // The Unique ID of a trial and its active group, where the name and group |
| 50 // identifiers are hashes of the trial and group name strings. |
| 51 struct ActiveGroupId { |
| 52 uint32 name; |
| 53 uint32 group; |
| 54 }; |
| 55 |
| 56 // Returns an ActiveGroupId struct for the given trial and group names. |
| 57 ActiveGroupId MakeActiveGroupId(const std::string& trial_name, |
| 58 const std::string& group_name); |
| 59 |
| 60 // We need to supply a Compare class for templates since ActiveGroupId is a |
| 61 // user-defined type. |
| 62 struct ActiveGroupIdCompare { |
| 63 bool operator() (const ActiveGroupId& lhs, const ActiveGroupId& rhs) const { |
| 64 // The group and name fields are just SHA-1 Hashes, so we just need to treat |
| 65 // them as IDs and do a less-than comparison. We test group first, since |
| 66 // name is more likely to collide. |
| 67 if (lhs.group != rhs.group) |
| 68 return lhs.group < rhs.group; |
| 69 return lhs.name < rhs.name; |
| 70 } |
| 71 }; |
| 72 |
| 73 // A key into the Associate/Get methods for VariationIDs. This is used to create |
| 74 // separate ID associations for separate parties interested in VariationIDs. |
| 75 enum IDCollectionKey { |
| 76 // This collection is used by Google web properties, transmitted through the |
| 77 // X-Chrome-Variations header. |
| 78 GOOGLE_WEB_PROPERTIES, |
| 79 // This collection is used by Google update services, transmitted through the |
| 80 // Google Update experiment labels. |
| 81 GOOGLE_UPDATE_SERVICE, |
| 82 // The total count of collections. |
| 83 ID_COLLECTION_COUNT, |
| 84 }; |
| 85 |
| 86 // Associate a chrome_variations::VariationID value with a FieldTrial group for |
| 87 // collection |key|. If an id was previously set for |trial_name| and |
| 88 // |group_name|, this does nothing. The group is denoted by |trial_name| and |
| 89 // |group_name|. This must be called whenever a FieldTrial is prepared (create |
| 90 // the trial and append groups) and needs to have a |
| 91 // chrome_variations::VariationID associated with it so Google servers can |
| 92 // recognize the FieldTrial. Thread safe. |
| 93 void AssociateGoogleVariationID(IDCollectionKey key, |
| 94 const std::string& trial_name, |
| 95 const std::string& group_name, |
| 96 VariationID id); |
| 97 |
| 98 // As above, but overwrites any previously set id. Thread safe. |
| 99 void AssociateGoogleVariationIDForce(IDCollectionKey key, |
| 100 const std::string& trial_name, |
| 101 const std::string& group_name, |
| 102 VariationID id); |
| 103 |
| 104 // Retrieve the chrome_variations::VariationID associated with a FieldTrial |
| 105 // group for collection |key|. The group is denoted by |trial_name| and |
| 106 // |group_name|. This will return chrome_variations::kEmptyID if there is |
| 107 // currently no associated ID for the named group. This API can be nicely |
| 108 // combined with FieldTrial::GetActiveFieldTrialGroups() to enumerate the |
| 109 // variation IDs for all active FieldTrial groups. Thread safe. |
| 110 VariationID GetGoogleVariationID(IDCollectionKey key, |
| 111 const std::string& trial_name, |
| 112 const std::string& group_name); |
| 113 |
| 114 // Associates the specified set of key-value |params| with the variation |
| 115 // specified by |trial_name| and |group_name|. Fails and returns false if the |
| 116 // specified variation already has params associated with it or the field trial |
| 117 // is already active (group() has been called on it). Thread safe. |
| 118 bool AssociateVariationParams(const std::string& trial_name, |
| 119 const std::string& group_name, |
| 120 const std::map<std::string, std::string>& params); |
| 121 |
| 122 // Retrieves the set of key-value |params| for the variation associated with |
| 123 // the specified field trial, based on its selected group. If the field trial |
| 124 // does not exist or its selected group does not have any parameters associated |
| 125 // with it, returns false and does not modify |params|. Calling this function |
| 126 // will result in the field trial being marked as active if found (i.e. group() |
| 127 // will be called on it), if it wasn't already. Currently, this information is |
| 128 // only available from the browser process. Thread safe. |
| 129 bool GetVariationParams(const std::string& trial_name, |
| 130 std::map<std::string, std::string>* params); |
| 131 |
| 132 // Retrieves a specific parameter value corresponding to |param_name| for the |
| 133 // variation associated with the specified field trial, based on its selected |
| 134 // group. If the field trial does not exist or the specified parameter does not |
| 135 // exist, returns an empty string. Calling this function will result in the |
| 136 // field trial being marked as active if found (i.e. group() will be called on |
| 137 // it), if it wasn't already. Currently, this information is only available from |
| 138 // the browser process. Thread safe. |
| 139 std::string GetVariationParamValue(const std::string& trial_name, |
| 140 const std::string& param_name); |
| 141 |
| 142 // Expose some functions for testing. |
| 143 namespace testing { |
| 144 |
| 145 // Clears all of the mapped associations. |
| 146 void ClearAllVariationIDs(); |
| 147 |
| 148 // Clears all of the associated params. |
| 149 void ClearAllVariationParams(); |
| 150 |
| 151 } // namespace testing |
| 152 |
| 153 } // namespace chrome_variations |
| 154 |
| 155 #endif // COMPONENTS_VARIATIONS_VARIATIONS_ASSOCIATED_DATA_H_ |
OLD | NEW |