diff options
author | cpu@google.com <cpu@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 18:54:03 +0000 |
---|---|---|
committer | cpu@google.com <cpu@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 18:54:03 +0000 |
commit | 519357d2b8ab7ac8d8a6c3fed1dbe744dc6f1bd5 (patch) | |
tree | de23c5e0e679b3bd9e8cea9786f6cc77321e01a8 /chrome/installer | |
parent | 08c8d347694b9dad34fcdff135517442372a34ba (diff) | |
download | chromium_src-519357d2b8ab7ac8d8a6c3fed1dbe744dc6f1bd5.zip chromium_src-519357d2b8ab7ac8d8a6c3fed1dbe744dc6f1bd5.tar.gz chromium_src-519357d2b8ab7ac8d8a6c3fed1dbe744dc6f1bd5.tar.bz2 |
Add experiment support in setup
- Adds the inactive user toast logic
- Some refactoring of helper functions
BUG=b/1484308
TEST=see the bug
Review URL: http://codereview.chromium.org/125234
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18640 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer')
-rw-r--r-- | chrome/installer/setup/main.cc | 8 | ||||
-rw-r--r-- | chrome/installer/util/browser_distribution.cc | 5 | ||||
-rw-r--r-- | chrome/installer/util/browser_distribution.h | 7 | ||||
-rw-r--r-- | chrome/installer/util/google_chrome_distribution.cc | 76 | ||||
-rw-r--r-- | chrome/installer/util/google_chrome_distribution.h | 4 | ||||
-rw-r--r-- | chrome/installer/util/helper.cc | 20 | ||||
-rw-r--r-- | chrome/installer/util/helper.h | 6 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.cc | 1 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.h | 2 |
9 files changed, 124 insertions, 5 deletions
diff --git a/chrome/installer/setup/main.cc b/chrome/installer/setup/main.cc index d840982..752fa59 100644 --- a/chrome/installer/setup/main.cc +++ b/chrome/installer/setup/main.cc @@ -340,6 +340,7 @@ installer_util::InstallStatus InstallChrome(const CommandLine& cmd_line, } LOG(INFO) << "created path " << temp_path; + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); std::wstring unpack_path(temp_path); file_util::AppendToPath(&unpack_path, std::wstring(installer::kInstallSourceDir)); @@ -408,6 +409,12 @@ 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 + dist->LaunchUserExperiment(install_status, *installer_version, + system_install, options); } // Delete temporary files. These include install temporary directory @@ -422,7 +429,6 @@ installer_util::InstallStatus InstallChrome(const CommandLine& cmd_line, } cleanup_list->Do(); - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); dist->UpdateDiffInstallStatus(system_install, incremental_install, install_status); return install_status; diff --git a/chrome/installer/util/browser_distribution.cc b/chrome/installer/util/browser_distribution.cc index 529d8ca..74416ad 100644 --- a/chrome/installer/util/browser_distribution.cc +++ b/chrome/installer/util/browser_distribution.cc @@ -85,3 +85,8 @@ std::wstring BrowserDistribution::GetVersionKey() { void BrowserDistribution::UpdateDiffInstallStatus(bool system_install, bool incremental_install, installer_util::InstallStatus install_status) { } + +void BrowserDistribution::LaunchUserExperiment( + installer_util::InstallStatus status, const installer::Version& version, + bool system_install, int options) { +} diff --git a/chrome/installer/util/browser_distribution.h b/chrome/installer/util/browser_distribution.h index a525f61..ece8960 100644 --- a/chrome/installer/util/browser_distribution.h +++ b/chrome/installer/util/browser_distribution.h @@ -53,6 +53,13 @@ class BrowserDistribution { virtual void UpdateDiffInstallStatus(bool system_install, bool incremental_install, installer_util::InstallStatus install_status); + // After an install or upgrade the user might qualify to participate in an + // experiment. This function determines if the user qualifies and if so it + // sets the wheels in motion or in simple cases does the experiment itself. + virtual void LaunchUserExperiment(installer_util::InstallStatus status, + const installer::Version& version, + bool system_install, int options); + protected: BrowserDistribution() {} diff --git a/chrome/installer/util/google_chrome_distribution.cc b/chrome/installer/util/google_chrome_distribution.cc index 8dcdfc0..eec4a58 100644 --- a/chrome/installer/util/google_chrome_distribution.cc +++ b/chrome/installer/util/google_chrome_distribution.cc @@ -17,11 +17,13 @@ #include "base/scoped_ptr.h" #include "base/string_util.h" #include "base/wmi_util.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/json_value_serializer.h" #include "chrome/common/pref_names.h" #include "chrome/installer/util/l10n_string_util.h" #include "chrome/installer/util/google_update_constants.h" #include "chrome/installer/util/google_update_settings.h" +#include "chrome/installer/util/helper.h" #include "chrome/installer/util/util_constants.h" #include "installer_util_strings.h" @@ -40,8 +42,47 @@ std::wstring GetUninstallSurveyUrl() { return ReplaceStringPlaceholders(kSurveyUrl.c_str(), language.c_str(), NULL); } + +// 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) { + const ULONGLONG k100sNanoSecsToHours = 10000000LL * 60 * 60; + ULARGE_INTEGER uli = {time.dwLowDateTime, time.dwHighDateTime}; + return static_cast<int>(uli.QuadPart / k100sNanoSecsToHours); +} + +// Returns the directory last write time in hours since January 1, 1601. +// Returns -1 if there was an error retrieving the directory time. +int GetDirectoryWriteTimeInHours(const wchar_t* path) { + // To open a directory you need to pass FILE_FLAG_BACKUP_SEMANTICS. + DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + HANDLE file = ::CreateFileW(path, 0, share, NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (INVALID_HANDLE_VALUE == file) + return -1; + FILETIME time; + if (!::GetFileTime(file, NULL, NULL, &time)) + return -1; + return FileTimeToHours(time); +} + +// Returns the directory last-write time age in hours, relative to current +// time, so if it returns 14 it means that the directory was last written 14 +// hours ago. Returns -1 if there was an error retrieving the directory. +int GetDirectoryWriteAgeInHours(const wchar_t* path) { + int dir_time = GetDirectoryWriteTimeInHours(path); + if (dir_time < 0) + return dir_time; + FILETIME time; + GetSystemTimeAsFileTime(&time); + int now_time = FileTimeToHours(time); + if (dir_time >= now_time) + return 0; + return (now_time - dir_time); } +} // namespace + bool GoogleChromeDistribution::BuildUninstallMetricsString( DictionaryValue* uninstall_metrics_dict, std::wstring* metrics) { DCHECK(NULL != metrics); @@ -329,3 +370,38 @@ void GoogleChromeDistribution::UpdateDiffInstallStatus(bool system_install, } key.Close(); } + +void GoogleChromeDistribution::LaunchUserExperiment( + installer_util::InstallStatus status, const installer::Version& version, + bool system_install, int options) { + // Currently we only have one experiment: the inactive user toast. Which + // only applies for users doing upgrades. + if (installer_util::NEW_VERSION_UPDATED != status) + return; + + // If user has not opted-in for usage stats or it is a system-wide install + // we don't do the experiments + if (!GoogleUpdateSettings::GetCollectStatsConsent() || system_install) + return; + + // User must be in the Great Britain as defined by googe_update language. + std::wstring lang; + if (!GoogleUpdateSettings::GetLanguage(&lang) || (lang != L"en-GB")) + return; + + // Check browser usage inactivity by the age of the last-write time of the + // chrome user data directory. Ninety days is our trigger. + std::wstring user_data_dir = installer::GetChromeUserDataPath(); + const int kNinetyDays = 90 * 24; + int dir_age_hours = GetDirectoryWriteAgeInHours(user_data_dir.c_str()); + if (dir_age_hours < kNinetyDays) + return; + + // User qualifies for the experiment. Launch chrome with --try-chrome + int32 exit_code = 0; + std::wstring option(L"--"); + option.append(switches::kTryChromeAgain); + if (!installer::LaunchChromeAndWaitForResult(false, option, &exit_code)) + return; +} + diff --git a/chrome/installer/util/google_chrome_distribution.h b/chrome/installer/util/google_chrome_distribution.h index 4677e94..9d41c33 100644 --- a/chrome/installer/util/google_chrome_distribution.h +++ b/chrome/installer/util/google_chrome_distribution.h @@ -78,6 +78,10 @@ class GoogleChromeDistribution : public BrowserDistribution { virtual void UpdateDiffInstallStatus(bool system_install, bool incremental_install, installer_util::InstallStatus install_status); + virtual void LaunchUserExperiment(installer_util::InstallStatus status, + const installer::Version& version, + bool system_install, int options); + private: friend class BrowserDistribution; FRIEND_TEST(GoogleChromeDistributionTest, TestExtractUninstallMetrics); diff --git a/chrome/installer/util/helper.cc b/chrome/installer/util/helper.cc index cfd6a32..a52f6b5 100644 --- a/chrome/installer/util/helper.cc +++ b/chrome/installer/util/helper.cc @@ -16,23 +16,35 @@ #include "chrome/installer/util/version.h" #include "chrome/installer/util/work_item_list.h" -std::wstring installer::GetChromeInstallPath(bool system_install) { +namespace { + +std::wstring GetChromeInstallBasePath(bool system_install, + const wchar_t* subpath) { FilePath install_path; if (system_install) { PathService::Get(base::DIR_PROGRAM_FILES, &install_path); } else { PathService::Get(base::DIR_LOCAL_APP_DATA, &install_path); } - if (!install_path.empty()) { BrowserDistribution* dist = BrowserDistribution::GetDistribution(); install_path = install_path.Append(dist->GetInstallSubDir()); - install_path = install_path.Append(installer_util::kInstallBinaryDir); + install_path = install_path.Append(subpath); } - return install_path.ToWStringHack(); } +} // namespace + +std::wstring installer::GetChromeInstallPath(bool system_install) { + return GetChromeInstallBasePath(system_install, + installer_util::kInstallBinaryDir); +} + +std::wstring installer::GetChromeUserDataPath() { + return GetChromeInstallBasePath(false, installer_util::kInstallUserDataDir); +} + bool installer::LaunchChrome(bool system_install) { std::wstring chrome_exe(L"\""); chrome_exe.append(installer::GetChromeInstallPath(system_install)); diff --git a/chrome/installer/util/helper.h b/chrome/installer/util/helper.h index c59ca89..afbbf17 100644 --- a/chrome/installer/util/helper.h +++ b/chrome/installer/util/helper.h @@ -18,6 +18,12 @@ namespace installer { // location (Document And Settings\<user>\Local Settings...) std::wstring GetChromeInstallPath(bool system_install); +// This function returns the path to the directory that holds the user data, +// this is always inside "Document And Settings\<user>\Local Settings.". Note +// that this is the default user data directory and does not take into account +// that it can be overriden with a command line parameter. +std::wstring GetChromeUserDataPath(); + // Launches Chrome without waiting for its exit. bool LaunchChrome(bool system_install); diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc index b7323b5..8bb0e5a 100644 --- a/chrome/installer/util/util_constants.cc +++ b/chrome/installer/util/util_constants.cc @@ -91,6 +91,7 @@ const wchar_t kAltDesktopShortcut[] = L"alt-desktop-shortcut"; } // namespace switches const wchar_t kInstallBinaryDir[] = L"Application"; +const wchar_t kInstallUserDataDir[] = L"User Data"; const wchar_t kChromeExe[] = L"chrome.exe"; const wchar_t kChromeOldExe[] = L"old_chrome.exe"; const wchar_t kChromeNewExe[] = L"new_chrome.exe"; diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h index 0484f7c..671641b 100644 --- a/chrome/installer/util/util_constants.h +++ b/chrome/installer/util/util_constants.h @@ -93,6 +93,7 @@ extern const wchar_t kAltDesktopShortcut[]; } // namespace switches extern const wchar_t kInstallBinaryDir[]; +extern const wchar_t kInstallUserDataDir[]; extern const wchar_t kChromeExe[]; extern const wchar_t kChromeOldExe[]; extern const wchar_t kChromeNewExe[]; @@ -104,6 +105,7 @@ extern const wchar_t kUninstallStringField[]; extern const wchar_t kUninstallDisplayNameField[]; extern const wchar_t kUninstallMetricsName[]; extern const wchar_t kUninstallInstallationDate[]; + } // namespace installer_util #endif // CHROME_INSTALLER_UTIL_UTIL_CONSTANTS_H__ |