Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(567)

Side by Side Diff: chrome/browser/metrics/chrome_setup_metrics_provider.cc

Issue 1537743006: Persist setup metrics and have Chrome report them during UMA upload. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@shared-histograms
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/metrics/chrome_setup_metrics_provider.h"
6
7 #include <vector>
8
9 #include "base/command_line.h"
10 #include "base/files/file.h"
11 #include "base/files/file_util.h"
12 #include "base/files/memory_mapped_file.h"
13 #include "base/logging.h"
14 #include "base/metrics/histogram_base.h"
15 #include "base/metrics/persistent_memory_allocator.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/threading/worker_pool.h"
18 #include "base/time/time.h"
19 #include "chrome/installer/util/google_update_constants.h"
20 #include "components/metrics/metrics_pref_names.h"
21 #include "components/metrics/metrics_service.h"
22
23
24 ChromeSetupMetricsProvider::ChromeSetupMetricsProvider(
25 metrics::MetricsService* metrics_service,
26 PrefService* local_state)
27 : metrics_found_(0),
28 metrics_service_(metrics_service),
29 pref_service_(local_state),
30 program_directory_(base::CommandLine::ForCurrentProcess()->GetProgram()
31 .DirName()) {
32 // Don't do any further actions if metrics_service is not valid (for testing).
33 if (!metrics_service_)
34 return;
35
36 // Start a background check for pending setup metrics so it can be uploaded
37 // during the initial report.
38 bool posted = base::WorkerPool::PostTask(
39 FROM_HERE,
40 base::Bind(&ChromeSetupMetricsProvider::CheckForSetupMetrics,
Alexei Svitkine (slow) 2015/12/21 16:54:53 In Chromium code, it's best practice to not have t
bcwhite 2015/12/22 12:51:30 Okay. I'm rewriting this to support multiple file
41 base::Unretained(this)),
42 false);
43 DCHECK(posted);
44 }
45
46 ChromeSetupMetricsProvider::~ChromeSetupMetricsProvider() {
47 // Destruction of this object can lead to failures because of a task
48 // posted on the Worker Pool or because the owned Memory Allocator has
49 // been passed to the Metrics Service. Both cases can only occur if
50 // a Metrics Service has been provided (i.e. not during testing).
51 if (metrics_service_) {
52 NOTREACHED();
53 // Removing the allocator may not be sufficient to avoid a crash (some
54 // Histogram could still be pointing to the memory) but it's the best
55 // that can be done.
56 if (metrics_allocator_)
57 metrics_service_->RemovePersistentMemorySegment(metrics_allocator_.get());
58 }
59 }
60
61 void ChromeSetupMetricsProvider::OnDidCreateMetricsLog() {
62 if (metrics_allocator_) {
63 // If an allocator has been created then the previous log collected all
64 // the metrics. The allocator can be released and the preferences updated
65 // to make sure it isn't reported again.
66 pref_service_->SetInt64(metrics::prefs::kSetupMetricsLastSeen,
67 base::Time::Now().ToInternalValue());
68 if (metrics_service_)
69 metrics_service_->RemovePersistentMemorySegment(metrics_allocator_.get());
Alexei Svitkine (slow) 2015/12/21 16:54:53 Can this functionality be done by a different help
bcwhite 2015/12/22 12:51:30 Not really. MetricsService is what owns the HSM a
70 metrics_allocator_.reset();
71 metrics_found_.store(false);
72 return;
73 }
74
75 if (metrics_found_.load(std::memory_order_acquire)) { // ACQ metrics_file
76 // A new file of setup metrics has been found. Attach to it and add it to
77 // the list of persistent allocators that need to have metrics reported.
78 DCHECK(metrics_file_);
79 if (base::FilePersistentMemoryAllocator::IsFileAcceptable(*metrics_file_)) {
80 metrics_allocator_.reset(new base::FilePersistentMemoryAllocator(
81 metrics_file_.release(), 0, std::string()));
82 if (!metrics_allocator_->IsCorrupt()) {
83 if (metrics_service_) {
84 metrics_service_->AddPersistentMemorySegment(
85 metrics_allocator_.get());
86 }
87 return;
88 }
89 }
90 // Something is fundamentally wrong with the file. Ignore it.
91 LOG(ERROR) << "Setup metrics file \""
92 << GetSetupMetricsFile().AsUTF8Unsafe()
93 << "\" is not valid -- ignored.";
94 metrics_allocator_.reset();
95 pref_service_->SetInt64(metrics::prefs::kSetupMetricsLastSeen,
96 base::Time::Now().ToInternalValue());
97 return;
98 }
99
100 // Don't do any further actions if metrics_service is not valid (for testing).
101 if (!metrics_service_)
102 return;
103
104 // Nothing else is going on so schedule a check to see if there are new
105 // setup metrics to load. If so, they will be reported during the next
106 // collection run after this one. The check is run off of the worker-
107 // pool so as to not cause delays on the main UI thread (which is currently
108 // where metric collection is done).
109 bool posted = base::WorkerPool::PostTask(
110 FROM_HERE,
111 base::Bind(&ChromeSetupMetricsProvider::CheckForSetupMetrics,
112 base::Unretained(this)),
113 false);
114 DCHECK(posted);
115 }
116
117 base::FilePath ChromeSetupMetricsProvider::GetSetupMetricsFile() {
118 return program_directory_.AppendASCII(
119 google_update::kSetupHistogramAllocatorName);
120 }
121
122 void ChromeSetupMetricsProvider::CheckForSetupMetrics() {
123 DCHECK(!metrics_found_.load());
124 DCHECK(!metrics_file_);
125
126 base::File::Info info;
127 if (!base::GetFileInfo(GetSetupMetricsFile(), &info) ||
128 info.is_directory || info.size == 0) {
129 return;
130 }
131
132 const base::Time last_seen = base::Time::FromInternalValue(
133 pref_service_->GetInt64(metrics::prefs::kSetupMetricsLastSeen));
134 if (last_seen >= info.last_modified)
135 return;
136
137 // A new file of setup metrics has been found. Map it into memory.
138 metrics_file_.reset(new base::MemoryMappedFile());
139 metrics_file_->Initialize(GetSetupMetricsFile());
140
141 // Tell main thread that metrics have been found.
142 metrics_found_.store(true, std::memory_order_release); // REL metrics_file
143 }
144
145 void ChromeSetupMetricsProvider::SetProgramDirectory(
146 const base::FilePath& dir) {
147 program_directory_ = dir;
148 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698