Chromium Code Reviews| Index: chrome/installer/gcapi/gcapi_omaha_experiment.cc |
| diff --git a/chrome/installer/gcapi/gcapi_omaha_experiment.cc b/chrome/installer/gcapi/gcapi_omaha_experiment.cc |
| index ac5899fe675e27fa09c8a2b557ae75fa38633b6a..bdac9623061d1ec4597c44a56921a4a6d78900af 100644 |
| --- a/chrome/installer/gcapi/gcapi_omaha_experiment.cc |
| +++ b/chrome/installer/gcapi/gcapi_omaha_experiment.cc |
| @@ -4,10 +4,12 @@ |
| #include "chrome/installer/gcapi/gcapi_omaha_experiment.h" |
| -#include "base/strings/string16.h" |
| +#include "base/basictypes.h" |
| +#include "base/lazy_instance.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/time/time.h" |
| #include "chrome/installer/gcapi/gcapi.h" |
| +#include "chrome/installer/util/google_update_constants.h" |
| #include "chrome/installer/util/google_update_experiment_util.h" |
| #include "chrome/installer/util/google_update_settings.h" |
| @@ -24,35 +26,104 @@ int GetCurrentRlzWeek() { |
| return delta.InDays() / 7; |
| } |
| -bool SetLabel(const wchar_t* brand_code, const wchar_t* label, int shell_mode) { |
| +bool SetExperimentLabel(const wchar_t* brand_code, |
| + const string16& label, |
| + int shell_mode) { |
| if (!brand_code) { |
| return false; |
| } |
| - int week_number = GetCurrentRlzWeek(); |
| - if (week_number < 0 || week_number > 999) |
| - week_number = 999; |
| + const bool system_level = shell_mode == GCAPI_INVOKED_UAC_ELEVATION; |
| string16 experiment_labels; |
| - base::SStringPrintf(&experiment_labels, |
| - L"%ls=%ls_%d|%ls", |
| - label, |
| - brand_code, |
| - week_number, |
| - installer::BuildExperimentDateString().c_str()); |
| + if (!GoogleUpdateSettings::ReadExperimentLabels(system_level, |
| + &experiment_labels)) { |
| + return false; |
| + } |
| - return GoogleUpdateSettings::SetExperimentLabels( |
| - shell_mode == GCAPI_INVOKED_UAC_ELEVATION, |
| - experiment_labels); |
| + // First erase this label from the existing experiment labels if it exists. |
|
Alexei Svitkine (slow)
2013/09/03 15:46:35
I think this logic is now sufficiently complicated
gab
2013/11/05 22:20:38
Done.
|
| + size_t existing_label_begin = experiment_labels.find(label + L"="); |
| + while (existing_label_begin != string16::npos && |
| + existing_label_begin != 0 && |
| + experiment_labels.at( |
| + existing_label_begin - 1) != *google_update::kExperimentLabelSep) { |
| + // Make sure |existing_label_begin|, if found, is either at the beginning of |
| + // |experiment_labels| or right after the separator. |
| + existing_label_begin = experiment_labels.find(label + L"=", |
| + existing_label_begin + 1); |
| + } |
| + if (existing_label_begin != string16::npos) { |
| + size_t existing_label_end = |
| + experiment_labels.find(google_update::kExperimentLabelSep, |
| + existing_label_begin); |
| + // Note: if |existing_label_end == string16::npos| this will work anyways |
| + // as npos is defined as the biggest possible unsigned integer and erase |
| + // will thus, by definition, erase to the end of the string. |
| + experiment_labels.erase(existing_label_begin, |
| + existing_label_end - existing_label_begin + 1); |
| + } |
| + |
| + // Then append the GCAPI experiment label to the |experiment_labels|. |
| + if (!experiment_labels.empty()) |
| + experiment_labels.append(google_update::kExperimentLabelSep); |
| + experiment_labels.append( |
| + gcapi_internals::GetGCAPIExperimentLabel(brand_code, label)); |
| + |
| + return GoogleUpdateSettings::SetExperimentLabels(system_level, |
| + experiment_labels); |
| } |
| } // namespace |
| +namespace gcapi_internals { |
| + |
| +const wchar_t kReactivationLabel[] = L"reacbrand"; |
| +const wchar_t kRelaunchLabel[] = L"relaunchbrand"; |
| + |
| +// Keeps a fixed state for time dependent constants for the life of this |
| +// GCAPI instance; this makes tests realiable when crossing time boundaries on |
|
Alexei Svitkine (slow)
2013/09/03 15:46:35
Nit: reliable
gab
2013/11/05 22:20:38
"real" "liable" is nice, no?! :)
|
| +// the system clock. |
| +struct GCAPILabelState { |
| + GCAPILabelState() |
| + : week_number(GetCurrentRlzWeek()), |
| + experiment_date_string(installer::BuildExperimentDateString()) { |
| + if (week_number < 0 || week_number > 999) |
| + week_number = 999; |
| + } |
| + |
| + int week_number; |
| + string16 experiment_date_string; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(GCAPILabelState); |
| +}; |
| + |
| +base::LazyInstance<GCAPILabelState> g_gcapi_label_state = |
| + LAZY_INSTANCE_INITIALIZER; |
| + |
| +string16 GetGCAPIExperimentLabel(const wchar_t* brand_code, |
| + const string16& label) { |
| + const GCAPILabelState& gcapi_label_state = g_gcapi_label_state.Get(); |
|
Alexei Svitkine (slow)
2013/09/03 15:46:35
Instead of having this GCAPILabelState state in la
gab
2013/11/05 22:20:38
Done.
|
| + |
| + string16 gcapi_experiment_label; |
| + base::SStringPrintf(&gcapi_experiment_label, |
| + L"%ls=%ls_%d|%ls", |
| + label.c_str(), |
| + brand_code, |
| + gcapi_label_state.week_number, |
| + gcapi_label_state.experiment_date_string.c_str()); |
| + return gcapi_experiment_label; |
| +} |
| + |
| +} // namespace gcapi_internals |
| + |
| bool SetReactivationExperimentLabels(const wchar_t* brand_code, |
| int shell_mode) { |
| - return SetLabel(brand_code, L"reacbrand", shell_mode); |
| + return SetExperimentLabel(brand_code, gcapi_internals::kReactivationLabel, |
| + shell_mode); |
| } |
| bool SetRelaunchExperimentLabels(const wchar_t* brand_code, int shell_mode) { |
| - return SetLabel(brand_code, L"relaunchbrand", shell_mode); |
| + return SetExperimentLabel(brand_code, gcapi_internals::kRelaunchLabel, |
| + shell_mode); |
| } |