[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. |
brettw | 94a2cc2 | 2015-07-01 19:26:54 | [diff] [blame^] | 74 | std::vector<base::StringPiece16> entries = base::SplitStringPiece( |
| 75 | labels, base::StringPiece16(&google_update::kExperimentLabelSeparator, 1), |
| 76 | base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 77 | |
| 78 | // 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] | 79 | base::string16 non_variation_labels; |
brettw | 94a2cc2 | 2015-07-01 19:26:54 | [diff] [blame^] | 80 | for (const base::StringPiece16& entry : entries) { |
| 81 | if (entry.empty() || |
| 82 | base::StartsWith(entry, |
| 83 | base::ASCIIToUTF16(kVariationPrefix), |
| 84 | base::CompareCase::INSENSITIVE_ASCII)) { |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 85 | continue; |
[email protected] | 036a5f3 | 2013-12-25 00:26:11 | [diff] [blame] | 86 | } |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 87 | |
| 88 | // Dump the whole thing, including the timestamp. |
| 89 | if (!non_variation_labels.empty()) |
[email protected] | 056a1a4 | 2014-05-23 22:46:48 | [diff] [blame] | 90 | non_variation_labels += google_update::kExperimentLabelSeparator; |
brettw | 94a2cc2 | 2015-07-01 19:26:54 | [diff] [blame^] | 91 | entry.AppendToString(&non_variation_labels); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 92 | } |
| 93 | |
| 94 | return non_variation_labels; |
| 95 | } |
| 96 | |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 97 | base::string16 CombineExperimentLabels(const base::string16& variation_labels, |
| 98 | const base::string16& other_labels) { |
brettw | 94a2cc2 | 2015-07-01 19:26:54 | [diff] [blame^] | 99 | base::StringPiece16 separator(&google_update::kExperimentLabelSeparator, 1); |
| 100 | DCHECK(!base::StartsWith(variation_labels, separator, |
| 101 | base::CompareCase::SENSITIVE)); |
| 102 | DCHECK(!base::EndsWith(variation_labels, separator, |
| 103 | base::CompareCase::SENSITIVE)); |
| 104 | DCHECK(!base::StartsWith(other_labels, separator, |
| 105 | base::CompareCase::SENSITIVE)); |
| 106 | DCHECK(!base::EndsWith(other_labels, separator, |
| 107 | base::CompareCase::SENSITIVE)); |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 108 | // Note that if either label is empty, a separator is not necessary. |
[email protected] | 428fac1 | 2013-12-05 21:38:49 | [diff] [blame] | 109 | base::string16 combined_labels = other_labels; |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 110 | if (!other_labels.empty() && !variation_labels.empty()) |
[email protected] | 056a1a4 | 2014-05-23 22:46:48 | [diff] [blame] | 111 | combined_labels += google_update::kExperimentLabelSeparator; |
[email protected] | 2134467 | 2013-11-07 06:04:28 | [diff] [blame] | 112 | combined_labels += variation_labels; |
| 113 | return combined_labels; |
| 114 | } |
| 115 | |
| 116 | } // namespace chrome_variations |