gcapi_omaha_experiment.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright (c) 2012 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/installer/gcapi/gcapi_omaha_experiment.h" 6 7#include "base/basictypes.h" 8#include "base/strings/string_split.h" 9#include "base/strings/string_util.h" 10#include "base/strings/stringprintf.h" 11#include "base/strings/utf_string_conversions.h" 12#include "base/time/time.h" 13#include "chrome/installer/gcapi/gcapi.h" 14#include "chrome/installer/util/google_update_constants.h" 15#include "chrome/installer/util/google_update_experiment_util.h" 16#include "chrome/installer/util/google_update_settings.h" 17 18namespace { 19 20// Returns the number of weeks since 2/3/2003. 21int GetCurrentRlzWeek(const base::Time& current_time) { 22 base::Time::Exploded february_third_2003_exploded = 23 {2003, 2, 1, 3, 0, 0, 0, 0}; 24 base::Time f = base::Time::FromUTCExploded(february_third_2003_exploded); 25 base::TimeDelta delta = current_time - f; 26 return delta.InDays() / 7; 27} 28 29bool SetExperimentLabel(const wchar_t* brand_code, 30 const string16& label, 31 int shell_mode) { 32 if (!brand_code) { 33 return false; 34 } 35 36 const bool system_level = shell_mode == GCAPI_INVOKED_UAC_ELEVATION; 37 38 string16 original_labels; 39 if (!GoogleUpdateSettings::ReadExperimentLabels(system_level, 40 &original_labels)) { 41 return false; 42 } 43 44 // Split the original labels by the label separator. 45 std::vector<string16> entries; 46 base::SplitStringUsingSubstr( 47 original_labels, 48 ASCIIToUTF16(google_update::kExperimentLabelSep), 49 &entries); 50 51 // Keep all labels, but the one we want to add/replace. 52 string16 new_labels; 53 for (std::vector<string16>::const_iterator it = entries.begin(); 54 it != entries.end(); ++it) { 55 if (!it->empty() && !StartsWith(*it, label + L"=", true)) { 56 new_labels += *it; 57 new_labels += ASCIIToUTF16(google_update::kExperimentLabelSep); 58 } 59 } 60 61 new_labels.append( 62 gcapi_internals::GetGCAPIExperimentLabel(brand_code, label)); 63 64 return GoogleUpdateSettings::SetExperimentLabels(system_level, 65 new_labels); 66} 67 68} // namespace 69 70namespace gcapi_internals { 71 72const wchar_t kReactivationLabel[] = L"reacbrand"; 73const wchar_t kRelaunchLabel[] = L"relaunchbrand"; 74 75string16 GetGCAPIExperimentLabel(const wchar_t* brand_code, 76 const string16& label) { 77 // Keeps a fixed time state for this GCAPI instance; this makes tests reliable 78 // when crossing time boundaries on the system clock and doesn't otherwise 79 // affect results of this short lived binary. 80 static time_t instance_time_value = 0; 81 if (instance_time_value == 0) 82 instance_time_value = base::Time::Now().ToTimeT(); 83 84 base::Time instance_time = base::Time::FromTimeT(instance_time_value); 85 86 string16 gcapi_experiment_label; 87 base::SStringPrintf(&gcapi_experiment_label, 88 L"%ls=%ls_%d|%ls", 89 label.c_str(), 90 brand_code, 91 GetCurrentRlzWeek(instance_time), 92 installer::BuildExperimentDateString( 93 instance_time).c_str()); 94 return gcapi_experiment_label; 95} 96 97} // namespace gcapi_internals 98 99bool SetReactivationExperimentLabels(const wchar_t* brand_code, 100 int shell_mode) { 101 return SetExperimentLabel(brand_code, gcapi_internals::kReactivationLabel, 102 shell_mode); 103} 104 105bool SetRelaunchExperimentLabels(const wchar_t* brand_code, int shell_mode) { 106 return SetExperimentLabel(brand_code, gcapi_internals::kRelaunchLabel, 107 shell_mode); 108} 109