summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-02 22:52:04 +0000
committercpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-02 22:52:04 +0000
commitbece7018aa1a122b59fd3db11829c0c60a39167d (patch)
treeab77d5cb64c1fb933873b2301443e7db8db5504c
parentabdd08582e7840759ea7d6fc2beb64cdddae4c70 (diff)
downloadchromium_src-bece7018aa1a122b59fd3db11829c0c60a39167d.zip
chromium_src-bece7018aa1a122b59fd3db11829c0c60a39167d.tar.gz
chromium_src-bece7018aa1a122b59fd3db11829c0c60a39167d.tar.bz2
Merge 37799 - Modify the toast to hit systemlevel installs
This is somewhat tricky. setup.exe is executed by SYSTEM and as such we cannot run the experiment. So what we do is that if there is an interactive user logged in at the moment of chrome upgrade we relaunch setup in her context, from then on things proceed as in the previous case. Other enhancements New experiment codes TKxx and TLxx (99% and 1% as usual) New experiment group TK40 and TL40 : An active user BUG=32474 TEST=see bug Review URL: http://codereview.chromium.org/557077 TBR=cpu@chromium.org Review URL: http://codereview.chromium.org/560022 git-svn-id: svn://svn.chromium.org/chrome/branches/249/src@37900 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/installer/setup/setup_main.cc13
-rw-r--r--chrome/installer/util/google_chrome_distribution.cc103
-rw-r--r--chrome/installer/util/util_constants.cc3
-rw-r--r--chrome/installer/util/util_constants.h6
4 files changed, 108 insertions, 17 deletions
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index e4949f9d..d000fe5 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -301,7 +301,10 @@ installer_util::InstallStatus InstallChrome(const CommandLine& cmd_line,
// There might be an experiment (for upgrade usually) that needs to happen.
// An experiment's outcome can include chrome's uninstallation. If that is
// the case we would not do that directly at this point but in another
- // instance of setup.exe
+ // instance of setup.exe
+ //
+ // There is another way to reach this same function if this is a system
+ // level install. See HandleNonInstallCmdLineOptions().
dist->LaunchUserExperiment(install_status, *installer_version,
system_level);
}
@@ -466,6 +469,14 @@ bool HandleNonInstallCmdLineOptions(const CommandLine& cmd_line,
// Launch the inactive user toast experiment.
dist->InactiveUserToastExperiment();
return true;
+ } else if (cmd_line.HasSwitch(installer_util::switches::kSystemLevelToast)) {
+ // We started as system-level and have been re-launched as user level
+ // to continue with the toast experiment.
+ scoped_ptr<installer::Version>
+ installed_version(InstallUtil::GetChromeVersion(system_install));
+ dist->LaunchUserExperiment(installer_util::REENTRY_SYS_UPDATE,
+ *installed_version, false);
+ return true;
}
return false;
}
diff --git a/chrome/installer/util/google_chrome_distribution.cc b/chrome/installer/util/google_chrome_distribution.cc
index 0862697..dfc4275 100644
--- a/chrome/installer/util/google_chrome_distribution.cc
+++ b/chrome/installer/util/google_chrome_distribution.cc
@@ -9,6 +9,7 @@
#include <atlbase.h>
#include <windows.h>
+#include <wtsapi32.h>
#include <msi.h>
#include "base/file_path.h"
@@ -31,18 +32,33 @@
#include "installer_util_strings.h"
+#pragma comment(lib, "wtsapi32.lib")
+
namespace {
const wchar_t kChromeGuid[] = L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
// The following strings are the possible outcomes of the toast experiment
// as recorded in the |client| field. Previously the groups used "TSxx" but
// the data captured is not valid.
-const wchar_t kToastExpQualifyGroup[] = L"TF01";
-const wchar_t kToastExpCancelGroup[] = L"TF02";
-const wchar_t kToastExpUninstallGroup[] = L"TF04";
-const wchar_t kToastExpTriesOkGroup[] = L"TF18";
-const wchar_t kToastExpTriesErrorGroup[] = L"TF28";
-const wchar_t kToastExpBaseGroup[] = L"TF80";
+const wchar_t kToastExpControlGroup[] = L"T%lc01";
+const wchar_t kToastExpCancelGroup[] = L"T%lc02";
+const wchar_t kToastExpUninstallGroup[] = L"T%lc04";
+const wchar_t kToastExpTriesOkGroup[] = L"T%lc18";
+const wchar_t kToastExpTriesErrorGroup[] = L"T%lc28";
+const wchar_t kToastActiveGroup[] = L"T%lc41";
+const wchar_t kToastUDDirFailure[] = L"T%lc42";
+const wchar_t kToastExpBaseGroup[] = L"T%lc80";
+
+// Generates the actual group string that gets written in the registry.
+// |group| is one of the above kToast* strings and |flavor| is a number
+// between 0 and 5.
+//
+// The big experiment in Dec 2009 used TGxx and THxx.
+// The big experiment in Feb 2010 uses TKxx and TLxx .
+std::wstring GetExperimentGroup(const wchar_t* group, int flavor) {
+ wchar_t c = flavor < 5 ? L'K' + flavor : L'X';
+ return StringPrintf(group, c);
+}
// Substitute the locale parameter in uninstall URL with whatever
// Google Update tells us is the locale. In case we fail to find
@@ -58,6 +74,12 @@ std::wstring GetUninstallSurveyUrl() {
return ReplaceStringPlaceholders(kSurveyUrl.c_str(), language.c_str(), NULL);
}
+std::wstring GetWelcomeBackUrl() {
+ const wchar_t kWelcomeUrl[] = L"http://www.google.com/chrome/intl/$1/"
+ L"welcomeback-new.html";
+ return LocalizeUrl(kWelcomeUrl);
+}
+
// Converts FILETIME to hours. FILETIME times are absolute times in
// 100 nanosecond units. For example 5:30 pm of June 15, 2009 is 3580464.
int FileTimeToHours(const FILETIME& time) {
@@ -105,6 +127,29 @@ bool RelaunchSetup(const std::wstring& flag) {
return base::LaunchApp(cmd_line, false, false, NULL);
}
+// This function launches setup as the currently logged-in interactive
+// user that is the user whose logon session is attached to winsta0\default.
+// It assumes that currently we are running as SYSTEM in a non-interactive
+// windowstation.
+// The function fails if there is no interactive session active, basically
+// the computer is on but nobody has logged in locally.
+bool RelaunchSetupAsConsoleUser(const std::wstring& flag) {
+ CommandLine cmd_line(CommandLine::ForCurrentProcess()->GetProgram());
+ cmd_line.AppendSwitch(WideToASCII(flag));
+
+ DWORD console_id = ::WTSGetActiveConsoleSessionId();
+ if (console_id == 0xFFFFFFFF)
+ return false;
+ HANDLE user_token;
+ if (!::WTSQueryUserToken(console_id, &user_token))
+ return false;
+ bool launched = base::LaunchAppAsUser(user_token,
+ cmd_line.command_line_string(),
+ false, NULL);
+ ::CloseHandle(user_token);
+ return launched;
+}
+
} // namespace
bool GoogleChromeDistribution::BuildUninstallMetricsString(
@@ -417,20 +462,37 @@ void GoogleChromeDistribution::UpdateDiffInstallStatus(bool system_install,
}
// Currently we only have one experiment: the inactive user toast. Which only
-// applies for users doing upgrades and non-systemwide install.
+// applies for users doing upgrades.
+//
+// There are three scenarios when this function is called:
+// 1- Is a per-user-install and it updated: perform the experiment
+// 2- Is a system-install and it updated : relaunch as the interactive user
+// 3- It has been re-launched from the #2 case. In this case we enter
+// this function with |system_install| false.
void GoogleChromeDistribution::LaunchUserExperiment(
installer_util::InstallStatus status, const installer::Version& version,
bool system_install) {
- if ((installer_util::NEW_VERSION_UPDATED != status) || system_install)
- return;
- // If user has not opted-in for usage stats we don't do the experiments.
- if (!GoogleUpdateSettings::GetCollectStatsConsent())
- return;
+ if (system_install) {
+ if (installer_util::NEW_VERSION_UPDATED == status) {
+ // We need to relaunch as the interactive user.
+ RelaunchSetupAsConsoleUser(installer_util::switches::kSystemLevelToast);
+ return;
+ }
+ } else {
+ if ((installer_util::NEW_VERSION_UPDATED != status) &&
+ (installer_util::REENTRY_SYS_UPDATE != status)) {
+ // We are not updating or in re-launch. Exit.
+ return;
+ }
+ }
+
+ // currently only two equal experiment groups. 90% get the welcome back url.
+ int flavor = (base::RandDouble() > 0.1) ? 0 : 1;
std::wstring brand;
if (GoogleUpdateSettings::GetBrand(&brand) && (brand == L"CHXX")) {
- // The user automatically qualifies for the experiment.
+ // Testing only: the user automatically qualifies for the experiment.
LOG(INFO) << "Experiment qualification bypass";
} else {
// Time to verify the conditions for the experiment.
@@ -443,9 +505,20 @@ void GoogleChromeDistribution::LaunchUserExperiment(
// Check browser usage inactivity by the age of the last-write time of the
// chrome user data directory.
std::wstring user_data_dir = installer::GetChromeUserDataPath();
- const int kSixtyDays = 60 * 24;
+ const int kThirtyDays = 30 * 24;
int dir_age_hours = GetDirectoryWriteAgeInHours(user_data_dir.c_str());
- if (dir_age_hours < kSixtyDays)
+ if (dir_age_hours < 0) {
+ // This means that we failed to find the user data dir. The most likey
+ // cause is that this user has not ever used chrome at all which can
+ // happen in a system-level install.
+ GoogleUpdateSettings::SetClient(
+ GetExperimentGroup(kToastUDDirFailure, flavor));
+ return;
+ } else if (dir_age_hours < kThirtyDays) {
+ // An active user, so it does not qualify.
+ LOG(INFO) << "Chrome used in last " << dir_age_hours << " hours";
+ GoogleUpdateSettings::SetClient(
+ GetExperimentGroup(kToastActiveGroup, flavor));
return;
// At this point the user qualifies for the experiment, however we need to
// tag a control group, which is at random 50% of the population.
diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc
index 64544c4..77311dc 100644
--- a/chrome/installer/util/util_constants.cc
+++ b/chrome/installer/util/util_constants.cc
@@ -105,6 +105,9 @@ const wchar_t kAltDesktopShortcut[] = L"alt-desktop-shortcut";
// Perform the inactive user toast experiment.
const wchar_t kInactiveUserToast[] = L"inactive-user-toast";
+// User toast experiment switch from system context to user context.
+const wchar_t kSystemLevelToast[] = L"system-level-toast";
+
} // namespace switches
const wchar_t kInstallBinaryDir[] = L"Application";
diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h
index d781be2..54f9725 100644
--- a/chrome/installer/util/util_constants.h
+++ b/chrome/installer/util/util_constants.h
@@ -40,7 +40,10 @@ enum InstallStatus {
EULA_ACCEPTED, // EULA dialog was accepted by user.
EULA_ACCEPTED_OPT_IN, // EULA accepted wtih the crash optin selected.
INSTALL_DIR_IN_USE, // Installation directory is in use by another process
- UNINSTALL_REQUIRES_REBOOT // Uninstallation required a reboot.
+ UNINSTALL_REQUIRES_REBOOT, // Uninstallation required a reboot.
+ IN_USE_UPDATED, // Chrome successfully updated but old version running
+ SAME_VERSION_REPAIR_FAILED, // Chrome repair failed as Chrome was running
+ REENTRY_SYS_UPDATE // Setup has been re-lauched as the interactive user
};
namespace switches {
@@ -71,6 +74,7 @@ extern const wchar_t kVerboseLogging[];
extern const wchar_t kShowEula[];
extern const wchar_t kAltDesktopShortcut[];
extern const wchar_t kInactiveUserToast[];
+extern const wchar_t kSystemLevelToast[];
} // namespace switches
extern const wchar_t kInstallBinaryDir[];