OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 #ifndef CHROME_COMMON_METRICS_EXPERIMENTS_HELPER_H_ | 5 #ifndef CHROME_COMMON_METRICS_EXPERIMENTS_HELPER_H_ |
6 #define CHROME_COMMON_METRICS_EXPERIMENTS_HELPER_H_ | 6 #define CHROME_COMMON_METRICS_EXPERIMENTS_HELPER_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
| 9 #include <string> |
| 10 #include <vector> |
| 11 |
9 #include "base/metrics/field_trial.h" | 12 #include "base/metrics/field_trial.h" |
10 | 13 |
11 // This namespace provides various helpers that extend the functionality around | 14 // This namespace provides various helpers that extend the functionality around |
12 // base::FieldTrial. | 15 // base::FieldTrial. |
13 // | 16 // |
14 // This includes a simple API used to handle getting and setting | 17 // This includes a simple API used to handle getting and setting |
15 // data related to Google-specific experiments in the browser. This is meant to | 18 // data related to Google-specific experiments in the browser. This is meant to |
16 // be an extension to the base::FieldTrial for Google-specific functionality. | 19 // be an extension to the base::FieldTrial for Google-specific functionality. |
17 // | 20 // |
18 // These calls are meant to be made directly after appending all your groups to | 21 // These calls are meant to be made directly after appending all your groups to |
19 // a FieldTrial (for associating IDs) and any time after the group selection has | 22 // a FieldTrial (for associating IDs) and any time after the group selection has |
20 // been done (for retrieving IDs). | 23 // been done (for retrieving IDs). |
21 // | 24 // |
22 // Typical usage looks like this: | 25 // Typical usage looks like this: |
23 // | 26 // |
24 // // Set up your trial and groups as usual. | 27 // // Set up your trial and groups as usual. |
25 // FieldTrial* trial = FieldTrialList::FactoryGetFieldTrial( | 28 // FieldTrial* trial = FieldTrialList::FactoryGetFieldTrial( |
26 // "trial", 1000, "default", 2012, 12, 31, NULL); | 29 // "trial", 1000, "default", 2012, 12, 31, NULL); |
27 // const int kHighMemGroup = trial->AppendGroup("HighMem", 20); | 30 // const int kHighMemGroup = trial->AppendGroup("HighMem", 20); |
28 // const int kLowMemGroup = trial->AppendGroup("LowMem", 20); | 31 // const int kLowMemGroup = trial->AppendGroup("LowMem", 20); |
29 // // All groups are now created. We want to associate GoogleExperimentIDs with | 32 // // All groups are now created. We want to associate GoogleExperimentIDs with |
30 // // them, so do that now. | 33 // // them, so do that now. |
31 // AssociateGoogleExperimentID( | 34 // AssociateGoogleExperimentID("trial", "default", 123); |
32 // FieldTrial::MakeNameGroupId("trial", "default"), 123); | 35 // AssociateGoogleExperimentID("trial", "HighMem", 456); |
33 // AssociateGoogleExperimentID( | 36 // AssociateGoogleExperimentID("trial", "LowMem", 789); |
34 // FieldTrial::MakeNameGroupId("trial", "HighMem"), 456); | |
35 // AssociateGoogleExperimentID( | |
36 // FieldTrial::MakeNameGroupId("trial", "LowMem"), 789); | |
37 // | 37 // |
38 // // Elsewhere, we are interested in retrieving the GoogleExperimentID | 38 // // Elsewhere, we are interested in retrieving the GoogleExperimentID |
39 // // assocaited with |trial|. | 39 // // assocaited with |trial|. |
40 // GoogleExperimentID id = GetGoogleExperimentID( | 40 // GoogleExperimentID id = GetGoogleExperimentID(trial->name(), |
41 // FieldTrial::MakeNameGroupId(trial->name(), trial->group_name())); | 41 // trial->group_name()); |
42 // // Do stuff with |id|... | 42 // // Do stuff with |id|... |
43 // | 43 // |
44 // The AssociateGoogleExperimentID and GetGoogleExperimentID API methods are | 44 // The AssociateGoogleExperimentID and GetGoogleExperimentID API methods are |
45 // thread safe. | 45 // thread safe. |
46 namespace experiments_helper { | 46 namespace experiments_helper { |
47 | 47 |
48 // An ID used by Google servers to identify a local browser experiment. | 48 // An ID used by Google servers to identify a local browser experiment. |
49 typedef uint32 GoogleExperimentID; | 49 typedef uint32 GoogleExperimentID; |
50 | 50 |
| 51 // The Unique ID of a trial and its selected group, where the name and group |
| 52 // identifiers are hashes of the trial and group name strings. |
| 53 struct SelectedGroupId { |
| 54 uint32 name; |
| 55 uint32 group; |
| 56 }; |
| 57 |
| 58 // We need to supply a Compare class for templates since SelectedGroupId is a |
| 59 // user-defined type. |
| 60 struct SelectedGroupIdCompare { |
| 61 bool operator() (const SelectedGroupId& lhs, |
| 62 const SelectedGroupId& rhs) const { |
| 63 // The group and name fields are just SHA-1 Hashes, so we just need to treat |
| 64 // them as IDs and do a less-than comparison. We test group first, since |
| 65 // name is more likely to collide. |
| 66 if (lhs.group != rhs.group) |
| 67 return lhs.group < rhs.group; |
| 68 return lhs.name < rhs.name; |
| 69 } |
| 70 }; |
| 71 |
51 // Used to represent no associated Google experiment ID. Calls to the | 72 // Used to represent no associated Google experiment ID. Calls to the |
52 // GetGoogleExperimentID API below will return this empty value for FieldTrial | 73 // GetGoogleExperimentID API below will return this empty value for FieldTrial |
53 // groups uninterested in associating themselves with Google experiments, or | 74 // groups uninterested in associating themselves with Google experiments, or |
54 // those that have not yet been seen yet. | 75 // those that have not yet been seen yet. |
55 extern const GoogleExperimentID kEmptyGoogleExperimentID; | 76 extern const GoogleExperimentID kEmptyGoogleExperimentID; |
56 | 77 |
57 // Set the GoogleExperimentID associated with a FieldTrial group. The group is | 78 // Fills the supplied vector |name_group_ids| (which must be empty when called) |
58 // denoted by |group_identifier|, which can be created by passing the | 79 // with unique SelectedGroupIds for each Field Trial that has a chosen group. |
59 // FieldTrial's trial and group names to base::FieldTrial::MakeNameGroupId. | 80 // Field Trials for which a group has not been chosen yet are NOT returned in |
60 // This does not need to be called for FieldTrials uninterested in Google | 81 // this list. |
61 // experiments. | 82 void GetFieldTrialSelectedGroupIds( |
62 void AssociateGoogleExperimentID( | 83 std::vector<SelectedGroupId>* name_group_ids); |
63 const base::FieldTrial::NameGroupId& group_identifier, | 84 |
64 GoogleExperimentID id); | 85 // Associate a GoogleExperimentID value with a FieldTrial group. The group is |
| 86 // denoted by |trial_name| and |group_name|. This must be called whenever you |
| 87 // prepare a FieldTrial (create the trial and append groups) that needs to have |
| 88 // a GoogleExperimentID associated with it so Google servers can recognize the |
| 89 // FieldTrial. |
| 90 void AssociateGoogleExperimentID(const std::string& trial_name, |
| 91 const std::string& group_name, |
| 92 GoogleExperimentID id); |
65 | 93 |
66 // Retrieve the GoogleExperimentID associated with a FieldTrial group. The group | 94 // Retrieve the GoogleExperimentID associated with a FieldTrial group. The group |
67 // is denoted by |group_identifier| (see comment above). This can be nicely | 95 // is denoted by |trial_name| and |group_name|. This can be nicely combined with |
68 // combined with FieldTrial::GetFieldTrialNameGroupIds to enumerate the | 96 // FieldTrial::GetFieldTrialSelectedGroupIds to enumerate the |
69 // GoogleExperimentIDs for all active FieldTrial groups. | 97 // GoogleExperimentIDs for all active FieldTrial groups. |
70 GoogleExperimentID GetGoogleExperimentID( | 98 GoogleExperimentID GetGoogleExperimentID(const std::string& trial_name, |
71 const base::FieldTrial::NameGroupId& group_identifier); | 99 const std::string& group_name); |
72 | 100 |
73 // Get the current set of chosen FieldTrial groups (aka experiments) and send | 101 // Get the current set of chosen FieldTrial groups (aka experiments) and send |
74 // them to the child process logging module so it can save it for crash dumps. | 102 // them to the child process logging module so it can save it for crash dumps. |
75 void SetChildProcessLoggingExperimentList(); | 103 void SetChildProcessLoggingExperimentList(); |
76 | 104 |
77 } // namespace experiments_helper | 105 } // namespace experiments_helper |
78 | 106 |
| 107 // Expose some functions for testing. These functions just wrap functionality |
| 108 // that is implemented above. |
| 109 namespace testing { |
| 110 |
| 111 void TestGetFieldTrialSelectedGroupIdsForSelectedGroups( |
| 112 const base::FieldTrial::SelectedGroups& selected_groups, |
| 113 std::vector<experiments_helper::SelectedGroupId>* name_group_ids); |
| 114 |
| 115 uint32 TestHashName(const std::string& name); |
| 116 |
| 117 } |
| 118 |
79 #endif // CHROME_COMMON_METRICS_EXPERIMENTS_HELPER_H_ | 119 #endif // CHROME_COMMON_METRICS_EXPERIMENTS_HELPER_H_ |
OLD | NEW |