Index: chrome/installer/setup/setup_main.cc |
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc |
index 2bee9267894eb062516d566cd97f00a608851ed2..a4680b218e3fff80a9beae3f451f9c192ca5310d 100644 |
--- a/chrome/installer/setup/setup_main.cc |
+++ b/chrome/installer/setup/setup_main.cc |
@@ -19,6 +19,9 @@ |
#include "base/files/file_util.h" |
#include "base/files/scoped_temp_dir.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/metrics/histogram_base.h" |
+#include "base/metrics/histogram_persistence.h" |
+#include "base/metrics/persistent_memory_allocator.h" |
#include "base/path_service.h" |
#include "base/process/launch.h" |
#include "base/process/memory.h" |
@@ -1627,6 +1630,23 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, |
if (!installer::IsProcessorSupported()) |
return installer::CPU_NOT_SUPPORTED; |
+ // Create a persistent space for any histograms that can be reported later |
+ // by the Chrome process. The "id" is a timestamp so that Chrome can tell |
+ // if it has already reported these metrics. No name is given so no internal |
+ // histograms are created or managed; such would be pointless because they |
+ // would have to be created on the heap and thus never be persisted for |
+ // reporting. |
+ uint32_t allocator_id = static_cast<uint32_t>(base::Time::Now().ToTimeT()); |
+ base::SetPersistentHistogramMemoryAllocator( |
+ new base::LocalPersistentMemoryAllocator(1 << 20, // 1 MiB |
+ allocator_id, |
+ std::string())); |
+ |
+ // Now that histograms have a persistent place to be stored, the allocator |
+ // itself can create histograms within that space. |
+ base::GetPersistentHistogramMemoryAllocator() |
+ ->CreateHistograms(google_update::kSetupHistogramAllocatorName); |
+ |
// The exit manager is in charge of calling the dtors of singletons. |
base::AtExitManager exit_manager; |
base::CommandLine::Init(0, NULL); |
@@ -1776,6 +1796,34 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, |
return_code = InstallUtil::GetInstallReturnCode(install_status); |
} |
+ // Save all the persistent histograms to a single file on disk for reading |
+ // by the browser so it can be reported. For atomicity, first write to a |
+ // temporary file and then rename it. The ImportantFileWriter would be good |
+ // for this except it supports only std::string for its data. |
+ base::FilePath file_path = installer_state.target_path().AppendASCII( |
+ google_update::kSetupHistogramAllocatorName); |
+ base::FilePath tmp_file_path; |
+ base::DeleteFile(file_path, false); |
+ if (base::CreateTemporaryFileInDir(file_path.DirName(), &tmp_file_path)) { |
+ base::File histograms(tmp_file_path, |
+ base::File::FLAG_CREATE | base::File::FLAG_WRITE); |
+ if (histograms.IsValid()) { |
+ base::PersistentMemoryAllocator* alloc = |
+ base::GetPersistentHistogramMemoryAllocator(); |
+ int used = static_cast<int>(alloc->used()); |
+ if (histograms.Write(0, static_cast<const char*>(alloc->data()), |
+ used) == used && |
+ histograms.Flush()) { |
+ histograms.Close(); |
+ if (base::ReplaceFile(tmp_file_path, file_path, nullptr)) { |
+ VLOG(1) << "Persistent histograms saved in file: " |
+ << file_path.AsUTF8Unsafe(); |
+ } |
+ } |
+ } |
+ } |
+ base::DeleteFile(tmp_file_path, false); |
+ |
VLOG(1) << "Installation complete, returning: " << return_code; |
return return_code; |