blob: 8ed156beb0c8c05a57c7cc3529688e53156ece6e [file] [log] [blame]
[email protected]cffb2002014-05-22 03:58:391// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]21344672013-11-07 06:04:282// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]cffb2002014-05-22 03:58:395#include "chrome/common/variations/experiment_labels.h"
6
7#include <vector>
[email protected]21344672013-11-07 06:04:288
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]d383ffc2013-12-06 15:27:2813#include "base/strings/utf_string_conversions.h"
[email protected]21344672013-11-07 06:04:2814#include "chrome/installer/util/google_update_experiment_util.h"
15#include "components/variations/variations_associated_data.h"
16
17namespace chrome_variations {
18
19namespace {
20
[email protected]d383ffc2013-12-06 15:27:2821const char kVariationPrefix[] = "CrVar";
[email protected]21344672013-11-07 06:04:2822
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]59b6f672014-07-26 18:35:4727base::string16 CreateSingleExperimentLabel(int count,
28 variations::VariationID id,
[email protected]428fac12013-12-05 21:38:4929 const base::Time& current_time) {
[email protected]21344672013-11-07 06:04:2830 // Build the parts separately so they can be validated.
[email protected]d383ffc2013-12-06 15:27:2831 const base::string16 key =
[email protected]036a5f32013-12-25 00:26:1132 base::ASCIIToUTF16(kVariationPrefix) + base::IntToString16(count);
[email protected]21344672013-11-07 06:04:2833 DCHECK_LE(key.size(), 8U);
[email protected]428fac12013-12-05 21:38:4934 const base::string16 value = base::IntToString16(id);
[email protected]21344672013-11-07 06:04:2835 DCHECK_LE(value.size(), 8U);
[email protected]428fac12013-12-05 21:38:4936 base::string16 label(key);
[email protected]036a5f32013-12-25 00:26:1137 label += base::ASCIIToUTF16("=");
[email protected]21344672013-11-07 06:04:2838 label += value;
[email protected]036a5f32013-12-25 00:26:1139 label += base::ASCIIToUTF16("|");
[email protected]21344672013-11-07 06:04:2840 label += installer::BuildExperimentDateString(current_time);
41 return label;
42}
43
44} // namespace
45
[email protected]428fac12013-12-05 21:38:4946base::string16 BuildGoogleUpdateExperimentLabel(
[email protected]21344672013-11-07 06:04:2847 const base::FieldTrial::ActiveGroups& active_groups) {
[email protected]428fac12013-12-05 21:38:4948 base::string16 experiment_labels;
[email protected]21344672013-11-07 06:04:2849 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]59b6f672014-07-26 18:35:4756 const variations::VariationID id =
57 variations::GetGoogleVariationID(variations::GOOGLE_UPDATE_SERVICE,
58 it->trial_name, it->group_name);
[email protected]21344672013-11-07 06:04:2859
[email protected]59b6f672014-07-26 18:35:4760 if (id == variations::EMPTY_ID)
[email protected]21344672013-11-07 06:04:2861 continue;
62
[email protected]056a1a42014-05-23 22:46:4863 if (!experiment_labels.empty())
64 experiment_labels += google_update::kExperimentLabelSeparator;
[email protected]21344672013-11-07 06:04:2865 experiment_labels += CreateSingleExperimentLabel(++counter, id,
66 current_time);
67 }
68
69 return experiment_labels;
70}
71
[email protected]428fac12013-12-05 21:38:4972base::string16 ExtractNonVariationLabels(const base::string16& labels) {
[email protected]21344672013-11-07 06:04:2873 // First, split everything by the label separator.
brettw94a2cc22015-07-01 19:26:5474 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]21344672013-11-07 06:04:2877
78 // For each label, keep the ones that do not look like a Variations label.
[email protected]056a1a42014-05-23 22:46:4879 base::string16 non_variation_labels;
brettw94a2cc22015-07-01 19:26:5480 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]21344672013-11-07 06:04:2885 continue;
[email protected]036a5f32013-12-25 00:26:1186 }
[email protected]21344672013-11-07 06:04:2887
88 // Dump the whole thing, including the timestamp.
89 if (!non_variation_labels.empty())
[email protected]056a1a42014-05-23 22:46:4890 non_variation_labels += google_update::kExperimentLabelSeparator;
brettw94a2cc22015-07-01 19:26:5491 entry.AppendToString(&non_variation_labels);
[email protected]21344672013-11-07 06:04:2892 }
93
94 return non_variation_labels;
95}
96
[email protected]428fac12013-12-05 21:38:4997base::string16 CombineExperimentLabels(const base::string16& variation_labels,
98 const base::string16& other_labels) {
brettw94a2cc22015-07-01 19:26:5499 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]21344672013-11-07 06:04:28108 // Note that if either label is empty, a separator is not necessary.
[email protected]428fac12013-12-05 21:38:49109 base::string16 combined_labels = other_labels;
[email protected]21344672013-11-07 06:04:28110 if (!other_labels.empty() && !variation_labels.empty())
[email protected]056a1a42014-05-23 22:46:48111 combined_labels += google_update::kExperimentLabelSeparator;
[email protected]21344672013-11-07 06:04:28112 combined_labels += variation_labels;
113 return combined_labels;
114}
115
116} // namespace chrome_variations