15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/gcapi/gcapi_omaha_experiment.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/basictypes.h" 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/string_split.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/string_util.h" 107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/stringprintf.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/gcapi/gcapi.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/installer/util/google_update_constants.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/installer/util/google_update_experiment_util.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/installer/util/google_update_settings.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the number of weeks since 2/3/2003. 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int GetCurrentRlzWeek(const base::Time& current_time) { 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Time::Exploded february_third_2003_exploded = 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) {2003, 2, 1, 3, 0, 0, 0, 0}; 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Time f = base::Time::FromUTCExploded(february_third_2003_exploded); 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta delta = current_time - f; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return delta.InDays() / 7; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SetExperimentLabel(const wchar_t* brand_code, 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& label, 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int shell_mode) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!brand_code) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const bool system_level = shell_mode == GCAPI_INVOKED_UAC_ELEVATION; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 original_labels; 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!GoogleUpdateSettings::ReadExperimentLabels(system_level, 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &original_labels)) { 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Split the original labels by the label separator. 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<base::string16> entries; 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::SplitString(original_labels, google_update::kExperimentLabelSeparator, 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &entries); 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Keep all labels, but the one we want to add/replace. 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 new_labels; 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::vector<base::string16>::const_iterator it = entries.begin(); 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != entries.end(); ++it) { 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!it->empty() && !StartsWith(*it, label + L"=", true)) { 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_labels += *it; 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new_labels += google_update::kExperimentLabelSeparator; 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_labels.append( 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gcapi_internals::GetGCAPIExperimentLabel(brand_code, label)); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return GoogleUpdateSettings::SetExperimentLabels(system_level, 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_labels); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace gcapi_internals { 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const wchar_t kReactivationLabel[] = L"reacbrand"; 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const wchar_t kRelaunchLabel[] = L"relaunchbrand"; 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 GetGCAPIExperimentLabel(const wchar_t* brand_code, 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& label) { 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Keeps a fixed time state for this GCAPI instance; this makes tests reliable 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // when crossing time boundaries on the system clock and doesn't otherwise 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // affect results of this short lived binary. 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static time_t instance_time_value = 0; 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (instance_time_value == 0) 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) instance_time_value = base::Time::Now().ToTimeT(); 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Time instance_time = base::Time::FromTimeT(instance_time_value); 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 gcapi_experiment_label; 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::SStringPrintf(&gcapi_experiment_label, 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) L"%ls=%ls_%d|%ls", 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) label.c_str(), 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) brand_code, 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetCurrentRlzWeek(instance_time), 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) installer::BuildExperimentDateString( 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) instance_time).c_str()); 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return gcapi_experiment_label; 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace gcapi_internals 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool SetReactivationExperimentLabels(const wchar_t* brand_code, 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int shell_mode) { 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SetExperimentLabel(brand_code, gcapi_internals::kReactivationLabel, 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shell_mode); 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool SetRelaunchExperimentLabels(const wchar_t* brand_code, int shell_mode) { 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SetExperimentLabel(brand_code, gcapi_internals::kRelaunchLabel, 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shell_mode); 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 107