summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormad@google.com <mad@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-20 21:19:50 +0000
committermad@google.com <mad@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-20 21:19:50 +0000
commitc5d4b184cc147760a0a783a02815d37f7a712710 (patch)
tree783fe7ccc9650cc0a27905ced7e57211e66339d7
parent2dcb00a07dabee3f055f3d63f23ba17c060eadaf (diff)
downloadchromium_src-c5d4b184cc147760a0a783a02815d37f7a712710.zip
chromium_src-c5d4b184cc147760a0a783a02815d37f7a712710.tar.gz
chromium_src-c5d4b184cc147760a0a783a02815d37f7a712710.tar.bz2
Adding a SW reporter component updater.
This is a special component that only gets registered when the user reset the profile settings and has enabled UMA reporting. Once installed (or if already installed), the component is executed and it's exit code is reported via UMA. In case the component doesn't have time to be installed and executed before Chrome exits, a local state pref identifies that we have a pending registration or execution so that it can be continued on next Chrome startup. BUG=377601 R=asvitkine@chromium.org, battre@chromium.org, jhawkins@chromium.org, robertshield@chromium.org, sorin@chromium.org, waffles@chromium.org Review URL: https://codereview.chromium.org/333193002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278820 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_browser_main.cc5
-rw-r--r--chrome/browser/component_updater/sw_reporter_installer_win.cc276
-rw-r--r--chrome/browser/component_updater/sw_reporter_installer_win.h36
-rw-r--r--chrome/browser/prefs/browser_prefs.cc4
-rw-r--r--chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc16
-rw-r--r--chrome/browser/profile_resetter/profile_resetter.cc40
-rw-r--r--chrome/browser/profile_resetter/profile_resetter.h4
-rw-r--r--chrome/browser/profile_resetter/profile_resetter_test_base.cc4
-rw-r--r--chrome/browser/ui/webui/options/reset_profile_settings_handler.cc1
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/common/pref_names.cc7
-rw-r--r--chrome/common/pref_names.h4
-rw-r--r--tools/metrics/histograms/histograms.xml31
13 files changed, 407 insertions, 23 deletions
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index d265c65..b0260a6 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -165,6 +165,7 @@
#include "base/win/windows_version.h"
#include "chrome/browser/browser_util_win.h"
#include "chrome/browser/chrome_browser_main_win.h"
+#include "chrome/browser/component_updater/sw_reporter_installer_win.h"
#include "chrome/browser/first_run/try_chrome_dialog_view.h"
#include "chrome/browser/first_run/upgrade_util_win.h"
#include "chrome/browser/ui/network_profile_bubble.h"
@@ -407,6 +408,10 @@ void RegisterComponentsForUpdate(const CommandLine& command_line) {
RegisterCldComponent(cus);
#endif
+#if defined(OS_WIN)
+ ExecutePendingSwReporter(cus, g_browser_process->local_state());
+#endif
+
cus->Start();
}
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.cc b/chrome/browser/component_updater/sw_reporter_installer_win.cc
new file mode 100644
index 0000000..cca7876
--- /dev/null
+++ b/chrome/browser/component_updater/sw_reporter_installer_win.cc
@@ -0,0 +1,276 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/component_updater/sw_reporter_installer_win.h"
+
+#include <string>
+#include <vector>
+
+#include "base/base_paths.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/sparse_histogram.h"
+#include "base/path_service.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/pref_service.h"
+#include "base/process/kill.h"
+#include "base/process/launch.h"
+#include "base/task_runner_util.h"
+#include "base/threading/worker_pool.h"
+#include "base/win/registry.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/component_updater/component_updater_service.h"
+#include "chrome/browser/component_updater/component_updater_utils.h"
+#include "chrome/browser/component_updater/default_component_installer.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/pref_names.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace component_updater {
+
+namespace {
+
+// These values are used to send UMA information and are replicated in the
+// histograms.xml file, so the order MUST NOT CHANGE.
+enum SwReporterUmaValue {
+ SW_REPORTER_EXPLICIT_REQUEST = 0,
+ SW_REPORTER_STARTUP_RETRY = 1,
+ SW_REPORTER_RETRIED_TOO_MANY_TIMES = 2,
+ SW_REPORTER_START_EXECUTION = 3,
+ SW_REPORTER_FAILED_TO_START = 4,
+ SW_REPORTER_REGISTRY_EXIT_CODE = 5,
+ SW_REPORTER_MAX,
+};
+
+// The maximum number of times to retry a download on startup.
+const int kMaxRetry = 7;
+
+// CRX hash. The extension id is: gkmgaooipdjhmangpemjhigmamcehddo. The hash was
+// generated in Python with something like this:
+// hashlib.sha256().update(open("<file>.crx").read()[16:16+294]).digest().
+const uint8 kSha256Hash[] = {0x6a, 0xc6, 0x0e, 0xe8, 0xf3, 0x97, 0xc0, 0xd6,
+ 0xf4, 0xc9, 0x78, 0x6c, 0x0c, 0x24, 0x73, 0x3e,
+ 0x05, 0xa5, 0x62, 0x4b, 0x2e, 0xc7, 0xb7, 0x1c,
+ 0x5f, 0xea, 0xf0, 0x88, 0xf6, 0x97, 0x9b, 0xc7};
+
+const base::FilePath::CharType kSwReporterExeName[] =
+ FILE_PATH_LITERAL("software_reporter_tool.exe");
+
+// Where to fetch the reporter exit code in the registry.
+const wchar_t kSoftwareRemovalToolRegistryKey[] =
+ L"Software\\Google\\Software Removal Tool";
+const wchar_t kExitCodeRegistryValueName[] = L"ExitCode";
+
+void ReportUmaStep(SwReporterUmaValue value) {
+ UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.Step", value, SW_REPORTER_MAX);
+}
+
+// This function is called on the UI thread to report the SwReporter exit code
+// and then clear it from the registry as well as clear the execution state
+// from the local state. This could be called from an interruptible worker
+// thread so should be resilient to unexpected shutdown.
+void ReportAndClearExitCode(int exit_code) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.ExitCode", exit_code);
+
+ base::win::RegKey srt_key(
+ HKEY_CURRENT_USER, kSoftwareRemovalToolRegistryKey, KEY_WRITE);
+ srt_key.DeleteValue(kExitCodeRegistryValueName);
+
+ // Now that we are done we can reset the try count.
+ g_browser_process->local_state()->SetInteger(
+ prefs::kSwReporterExecuteTryCount, 0);
+}
+
+// This function is called from a worker thread to launch the SwReporter and
+// wait for termination to collect its exit code. This task could be interrupted
+// by a shutdown at anytime, so it shouldn't depend on anything external that
+// could be shutdown beforehand.
+void LaunchAndWaitForExit(const base::FilePath& exe_path) {
+ const base::CommandLine reporter_command_line(exe_path);
+ base::ProcessHandle scan_reporter_process = base::kNullProcessHandle;
+ if (!base::LaunchProcess(reporter_command_line,
+ base::LaunchOptions(),
+ &scan_reporter_process)) {
+ ReportUmaStep(SW_REPORTER_FAILED_TO_START);
+ return;
+ }
+ ReportUmaStep(SW_REPORTER_START_EXECUTION);
+
+ int exit_code = -1;
+ bool success = base::WaitForExitCode(scan_reporter_process, &exit_code);
+ DCHECK(success);
+ base::CloseProcessHandle(scan_reporter_process);
+ scan_reporter_process = base::kNullProcessHandle;
+ // It's OK if this doesn't complete, the work will continue on next startup.
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&ReportAndClearExitCode, exit_code));
+}
+
+void ExecuteReporter(const base::FilePath& install_dir) {
+ base::WorkerPool::PostTask(
+ FROM_HERE,
+ base::Bind(&LaunchAndWaitForExit, install_dir.Append(kSwReporterExeName)),
+ true);
+}
+
+class SwReporterInstallerTraits : public ComponentInstallerTraits {
+ public:
+ explicit SwReporterInstallerTraits(PrefService* prefs) : prefs_(prefs) {}
+
+ virtual ~SwReporterInstallerTraits() {}
+
+ virtual bool VerifyInstallation(const base::FilePath& dir) const {
+ return base::PathExists(dir.Append(kSwReporterExeName));
+ }
+
+ virtual bool CanAutoUpdate() const { return true; }
+
+ virtual bool OnCustomInstall(const base::DictionaryValue& manifest,
+ const base::FilePath& install_dir) {
+ return true;
+ }
+
+ virtual void ComponentReady(const base::Version& version,
+ const base::FilePath& install_dir,
+ scoped_ptr<base::DictionaryValue> manifest) {
+ wcsncpy_s(version_dir_,
+ _MAX_PATH,
+ install_dir.value().c_str(),
+ install_dir.value().size());
+ // Only execute the reporter if there is still a pending request for it.
+ if (prefs_->GetInteger(prefs::kSwReporterExecuteTryCount) > 0)
+ ExecuteReporter(install_dir);
+ }
+
+ virtual base::FilePath GetBaseDirectory() const { return install_dir(); }
+
+ virtual void GetHash(std::vector<uint8>* hash) const { GetPkHash(hash); }
+
+ virtual std::string GetName() const { return "Software Reporter Tool"; }
+
+ static base::FilePath install_dir() {
+ // The base directory on windows looks like:
+ // <profile>\AppData\Local\Google\Chrome\User Data\SwReporter\.
+ base::FilePath result;
+ PathService::Get(chrome::DIR_USER_DATA, &result);
+ return result.Append(FILE_PATH_LITERAL("SwReporter"));
+ }
+
+ static std::string ID() {
+ CrxComponent component;
+ component.version = Version("0.0.0.0");
+ GetPkHash(&component.pk_hash);
+ return component_updater::GetCrxComponentID(component);
+ }
+
+ static base::FilePath VersionPath() { return base::FilePath(version_dir_); }
+
+ private:
+ static void GetPkHash(std::vector<uint8>* hash) {
+ DCHECK(hash);
+ hash->assign(kSha256Hash, kSha256Hash + sizeof(kSha256Hash));
+ }
+
+ PrefService* prefs_;
+ static wchar_t version_dir_[_MAX_PATH];
+};
+
+wchar_t SwReporterInstallerTraits::version_dir_[] = {};
+
+void RegisterComponent(ComponentUpdateService* cus, PrefService* prefs) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ scoped_ptr<ComponentInstallerTraits> traits(
+ new SwReporterInstallerTraits(prefs));
+ // |cus| will take ownership of |installer| during installer->Register(cus).
+ DefaultComponentInstaller* installer =
+ new DefaultComponentInstaller(traits.Pass());
+ installer->Register(cus);
+}
+
+// We need a conditional version of register component so that it can be called
+// back on the UI thread after validating on the File thread that the component
+// path exists and we must re-register on startup for example.
+void MaybeRegisterComponent(ComponentUpdateService* cus,
+ PrefService* prefs,
+ bool register_component) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (register_component)
+ RegisterComponent(cus, prefs);
+}
+
+} // namespace
+
+void ExecuteSwReporter(ComponentUpdateService* cus, PrefService* prefs) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // This is an explicit call, so let's forget about previous incomplete
+ // execution attempts and start from scratch.
+ prefs->SetInteger(prefs::kSwReporterExecuteTryCount, kMaxRetry);
+ ReportUmaStep(SW_REPORTER_EXPLICIT_REQUEST);
+ const std::vector<std::string> registered_components(cus->GetComponentIDs());
+ if (std::find(registered_components.begin(),
+ registered_components.end(),
+ SwReporterInstallerTraits::ID()) ==
+ registered_components.end()) {
+ RegisterComponent(cus, prefs);
+ } else if (!SwReporterInstallerTraits::VersionPath().empty()) {
+ // Here, we already have a fully registered and installed component
+ // available for immediate use. This doesn't handle cases where the version
+ // folder is there but the executable is not within in. This is a corruption
+ // we don't want to handle here.
+ ExecuteReporter(SwReporterInstallerTraits::VersionPath());
+ }
+ // If the component is registered but the version path is not available, it
+ // means the component was not fully installed yet, and it should run the
+ // reporter when ComponentReady is called.
+}
+
+void ExecutePendingSwReporter(ComponentUpdateService* cus, PrefService* prefs) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // Register the existing component for updates.
+ base::PostTaskAndReplyWithResult(
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
+ FROM_HERE,
+ base::Bind(&base::PathExists, SwReporterInstallerTraits::install_dir()),
+ base::Bind(&MaybeRegisterComponent, cus, prefs));
+
+ // Run the reporter if there is a pending execution request.
+ int execute_try_count = prefs->GetInteger(prefs::kSwReporterExecuteTryCount);
+ if (execute_try_count > 0) {
+ // Retrieve the results if the pending request has completed.
+ base::win::RegKey srt_key(
+ HKEY_CURRENT_USER, kSoftwareRemovalToolRegistryKey, KEY_READ);
+ DWORD exit_code = -1;
+ if (srt_key.Valid() &&
+ srt_key.ReadValueDW(kExitCodeRegistryValueName, &exit_code) ==
+ ERROR_SUCCESS) {
+ ReportUmaStep(SW_REPORTER_REGISTRY_EXIT_CODE);
+ ReportAndClearExitCode(exit_code);
+ return;
+ }
+
+ // The previous request has not completed. The reporter will run again
+ // when ComponentReady is called or the request is abandoned if it has
+ // been tried too many times.
+ prefs->SetInteger(prefs::kSwReporterExecuteTryCount, --execute_try_count);
+ if (execute_try_count > 0)
+ ReportUmaStep(SW_REPORTER_STARTUP_RETRY);
+ else
+ ReportUmaStep(SW_REPORTER_RETRIED_TOO_MANY_TIMES);
+ }
+}
+
+void RegisterPrefsForSwReporter(PrefRegistrySimple* registry) {
+ registry->RegisterIntegerPref(prefs::kSwReporterExecuteTryCount, 0);
+}
+
+} // namespace component_updater
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.h b/chrome/browser/component_updater/sw_reporter_installer_win.h
new file mode 100644
index 0000000..a3d0d4e
--- /dev/null
+++ b/chrome/browser/component_updater/sw_reporter_installer_win.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_COMPONENT_UPDATER_SW_REPORTER_INSTALLER_WIN_H_
+#define CHROME_BROWSER_COMPONENT_UPDATER_SW_REPORTER_INSTALLER_WIN_H_
+
+class PrefRegistrySimple;
+class PrefService;
+
+namespace component_updater {
+
+class ComponentUpdateService;
+
+// Execute the SwReporter if one is available, otherwise 1) register with the
+// component updater, 2) save a preference in |prefs| identifying that an
+// attempt to execute the reporter tool was made, so that calls to
+// ExecutePending below will be able to continue the work if it doesn't complete
+// before the Chrome session ends. It will also allow the component updater to
+// know if there is a pending execution or not when an update happens. This must
+// be called from the UI thread.
+void ExecuteSwReporter(ComponentUpdateService* cus, PrefService* prefs);
+
+// ExecutePending will only register/execute the SwReporter if a preference is
+// set in |prefs|, identifying that an attempt to register/execute the
+// SwReporter has already been made by calling ExecuteSwReporter above. But only
+// if the max number of retries has not been reached yet. This must be called
+// from the UI thread.
+void ExecutePendingSwReporter(ComponentUpdateService* cus, PrefService* prefs);
+
+// Register user preferences related to the SwReporter.
+void RegisterPrefsForSwReporter(PrefRegistrySimple* registry);
+
+} // namespace component_updater
+
+#endif // CHROME_BROWSER_COMPONENT_UPDATER_SW_REPORTER_INSTALLER_WIN_H_
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 2e74da7..076eff5 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/prefs/browser_prefs.h"
+#include <string>
+
#include "base/debug/trace_event.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
@@ -185,6 +187,7 @@
#if defined(OS_WIN)
#include "chrome/browser/apps/app_launch_for_metro_restart_win.h"
+#include "chrome/browser/component_updater/sw_reporter_installer_win.h"
#endif
#if defined(TOOLKIT_VIEWS)
@@ -329,6 +332,7 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
#if defined(OS_WIN)
app_metro_launch::RegisterPrefs(registry);
+ component_updater::RegisterPrefsForSwReporter(registry);
password_manager::PasswordManager::RegisterLocalPrefs(registry);
#endif
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc
index 502b805..d8e6e2f 100644
--- a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc
+++ b/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc
@@ -356,14 +356,14 @@ void AutomaticProfileResetterDelegateImpl::RunProfileSettingsReset(
old_settings_snapshot.reset(new ResettableSettingsSnapshot(profile_));
old_settings_snapshot->RequestShortcuts(base::Closure());
}
- profile_resetter_->Reset(
- resettable_aspects_,
- brandcoded_defaults_.Pass(),
- base::Bind(&AutomaticProfileResetterDelegateImpl::
- OnProfileSettingsResetCompleted,
- AsWeakPtr(),
- completion,
- base::Passed(&old_settings_snapshot)));
+ profile_resetter_->Reset(resettable_aspects_,
+ brandcoded_defaults_.Pass(),
+ send_feedback,
+ base::Bind(&AutomaticProfileResetterDelegateImpl::
+ OnProfileSettingsResetCompleted,
+ AsWeakPtr(),
+ completion,
+ base::Passed(&old_settings_snapshot)));
}
void AutomaticProfileResetterDelegateImpl::
diff --git a/chrome/browser/profile_resetter/profile_resetter.cc b/chrome/browser/profile_resetter/profile_resetter.cc
index d37e61c..17f451f 100644
--- a/chrome/browser/profile_resetter/profile_resetter.cc
+++ b/chrome/browser/profile_resetter/profile_resetter.cc
@@ -4,9 +4,12 @@
#include "chrome/browser/profile_resetter/profile_resetter.h"
+#include <string>
+
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/synchronization/cancellation_flag.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/browsing_data/browsing_data_helper.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/extensions/extension_service.h"
@@ -30,8 +33,8 @@
#if defined(OS_WIN)
#include "base/base_paths.h"
#include "base/path_service.h"
+#include "chrome/browser/component_updater/sw_reporter_installer_win.h"
#include "chrome/installer/util/shell_util.h"
-#include "content/public/browser/browser_thread.h"
namespace {
@@ -77,6 +80,7 @@ ProfileResetter::~ProfileResetter() {
void ProfileResetter::Reset(
ProfileResetter::ResettableFlags resettable_flags,
scoped_ptr<BrandcodedDefaultSettings> master_settings,
+ bool accepted_send_feedback,
const base::Closure& callback) {
DCHECK(CalledOnValidThread());
DCHECK(master_settings);
@@ -102,16 +106,16 @@ void ProfileResetter::Reset(
struct {
Resettable flag;
void (ProfileResetter::*method)();
- } flagToMethod [] = {
- { DEFAULT_SEARCH_ENGINE, &ProfileResetter::ResetDefaultSearchEngine },
- { HOMEPAGE, &ProfileResetter::ResetHomepage },
- { CONTENT_SETTINGS, &ProfileResetter::ResetContentSettings },
- { COOKIES_AND_SITE_DATA, &ProfileResetter::ResetCookiesAndSiteData },
- { EXTENSIONS, &ProfileResetter::ResetExtensions },
- { STARTUP_PAGES, &ProfileResetter::ResetStartupPages },
- { PINNED_TABS, &ProfileResetter::ResetPinnedTabs },
- { SHORTCUTS, &ProfileResetter::ResetShortcuts },
- };
+ } flagToMethod[] = {
+ {DEFAULT_SEARCH_ENGINE, &ProfileResetter::ResetDefaultSearchEngine},
+ {HOMEPAGE, &ProfileResetter::ResetHomepage},
+ {CONTENT_SETTINGS, &ProfileResetter::ResetContentSettings},
+ {COOKIES_AND_SITE_DATA, &ProfileResetter::ResetCookiesAndSiteData},
+ {EXTENSIONS, &ProfileResetter::ResetExtensions},
+ {STARTUP_PAGES, &ProfileResetter::ResetStartupPages},
+ {PINNED_TABS, &ProfileResetter::ResetPinnedTabs},
+ {SHORTCUTS, &ProfileResetter::ResetShortcuts},
+ };
ResettableFlags reset_triggered_for_flags = 0;
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flagToMethod); ++i) {
@@ -121,6 +125,20 @@ void ProfileResetter::Reset(
}
}
+// When the user resets any of their settings on Windows and agreed to sending
+// feedback, run the software reporter tool to see if it could find the reason
+// why the user wanted a reset.
+#if defined(OS_WIN)
+ // The browser process and / or local_state can be NULL when running tests.
+ if (accepted_send_feedback && g_browser_process &&
+ g_browser_process->local_state() &&
+ g_browser_process->local_state()->GetBoolean(
+ prefs::kMetricsReportingEnabled)) {
+ ExecuteSwReporter(g_browser_process->component_updater(),
+ g_browser_process->local_state());
+ }
+#endif
+
DCHECK_EQ(resettable_flags, reset_triggered_for_flags);
}
diff --git a/chrome/browser/profile_resetter/profile_resetter.h b/chrome/browser/profile_resetter/profile_resetter.h
index f22f30d..354c1b3 100644
--- a/chrome/browser/profile_resetter/profile_resetter.h
+++ b/chrome/browser/profile_resetter/profile_resetter.h
@@ -60,9 +60,11 @@ class ProfileResetter : public base::NonThreadSafe,
// Resets |resettable_flags| and calls |callback| on the UI thread on
// completion. |default_settings| allows the caller to specify some default
- // settings. |default_settings| shouldn't be NULL.
+ // settings. |default_settings| shouldn't be NULL. |accepted_send_feedback|
+ // identifies whether the user accepted to send feedback or not.
void Reset(ResettableFlags resettable_flags,
scoped_ptr<BrandcodedDefaultSettings> master_settings,
+ bool accepted_send_feedback,
const base::Closure& callback);
bool IsActive() const;
diff --git a/chrome/browser/profile_resetter/profile_resetter_test_base.cc b/chrome/browser/profile_resetter/profile_resetter_test_base.cc
index 85b4ef7..f149672 100644
--- a/chrome/browser/profile_resetter/profile_resetter_test_base.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_test_base.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/profile_resetter/profile_resetter_test_base.h"
+#include <string>
+
#include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
ProfileResetterMockObject::ProfileResetterMockObject() {}
@@ -33,6 +35,7 @@ void ProfileResetterTestBase::ResetAndWait(
new BrandcodedDefaultSettings);
resetter_->Reset(resettable_flags,
master_settings.Pass(),
+ false,
base::Bind(&ProfileResetterMockObject::StopLoop,
base::Unretained(&mock_object_)));
mock_object_.RunLoop();
@@ -45,6 +48,7 @@ void ProfileResetterTestBase::ResetAndWait(
new BrandcodedDefaultSettings(prefs));
resetter_->Reset(resettable_flags,
master_settings.Pass(),
+ false,
base::Bind(&ProfileResetterMockObject::StopLoop,
base::Unretained(&mock_object_)));
mock_object_.RunLoop();
diff --git a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc b/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc
index 130eb137..6efc5dc 100644
--- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc
@@ -198,6 +198,7 @@ void ResetProfileSettingsHandler::ResetProfile(bool send_settings) {
resetter_->Reset(
ProfileResetter::ALL,
default_settings.Pass(),
+ send_settings,
base::Bind(&ResetProfileSettingsHandler::OnResetProfileSettingsDone,
AsWeakPtr(),
send_settings));
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 886d138..fa0de94 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -474,6 +474,8 @@
'browser/component_updater/ppapi_utils.h',
'browser/component_updater/recovery_component_installer.cc',
'browser/component_updater/recovery_component_installer.h',
+ 'browser/component_updater/sw_reporter_installer_win.cc',
+ 'browser/component_updater/sw_reporter_installer_win.h',
'browser/component_updater/swiftshader_component_installer.cc',
'browser/component_updater/swiftshader_component_installer.h',
'browser/component_updater/update_checker.cc',
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 85e68af..3781f90 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -2224,6 +2224,13 @@ const char kComponentUpdaterState[] = "component_updater.state";
const char kAttemptedToEnableAutoupdate[] =
"browser.attempted_to_enable_autoupdate";
+#if defined(OS_WIN)
+// The number of attempts left to execute the SwReporter. This starts at the max
+// number of retries allowed, and goes down as attempts are made and is cleared
+// back to 0 when it successfully completes.
+const char kSwReporterExecuteTryCount[] = "software_reporter.execute_try_count";
+#endif
+
// The next media gallery ID to assign.
const char kMediaGalleriesUniqueId[] = "media_galleries.gallery_id";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 7168b35..bed422f 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -755,6 +755,10 @@ extern const char kRecoveryComponentVersion[];
extern const char kComponentUpdaterState[];
extern const char kAttemptedToEnableAutoupdate[];
+#if defined(OS_WIN)
+extern const char kSwReporterExecuteTryCount[];
+#endif
+
extern const char kMediaGalleriesUniqueId[];
extern const char kMediaGalleriesRememberedGalleries[];
extern const char kMediaGalleriesLastScanTime[];
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index f6e76c0..6901d04 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -2713,9 +2713,7 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<histogram name="CloudPrint.XmppPingTry">
<owner>vitalybuka@chromium.org</owner>
- <summary>
- Number of tries before successfull ping. 99 means giving up.
- </summary>
+ <summary>Number of tries before successful ping. 99 means giving up.</summary>
</histogram>
<histogram name="Compositing.CopyFromSurfaceTime" units="ms">
@@ -28520,6 +28518,18 @@ Therefore, the affected-histogram name has to have at least one dot in it.
</summary>
</histogram>
+<histogram name="SoftwareReporter.ExitCode" enum="SwReporterExitCode">
+ <owner>mad@chromium.org</owner>
+ <summary>The exit code from the execution of the software reporter.</summary>
+</histogram>
+
+<histogram name="SoftwareReporter.Step" enum="SwReporterStep">
+ <owner>mad@chromium.org</owner>
+ <summary>
+ The registration and execution steps for the software reporter.
+ </summary>
+</histogram>
+
<histogram name="SpellCheck.SpellingService.Enabled" enum="BooleanEnabled">
<owner>groby@chromium.org</owner>
<owner>rlp@chromium.org</owner>
@@ -44838,6 +44848,21 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="3" label="Attempted"/>
</enum>
+<enum name="SwReporterExitCode" type="int">
+ <int value="0" label="Success / Found"/>
+ <int value="1" label="Failed"/>
+ <int value="2" label="Nothing Found"/>
+</enum>
+
+<enum name="SwReporterStep" type="int">
+ <int value="0" label="Explicit request"/>
+ <int value="1" label="Startup retry"/>
+ <int value="2" label="Retried too many times"/>
+ <int value="3" label="Start execution"/>
+ <int value="4" label="Failed to start"/>
+ <int value="5" label="Registry exit code"/>
+</enum>
+
<enum name="SyncAuthError" type="int">
<int value="0"
label="Number of times clients have encountered an Auth error."/>