summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/installer/setup/main.cc8
-rw-r--r--chrome/installer/util/browser_distribution.cc5
-rw-r--r--chrome/installer/util/browser_distribution.h7
-rw-r--r--chrome/installer/util/google_chrome_distribution.cc76
-rw-r--r--chrome/installer/util/google_chrome_distribution.h4
-rw-r--r--chrome/installer/util/helper.cc20
-rw-r--r--chrome/installer/util/helper.h6
-rw-r--r--chrome/installer/util/util_constants.cc1
-rw-r--r--chrome/installer/util/util_constants.h2
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__