[email protected] | cffb200 | 2014-05-22 03:58:39 | [diff] [blame] | 1 | // Copyright 2014 The Chromium Authors. All rights reserved. |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | cffb200 | 2014-05-22 03:58:39 | [diff] [blame] | 5 | #include "chrome/common/variations/experiment_labels.h" |
| 6 | |
| 7 | #include <vector> |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 8 | |
| 9 | #include "base/logging.h" |
| 10 | #include "base/strings/string_number_conversions.h" |
| 11 | #include "base/strings/string_split.h" |
| 12 | #include "base/strings/string_util.h" |
[email protected] | d383ffc | 2013-12-06 15:27:28 | [diff] [blame] | 13 | #include "base/strings/utf_string_conversions.h" |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 14 | #include "chrome/installer/util/google_update_experiment_util.h" |
| 15 | #include "components/variations/variations_associated_data.h" |
| 16 | |
| 17 | namespace chrome_variations { |
| 18 | |
| 19 | namespace { |
| 20 | |
[email protected] | d383ffc | 2013-12-06 15:27:28 | [diff] [blame] | 21 | const char kVariationPrefix[] = "CrVar"; |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 22 | |
| 23 | // This method builds a single experiment label for a Chrome Variation, |
| 24 | // including a timestamp that is a year in the future from |current_time|. Since |
| 25 | // multiple headers can be transmitted, |count| is a number that is appended |
| 26 | // after the label key to differentiate the labels. |
[email protected] | 59b6f67 | 2014-07-26 18:35:47 | [diff] [blame] | 27 | base::string16 CreateSingleExperimentLabel(int count, |
| 28 | variations::VariationID id, |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 29 | const base::Time& current_time) { |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 30 | // Build the parts separately so they can be validated. |
[email protected] | d383ffc | 2013-12-06 15:27:28 | [diff] [blame] | 31 | const base::string16 key = |
[email protected] | 036a5f3 | 2013-12-25 00:26:11 | [diff] [blame] | 32 | base::ASCIIToUTF16(kVariationPrefix) + base::IntToString16(count); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 33 | DCHECK_LE(key.size(), 8U); |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 34 | const base::string16 value = base::IntToString16(id); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 35 | DCHECK_LE(value.size(), 8U); |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 36 | base::string16 label(key); |
[email protected] | 036a5f3 | 2013-12-25 00:26:11 | [diff] [blame] | 37 | label += base::ASCIIToUTF16("="); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 38 | label += value; |
[email protected] | 036a5f3 | 2013-12-25 00:26:11 | [diff] [blame] | 39 | label += base::ASCIIToUTF16("|"); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 40 | label += installer::BuildExperimentDateString(current_time); |
| 41 | return label; |
| 42 | } |
| 43 | |
| 44 | } // namespace |
| 45 | |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 46 | base::string16 BuildGoogleUpdateExperimentLabel( |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 47 | const base::FieldTrial::ActiveGroups& active_groups) { |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 48 | base::string16 experiment_labels; |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 49 | int counter = 0; |
| 50 | |
| 51 | const base::Time current_time(base::Time::Now()); |
| 52 | |
| 53 | // Find all currently active VariationIDs associated with Google Update. |
| 54 | for (base::FieldTrial::ActiveGroups::const_iterator it = |
| 55 | active_groups.begin(); it != active_groups.end(); ++it) { |
[email protected] | 59b6f67 | 2014-07-26 18:35:47 | [diff] [blame] | 56 | const variations::VariationID id = |
| 57 | variations::GetGoogleVariationID(variations::GOOGLE_UPDATE_SERVICE, |
| 58 | it->trial_name, it->group_name); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 59 | |
[email protected] | 59b6f67 | 2014-07-26 18:35:47 | [diff] [blame] | 60 | if (id == variations::EMPTY_ID) |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 61 | continue; |
| 62 | |
[email protected] | 056a1a4 | 2014-05-23 22:46:48 | [diff] [blame] | 63 | if (!experiment_labels.empty()) |
| 64 | experiment_labels += google_update::kExperimentLabelSeparator; |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 65 | experiment_labels += CreateSingleExperimentLabel(++counter, id, |
| 66 | current_time); |
| 67 | } |
| 68 | |
| 69 | return experiment_labels; |
| 70 | } |
| 71 | |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 72 | base::string16 ExtractNonVariationLabels(const base::string16& labels) { |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 73 | // First, split everything by the label separator. |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 74 | std::vector<base::string16> entries; |
[email protected] | 056a1a4 | 2014-05-23 22:46:48 | [diff] [blame] | 75 | base::SplitString(labels, google_update::kExperimentLabelSeparator, &entries); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 76 | |
| 77 | // For each label, keep the ones that do not look like a Variations label. |
[email protected] | 056a1a4 | 2014-05-23 22:46:48 | [diff] [blame] | 78 | base::string16 non_variation_labels; |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 79 | for (std::vector<base::string16>::const_iterator it = entries.begin(); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 80 | it != entries.end(); ++it) { |
[email protected] | 036a5f3 | 2013-12-25 00:26:11 | [diff] [blame] | 81 | if (it->empty() || |
brettw | 44ce0ec5 | 2015-06-12 01:57:57 | [diff] [blame] | 82 | base::StartsWith(*it, base::ASCIIToUTF16(kVariationPrefix), false)) { |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 83 | continue; |
[email protected] | 036a5f3 | 2013-12-25 00:26:11 | [diff] [blame] | 84 | } |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 85 | |
| 86 | // Dump the whole thing, including the timestamp. |
| 87 | if (!non_variation_labels.empty()) |
[email protected] | 056a1a4 | 2014-05-23 22:46:48 | [diff] [blame] | 88 | non_variation_labels += google_update::kExperimentLabelSeparator; |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 89 | non_variation_labels += *it; |
| 90 | } |
| 91 | |
| 92 | return non_variation_labels; |
| 93 | } |
| 94 | |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 95 | base::string16 CombineExperimentLabels(const base::string16& variation_labels, |
| 96 | const base::string16& other_labels) { |
[email protected] | 056a1a4 | 2014-05-23 22:46:48 | [diff] [blame] | 97 | const base::string16 separator(1, google_update::kExperimentLabelSeparator); |
brettw | 44ce0ec5 | 2015-06-12 01:57:57 | [diff] [blame] | 98 | DCHECK(!base::StartsWith(variation_labels, separator, false)); |
brettw | 17b32ad | 2015-06-12 23:46:41 | [diff] [blame] | 99 | DCHECK(!base::EndsWith(variation_labels, separator, false)); |
brettw | 44ce0ec5 | 2015-06-12 01:57:57 | [diff] [blame] | 100 | DCHECK(!base::StartsWith(other_labels, separator, false)); |
brettw | 17b32ad | 2015-06-12 23:46:41 | [diff] [blame] | 101 | DCHECK(!base::EndsWith(other_labels, separator, false)); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 102 | // Note that if either label is empty, a separator is not necessary. |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 103 | base::string16 combined_labels = other_labels; |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 104 | if (!other_labels.empty() && !variation_labels.empty()) |
[email protected] | 056a1a4 | 2014-05-23 22:46:48 | [diff] [blame] | 105 | combined_labels += google_update::kExperimentLabelSeparator; |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 106 | combined_labels += variation_labels; |
| 107 | return combined_labels; |
| 108 | } |
| 109 | |
| 110 | } // namespace chrome_variations |