12385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 22385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Use of this source code is governed by a BSD-style license that can be 32385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// found in the LICENSE file. 42385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 52385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#ifndef CHROME_COMMON_METRICS_VARIATIONS_VARIATIONS_ASSOCIATED_DATA_H_ 62385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#define CHROME_COMMON_METRICS_VARIATIONS_VARIATIONS_ASSOCIATED_DATA_H_ 72385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 82385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include <map> 92385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include <string> 102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/metrics/field_trial.h" 122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/strings/string16.h" 132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/common/metrics/variations/variation_ids.h" 142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// This file provides various helpers that extend the functionality around 162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// base::FieldTrial. 172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// 182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// This includes several simple APIs to handle getting and setting additional 192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// data related to Chrome variations, such as parameters and Google variation 202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// IDs. These APIs are meant to extend the base::FieldTrial APIs to offer extra 212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// functionality that is not offered by the simpler base::FieldTrial APIs. 222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// 232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// The AssociateGoogleVariationID and AssociateVariationParams functions are 242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// generally meant to be called by the VariationsService based on server-side 252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// variation configs, but may also be used for client-only field trials by 262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// invoking them directly after appending all the groups to a FieldTrial. 272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// 282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Experiment code can then use the getter APIs to retrieve variation parameters 292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// or IDs: 302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// 312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// std::map<std::string, std::string> params; 322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// if (GetVariationParams("trial", ¶ms)) { 332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// // use |params| 342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// } 352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// 362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// std::string value = GetVariationParamValue("trial", "param_x"); 372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// // use |value|, which will be "" if it does not exist 382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// 392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// VariationID id = GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, "trial", 402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// "group1"); 412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// if (id != chrome_variations::kEmptyID) { 422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// // use |id| 432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// } 442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochnamespace chrome_variations { 462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// The Unique ID of a trial and its active group, where the name and group 482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// identifiers are hashes of the trial and group name strings. 492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochstruct ActiveGroupId { 502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch uint32 name; 512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch uint32 group; 522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}; 532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Returns an ActiveGroupId struct for the given trial and group names. 552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochActiveGroupId MakeActiveGroupId(const std::string& trial_name, 562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string& group_name); 572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// We need to supply a Compare class for templates since ActiveGroupId is a 592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// user-defined type. 602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochstruct ActiveGroupIdCompare { 612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch bool operator() (const ActiveGroupId& lhs, const ActiveGroupId& rhs) const { 622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // The group and name fields are just SHA-1 Hashes, so we just need to treat 632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // them as IDs and do a less-than comparison. We test group first, since 642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // name is more likely to collide. 652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (lhs.group != rhs.group) 662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return lhs.group < rhs.group; 672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return lhs.name < rhs.name; 682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}; 702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// A key into the Associate/Get methods for VariationIDs. This is used to create 722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// separate ID associations for separate parties interested in VariationIDs. 732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochenum IDCollectionKey { 742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // This collection is used by Google web properties, transmitted through the 752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // X-Chrome-Variations header. 762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch GOOGLE_WEB_PROPERTIES, 772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // This collection is used by Google update services, transmitted through the 782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Google Update experiment labels. 792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch GOOGLE_UPDATE_SERVICE, 802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // The total count of collections. 812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ID_COLLECTION_COUNT, 822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}; 832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Associate a chrome_variations::VariationID value with a FieldTrial group for 852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// collection |key|. If an id was previously set for |trial_name| and 862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// |group_name|, this does nothing. The group is denoted by |trial_name| and 872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// |group_name|. This must be called whenever a FieldTrial is prepared (create 882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// the trial and append groups) and needs to have a 892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// chrome_variations::VariationID associated with it so Google servers can 902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// recognize the FieldTrial. Thread safe. 912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid AssociateGoogleVariationID(IDCollectionKey key, 922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string& trial_name, 932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string& group_name, 942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch VariationID id); 952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// As above, but overwrites any previously set id. Thread safe. 972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid AssociateGoogleVariationIDForce(IDCollectionKey key, 982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string& trial_name, 992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string& group_name, 1002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch VariationID id); 1012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Retrieve the chrome_variations::VariationID associated with a FieldTrial 1032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// group for collection |key|. The group is denoted by |trial_name| and 1042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// |group_name|. This will return chrome_variations::kEmptyID if there is 1052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// currently no associated ID for the named group. This API can be nicely 1062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// combined with FieldTrial::GetActiveFieldTrialGroups() to enumerate the 1072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// variation IDs for all active FieldTrial groups. Thread safe. 1082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochVariationID GetGoogleVariationID(IDCollectionKey key, 1092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string& trial_name, 1102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string& group_name); 1112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Associates the specified set of key-value |params| with the variation 1132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// specified by |trial_name| and |group_name|. Fails and returns false if the 1142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// specified variation already has params associated with it or the field trial 1152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// is already active (group() has been called on it). Thread safe. 1162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool AssociateVariationParams(const std::string& trial_name, 1172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string& group_name, 1182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::map<std::string, std::string>& params); 1192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Retrieves the set of key-value |params| for the variation associated with 1212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// the specified field trial, based on its selected group. If the field trial 1222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// does not exist or its selected group does not have any parameters associated 1232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// with it, returns false and does not modify |params|. Calling this function 1242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// will result in the field trial being marked as active if found (i.e. group() 1252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// will be called on it), if it wasn't already. Currently, this information is 1262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// only available from the browser process. Thread safe. 1272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool GetVariationParams(const std::string& trial_name, 1282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch std::map<std::string, std::string>* params); 1292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Retrieves a specific parameter value corresponding to |param_name| for the 1312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// variation associated with the specified field trial, based on its selected 1322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// group. If the field trial does not exist or the specified parameter does not 1332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// exist, returns an empty string. Calling this function will result in the 1342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// field trial being marked as active if found (i.e. group() will be called on 1352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// it), if it wasn't already. Currently, this information is only available from 1362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// the browser process. Thread safe. 1372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochstd::string GetVariationParamValue(const std::string& trial_name, 1382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string& param_name); 1392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1404311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch// Expose some functions for testing. 1412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochnamespace testing { 1422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Clears all of the mapped associations. 1442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid ClearAllVariationIDs(); 1452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1464311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch// Clears all of the associated params. 1474311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdochvoid ClearAllVariationParams(); 1484311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch 1492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} // namespace testing 1502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} // namespace chrome_variations 1522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif // CHROME_COMMON_METRICS_VARIATIONS_VARIATIONS_ASSOCIATED_DATA_H_ 154