blob: ad230f569beb0af8bc8b20676ebae2bee3616174 [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.
[email protected]428fac12013-12-05 21:38:4974 std::vector<base::string16> entries;
[email protected]056a1a42014-05-23 22:46:4875 base::SplitString(labels, google_update::kExperimentLabelSeparator, &entries);
[email protected]21344672013-11-07 06:04:2876
77 // For each label, keep the ones that do not look like a Variations label.
[email protected]056a1a42014-05-23 22:46:4878 base::string16 non_variation_labels;
[email protected]428fac12013-12-05 21:38:4979 for (std::vector<base::string16>::const_iterator it = entries.begin();
[email protected]21344672013-11-07 06:04:2880 it != entries.end(); ++it) {
[email protected]036a5f32013-12-25 00:26:1181 if (it->empty() ||
brettw44ce0ec52015-06-12 01:57:5782 base::StartsWith(*it, base::ASCIIToUTF16(kVariationPrefix), false)) {
[email protected]21344672013-11-07 06:04:2883 continue;
[email protected]036a5f32013-12-25 00:26:1184 }
[email protected]21344672013-11-07 06:04:2885
86 // Dump the whole thing, including the timestamp.
87 if (!non_variation_labels.empty())
[email protected]056a1a42014-05-23 22:46:4888 non_variation_labels += google_update::kExperimentLabelSeparator;
[email protected]21344672013-11-07 06:04:2889 non_variation_labels += *it;
90 }
91
92 return non_variation_labels;
93}
94
[email protected]428fac12013-12-05 21:38:4995base::string16 CombineExperimentLabels(const base::string16& variation_labels,
96 const base::string16& other_labels) {
[email protected]056a1a42014-05-23 22:46:4897 const base::string16 separator(1, google_update::kExperimentLabelSeparator);
brettw44ce0ec52015-06-12 01:57:5798 DCHECK(!base::StartsWith(variation_labels, separator, false));
brettw17b32ad2015-06-12 23:46:4199 DCHECK(!base::EndsWith(variation_labels, separator, false));
brettw44ce0ec52015-06-12 01:57:57100 DCHECK(!base::StartsWith(other_labels, separator, false));
brettw17b32ad2015-06-12 23:46:41101 DCHECK(!base::EndsWith(other_labels, separator, false));
[email protected]21344672013-11-07 06:04:28102 // Note that if either label is empty, a separator is not necessary.
[email protected]428fac12013-12-05 21:38:49103 base::string16 combined_labels = other_labels;
[email protected]21344672013-11-07 06:04:28104 if (!other_labels.empty() && !variation_labels.empty())
[email protected]056a1a42014-05-23 22:46:48105 combined_labels += google_update::kExperimentLabelSeparator;
[email protected]21344672013-11-07 06:04:28106 combined_labels += variation_labels;
107 return combined_labels;
108}
109
110} // namespace chrome_variations