blob: 07d339175d396fa1a586e1501791981554f0cb23 [file] [log] [blame]
[email protected]21344672013-11-07 06:04:281// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/common/metrics/variations/experiment_labels_win.h"
6
7#include "base/logging.h"
8#include "base/strings/string_number_conversions.h"
9#include "base/strings/string_split.h"
10#include "base/strings/string_util.h"
11#include "chrome/installer/util/google_update_constants.h"
12#include "chrome/installer/util/google_update_experiment_util.h"
13#include "components/variations/variations_associated_data.h"
14
15namespace chrome_variations {
16
17namespace {
18
19const wchar_t kVariationPrefix[] = L"CrVar";
20
21// This method builds a single experiment label for a Chrome Variation,
22// including a timestamp that is a year in the future from |current_time|. Since
23// multiple headers can be transmitted, |count| is a number that is appended
24// after the label key to differentiate the labels.
[email protected]428fac12013-12-05 21:38:4925base::string16 CreateSingleExperimentLabel(int count, VariationID id,
26 const base::Time& current_time) {
[email protected]21344672013-11-07 06:04:2827 // Build the parts separately so they can be validated.
[email protected]428fac12013-12-05 21:38:4928 const base::string16 key = kVariationPrefix + base::IntToString16(count);
[email protected]21344672013-11-07 06:04:2829 DCHECK_LE(key.size(), 8U);
[email protected]428fac12013-12-05 21:38:4930 const base::string16 value = base::IntToString16(id);
[email protected]21344672013-11-07 06:04:2831 DCHECK_LE(value.size(), 8U);
[email protected]428fac12013-12-05 21:38:4932 base::string16 label(key);
[email protected]21344672013-11-07 06:04:2833 label += L'=';
34 label += value;
35 label += L'|';
36 label += installer::BuildExperimentDateString(current_time);
37 return label;
38}
39
40} // namespace
41
[email protected]428fac12013-12-05 21:38:4942base::string16 BuildGoogleUpdateExperimentLabel(
[email protected]21344672013-11-07 06:04:2843 const base::FieldTrial::ActiveGroups& active_groups) {
[email protected]428fac12013-12-05 21:38:4944 base::string16 experiment_labels;
[email protected]21344672013-11-07 06:04:2845 int counter = 0;
46
47 const base::Time current_time(base::Time::Now());
48
49 // Find all currently active VariationIDs associated with Google Update.
50 for (base::FieldTrial::ActiveGroups::const_iterator it =
51 active_groups.begin(); it != active_groups.end(); ++it) {
52 const VariationID id = GetGoogleVariationID(GOOGLE_UPDATE_SERVICE,
53 it->trial_name, it->group_name);
54
55 if (id == EMPTY_ID)
56 continue;
57
58 if (!experiment_labels.empty())
59 experiment_labels += google_update::kExperimentLabelSep;
60 experiment_labels += CreateSingleExperimentLabel(++counter, id,
61 current_time);
62 }
63
64 return experiment_labels;
65}
66
[email protected]428fac12013-12-05 21:38:4967base::string16 ExtractNonVariationLabels(const base::string16& labels) {
68 base::string16 non_variation_labels;
[email protected]21344672013-11-07 06:04:2869
70 // First, split everything by the label separator.
[email protected]428fac12013-12-05 21:38:4971 std::vector<base::string16> entries;
[email protected]21344672013-11-07 06:04:2872 base::SplitStringUsingSubstr(labels, google_update::kExperimentLabelSep,
73 &entries);
74
75 // For each label, keep the ones that do not look like a Variations label.
[email protected]428fac12013-12-05 21:38:4976 for (std::vector<base::string16>::const_iterator it = entries.begin();
[email protected]21344672013-11-07 06:04:2877 it != entries.end(); ++it) {
78 if (it->empty() || StartsWith(*it, kVariationPrefix, false))
79 continue;
80
81 // Dump the whole thing, including the timestamp.
82 if (!non_variation_labels.empty())
83 non_variation_labels += google_update::kExperimentLabelSep;
84 non_variation_labels += *it;
85 }
86
87 return non_variation_labels;
88}
89
[email protected]428fac12013-12-05 21:38:4990base::string16 CombineExperimentLabels(const base::string16& variation_labels,
91 const base::string16& other_labels) {
[email protected]21344672013-11-07 06:04:2892 DCHECK(!StartsWith(variation_labels, google_update::kExperimentLabelSep,
93 false));
94 DCHECK(!EndsWith(variation_labels, google_update::kExperimentLabelSep,
95 false));
96 DCHECK(!StartsWith(other_labels, google_update::kExperimentLabelSep, false));
97 DCHECK(!EndsWith(other_labels, google_update::kExperimentLabelSep, false));
98 // Note that if either label is empty, a separator is not necessary.
[email protected]428fac12013-12-05 21:38:4999 base::string16 combined_labels = other_labels;
[email protected]21344672013-11-07 06:04:28100 if (!other_labels.empty() && !variation_labels.empty())
101 combined_labels += google_update::kExperimentLabelSep;
102 combined_labels += variation_labels;
103 return combined_labels;
104}
105
106} // namespace chrome_variations