gcapi_omaha_experiment.cc revision f2477e01787aa58f445919b809d89e252beef54f
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"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_split.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/string_util.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/stringprintf.h"
118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/time/time.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/gcapi/gcapi.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/installer/util/google_update_constants.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/installer/util/google_update_experiment_util.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/installer/util/google_update_settings.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the number of weeks since 2/3/2003.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetCurrentRlzWeek(const base::Time& current_time) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time::Exploded february_third_2003_exploded =
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      {2003, 2, 1, 3, 0, 0, 0, 0};
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::Time f = base::Time::FromUTCExploded(february_third_2003_exploded);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta delta = current_time - f;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return delta.InDays() / 7;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetExperimentLabel(const wchar_t* brand_code,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const string16& label,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int shell_mode) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!brand_code) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool system_level = shell_mode == GCAPI_INVOKED_UAC_ELEVATION;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 original_labels;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GoogleUpdateSettings::ReadExperimentLabels(system_level,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  &original_labels)) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Split the original labels by the label separator.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<string16> entries;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SplitStringUsingSubstr(
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      original_labels, google_update::kExperimentLabelSep, &entries);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Keep all labels, but the one we want to add/replace.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 new_labels;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<string16>::const_iterator it = entries.begin();
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)       it != entries.end(); ++it) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!it->empty() && !StartsWith(*it, label + L"=", true)) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_labels += *it;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_labels += google_update::kExperimentLabelSep;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_labels.append(
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gcapi_internals::GetGCAPIExperimentLabel(brand_code, label));
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GoogleUpdateSettings::SetExperimentLabels(system_level,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   new_labels);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace gcapi_internals {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const wchar_t kReactivationLabel[] = L"reacbrand";
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const wchar_t kRelaunchLabel[] = L"relaunchbrand";
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 GetGCAPIExperimentLabel(const wchar_t* brand_code,
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 const string16& label) {
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Keeps a fixed time state for this GCAPI instance; this makes tests reliable
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when crossing time boundaries on the system clock and doesn't otherwise
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // affect results of this short lived binary.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static time_t instance_time_value = 0;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (instance_time_value == 0)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instance_time_value = base::Time::Now().ToTimeT();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time instance_time = base::Time::FromTimeT(instance_time_value);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 gcapi_experiment_label;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SStringPrintf(&gcapi_experiment_label,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      L"%ls=%ls_%d|%ls",
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      label.c_str(),
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      brand_code,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      GetCurrentRlzWeek(instance_time),
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      installer::BuildExperimentDateString(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          instance_time).c_str());
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gcapi_experiment_label;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gcapi_internals
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetReactivationExperimentLabels(const wchar_t* brand_code,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int shell_mode) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SetExperimentLabel(brand_code, gcapi_internals::kReactivationLabel,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            shell_mode);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetRelaunchExperimentLabels(const wchar_t* brand_code, int shell_mode) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SetExperimentLabel(brand_code, gcapi_internals::kRelaunchLabel,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            shell_mode);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)