Revert r196089 "Add default values for Latin script font prefs."
[chromium-blink-merge.git] / chrome / browser / metrics / metrics_service.h
blob365e857bfd403646bf4f8c0ef9c90f8dfe260800
1 // Copyright (c) 2012 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.
5 // This file defines a service that collects information about the user
6 // experience in order to help improve future versions of the app.
8 #ifndef CHROME_BROWSER_METRICS_METRICS_SERVICE_H_
9 #define CHROME_BROWSER_METRICS_METRICS_SERVICE_H_
11 #include <map>
12 #include <string>
13 #include <vector>
15 #include "base/basictypes.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/metrics/field_trial.h"
20 #include "base/process_util.h"
21 #include "chrome/browser/metrics/metrics_log.h"
22 #include "chrome/browser/metrics/tracking_synchronizer_observer.h"
23 #include "chrome/common/metrics/metrics_service_base.h"
24 #include "chrome/installer/util/google_update_settings.h"
25 #include "content/public/browser/browser_child_process_observer.h"
26 #include "content/public/browser/notification_observer.h"
27 #include "content/public/browser/notification_registrar.h"
28 #include "content/public/browser/user_metrics.h"
29 #include "net/url_request/url_fetcher_delegate.h"
31 #if defined(OS_CHROMEOS)
32 #include "chrome/browser/chromeos/external_metrics.h"
33 #endif
35 class MetricsReportingScheduler;
36 class PrefService;
37 class PrefRegistrySimple;
38 class Profile;
39 class TemplateURLService;
41 namespace base {
42 class DictionaryValue;
43 class MessageLoopProxy;
46 namespace content {
47 class RenderProcessHost;
50 namespace extensions {
51 class ExtensionDownloader;
52 class ManifestFetchData;
55 namespace net {
56 class URLFetcher;
59 namespace prerender {
60 bool IsOmniboxEnabled(Profile* profile);
63 namespace tracked_objects {
64 struct ProcessDataSnapshot;
67 namespace webkit {
68 struct WebPluginInfo;
71 class MetricsService
72 : public chrome_browser_metrics::TrackingSynchronizerObserver,
73 public content::BrowserChildProcessObserver,
74 public content::NotificationObserver,
75 public net::URLFetcherDelegate,
76 public MetricsServiceBase {
77 public:
78 MetricsService();
79 virtual ~MetricsService();
81 // Starts the metrics system, turning on recording and uploading of metrics.
82 // Should be called when starting up with metrics enabled, or when metrics
83 // are turned on.
84 void Start();
86 // Starts the metrics system in a special test-only mode. Metrics won't ever
87 // be uploaded or persisted in this mode, but metrics will be recorded in
88 // memory.
89 void StartRecordingForTests();
91 // Shuts down the metrics system. Should be called at shutdown, or if metrics
92 // are turned off.
93 void Stop();
95 // Enable/disable transmission of accumulated logs and crash reports (dumps).
96 // Calling Start() automatically enables reporting, but sending is
97 // asyncronous so this can be called immediately after Start() to prevent
98 // any uploading.
99 void EnableReporting();
100 void DisableReporting();
102 // Returns the client ID for this client, or the empty string if metrics
103 // recording is not currently running.
104 std::string GetClientId();
106 // Returns the preferred entropy provider used to seed persistent activities
107 // based on whether or not metrics reporting will be permitted on this client.
108 // The caller must determine if metrics reporting will be enabled for this
109 // client and pass that state in as |reporting_will_be_enabled|.
111 // If |reporting_will_be_enabled| is true, this method returns an entropy
112 // provider that has a high source of entropy, partially based on the client
113 // ID. Otherwise, an entropy provider that is based on a low entropy source
114 // is returned.
116 // Note that this reporting state can not be checked by reporting_active()
117 // because this method may need to be called before the MetricsService needs
118 // to be started.
119 scoped_ptr<const base::FieldTrial::EntropyProvider> CreateEntropyProvider(
120 bool reporting_will_be_enabled);
122 // Force the client ID to be generated. This is useful in case it's needed
123 // before recording.
124 void ForceClientIdCreation();
126 // At startup, prefs needs to be called with a list of all the pref names and
127 // types we'll be using.
128 static void RegisterPrefs(PrefRegistrySimple* registry);
130 // Set up notifications which indicate that a user is performing work. This is
131 // useful to allow some features to sleep, until the machine becomes active,
132 // such as precluding UMA uploads unless there was recent activity.
133 static void SetUpNotifications(content::NotificationRegistrar* registrar,
134 content::NotificationObserver* observer);
136 // Implementation of content::BrowserChildProcessObserver
137 virtual void BrowserChildProcessHostConnected(
138 const content::ChildProcessData& data) OVERRIDE;
139 virtual void BrowserChildProcessCrashed(
140 const content::ChildProcessData& data) OVERRIDE;
141 virtual void BrowserChildProcessInstanceCreated(
142 const content::ChildProcessData& data) OVERRIDE;
144 // Implementation of content::NotificationObserver
145 virtual void Observe(int type,
146 const content::NotificationSource& source,
147 const content::NotificationDetails& details) OVERRIDE;
149 // Invoked when we get a WM_SESSIONEND. This places a value in prefs that is
150 // reset when RecordCompletedSessionEnd is invoked.
151 void RecordStartOfSessionEnd();
153 // This should be called when the application is shutting down. It records
154 // that session end was successful.
155 void RecordCompletedSessionEnd();
157 #if defined(OS_ANDROID) || defined(OS_IOS)
158 // Called when the application is going into background mode.
159 void OnAppEnterBackground();
161 // Called when the application is coming out of background mode.
162 void OnAppEnterForeground();
163 #else
164 // Set the dirty flag, which will require a later call to LogCleanShutdown().
165 static void LogNeedForCleanShutdown();
166 #endif // defined(OS_ANDROID) || defined(OS_IOS)
168 // Saves in the preferences if the crash report registration was successful.
169 // This count is eventually send via UMA logs.
170 void RecordBreakpadRegistration(bool success);
172 // Saves in the preferences if the browser is running under a debugger.
173 // This count is eventually send via UMA logs.
174 void RecordBreakpadHasDebugger(bool has_debugger);
176 // Save any unsent logs into a persistent store in a pref. We always do this
177 // at shutdown, but we can do it as we reduce the list as well.
178 void StoreUnsentLogs();
180 #if defined(OS_CHROMEOS)
181 // Start the external metrics service, which collects metrics from Chrome OS
182 // and passes them to UMA.
183 void StartExternalMetrics();
185 // Records a Chrome OS crash.
186 void LogChromeOSCrash(const std::string &crash_type);
187 #endif
189 bool recording_active() const;
190 bool reporting_active() const;
192 void LogPluginLoadingError(const base::FilePath& plugin_path);
194 // Redundant test to ensure that we are notified of a clean exit.
195 // This value should be true when process has completed shutdown.
196 static bool UmaMetricsProperlyShutdown();
198 private:
199 // The MetricsService has a lifecycle that is stored as a state.
200 // See metrics_service.cc for description of this lifecycle.
201 enum State {
202 INITIALIZED, // Constructor was called.
203 INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to complete.
204 INIT_TASK_DONE, // Waiting for timer to send initial log.
205 INITIAL_LOG_READY, // Initial log generated, and waiting for reply.
206 SENDING_OLD_LOGS, // Sending unsent logs from previous session.
207 SENDING_CURRENT_LOGS, // Sending standard current logs as they acrue.
210 enum ShutdownCleanliness {
211 CLEANLY_SHUTDOWN = 0xdeadbeef,
212 NEED_TO_SHUTDOWN = ~CLEANLY_SHUTDOWN
215 // Designates which entropy source was returned from this MetricsService.
216 // This is used for testing to validate that we return the correct source
217 // depending on the state of the service.
218 enum EntropySourceReturned {
219 LAST_ENTROPY_NONE,
220 LAST_ENTROPY_LOW,
221 LAST_ENTROPY_HIGH,
224 struct ChildProcessStats;
226 // First part of the init task. Called on the FILE thread to load hardware
227 // class information.
228 static void InitTaskGetHardwareClass(base::WeakPtr<MetricsService> self,
229 base::MessageLoopProxy* target_loop);
231 // Callback from InitTaskGetHardwareClass() that continues the init task by
232 // loading plugin information.
233 void OnInitTaskGotHardwareClass(const std::string& hardware_class);
235 // Callback from PluginService::GetPlugins() that continues the init task by
236 // launching a task to gather Google Update statistics.
237 void OnInitTaskGotPluginInfo(
238 const std::vector<webkit::WebPluginInfo>& plugins);
240 // Task launched by OnInitTaskGotPluginInfo() that continues the init task by
241 // loading Google Update statistics. Called on a blocking pool thread.
242 static void InitTaskGetGoogleUpdateData(base::WeakPtr<MetricsService> self,
243 base::MessageLoopProxy* target_loop);
245 // Callback from InitTaskGetGoogleUpdateData() that continues the init task by
246 // loading profiler data.
247 void OnInitTaskGotGoogleUpdateData(
248 const GoogleUpdateMetrics& google_update_metrics);
250 void OnUserAction(const std::string& action);
252 // TrackingSynchronizerObserver:
253 virtual void ReceivedProfilerData(
254 const tracked_objects::ProcessDataSnapshot& process_data,
255 int process_type) OVERRIDE;
256 // Callback that moves the state to INIT_TASK_DONE.
257 virtual void FinishedReceivingProfilerData() OVERRIDE;
259 // Returns the low entropy source for this client. This is a random value
260 // that is non-identifying amongst browser clients. This method will
261 // generate the entropy source value if it has not been called before.
262 int GetLowEntropySource();
264 // Returns the first entropy source that was returned by this service since
265 // start up, or NONE if neither was returned yet. This is exposed for testing
266 // only.
267 EntropySourceReturned entropy_source_returned() const {
268 return entropy_source_returned_;
271 // When we start a new version of Chromium (different from our last run), we
272 // need to discard the old crash stats so that we don't attribute crashes etc.
273 // in the old version to the current version (via current logs).
274 // Without this, a common reason to finally start a new version is to crash
275 // the old version (after an autoupdate has arrived), and so we'd bias
276 // initial results towards showing crashes :-(.
277 static void DiscardOldStabilityStats(PrefService* local_state);
279 // Turns recording on or off.
280 // DisableRecording() also forces a persistent save of logging state (if
281 // anything has been recorded, or transmitted).
282 void EnableRecording();
283 void DisableRecording();
285 // If in_idle is true, sets idle_since_last_transmission to true.
286 // If in_idle is false and idle_since_last_transmission_ is true, sets
287 // idle_since_last_transmission to false and starts the timer (provided
288 // starting the timer is permitted).
289 void HandleIdleSinceLastTransmission(bool in_idle);
291 // Set up client ID, session ID, etc.
292 void InitializeMetricsState();
294 // Generates a new client ID to use to identify self to metrics server.
295 static std::string GenerateClientID();
297 // Schedule the next save of LocalState information. This is called
298 // automatically by the task that performs each save to schedule the next one.
299 void ScheduleNextStateSave();
301 // Save the LocalState information immediately. This should not be called by
302 // anybody other than the scheduler to avoid doing too many writes. When you
303 // make a change, call ScheduleNextStateSave() instead.
304 void SaveLocalState();
306 // Opens a new log for recording user experience metrics.
307 void OpenNewLog();
309 // Closes out the current log after adding any last information.
310 void CloseCurrentLog();
312 // Pushes the text of the current and staged logs into persistent storage.
313 // Called when Chrome shuts down.
314 void PushPendingLogsToPersistentStorage();
316 // Ensures that scheduler is running, assuming the current settings are such
317 // that metrics should be reported. If not, this is a no-op.
318 void StartSchedulerIfNecessary();
320 // Starts the process of uploading metrics data.
321 void StartScheduledUpload();
323 // Starts collecting any data that should be added to a log just before it is
324 // closed.
325 void StartFinalLogInfoCollection();
326 // Callbacks for various stages of final log info collection. Do not call
327 // these directly.
328 void OnMemoryDetailCollectionDone();
329 void OnHistogramSynchronizationDone();
330 void OnFinalLogInfoCollectionDone();
332 // Either closes the current log or creates and closes the initial log
333 // (depending on |state_|), and stages it for upload.
334 void StageNewLog();
336 // Record stats, client ID, Session ID, etc. in a special "first" log.
337 void PrepareInitialLog();
339 // Uploads the currently staged log (which must be non-null).
340 void SendStagedLog();
342 // Prepared the staged log to be passed to the server. Upon return,
343 // current_fetch_ should be reset with its upload data set to a compressed
344 // copy of the staged log.
345 void PrepareFetchWithStagedLog();
347 // Implementation of net::URLFetcherDelegate. Called after transmission
348 // completes (either successfully or with failure).
349 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
351 // Records a window-related notification. |window_or_tab| is either a pointer
352 // to a WebContents (for a tab) or a Browser (for a window).
353 void LogWindowOrTabChange(int type, uintptr_t window_or_tab);
355 // Reads, increments and then sets the specified integer preference.
356 void IncrementPrefValue(const char* path);
358 // Reads, increments and then sets the specified long preference that is
359 // stored as a string.
360 void IncrementLongPrefsValue(const char* path);
362 // Records a renderer process crash.
363 void LogRendererCrash(content::RenderProcessHost* host,
364 base::TerminationStatus status,
365 int exit_code);
367 // Records a renderer process hang.
368 void LogRendererHang();
370 // Records that the browser was shut down cleanly.
371 void LogCleanShutdown();
373 // Returns reference to ChildProcessStats corresponding to |data|.
374 ChildProcessStats& GetChildProcessStats(
375 const content::ChildProcessData& data);
377 // Logs the number of keywords.
378 void LogKeywordCount(size_t keyword_count);
380 // Saves plugin-related updates from the in-object buffer to Local State
381 // for retrieval next time we send a Profile log (generally next launch).
382 void RecordPluginChanges(PrefService* pref);
384 // Records state that should be periodically saved, like uptime and
385 // buffered plugin stability statistics.
386 void RecordCurrentState(PrefService* pref);
388 // Logs the initiation of a page load
389 void LogLoadStarted();
391 // Records a page load notification.
392 void LogLoadComplete(int type,
393 const content::NotificationSource& source,
394 const content::NotificationDetails& details);
396 // Checks whether a notification can be logged.
397 bool CanLogNotification();
399 // Sets the value of the specified path in prefs and schedules a save.
400 void RecordBooleanPrefValue(const char* path, bool value);
402 // Returns true if process of type |type| should be counted as a plugin
403 // process, and false otherwise.
404 static bool IsPluginProcess(int process_type);
406 content::ActionCallback action_callback_;
408 content::NotificationRegistrar registrar_;
410 // Indicate whether recording and reporting are currently happening.
411 // These should not be set directly, but by calling SetRecording and
412 // SetReporting.
413 bool recording_active_;
414 bool reporting_active_;
416 // Indicate whether test mode is enabled, where the initial log should never
417 // be cut, and logs are neither persisted nor uploaded.
418 bool test_mode_active_;
420 // The progession of states made by the browser are recorded in the following
421 // state.
422 State state_;
424 // Chrome OS hardware class (e.g., hardware qualification ID). This
425 // class identifies the configured system components such as CPU,
426 // WiFi adapter, etc. For non Chrome OS hosts, this will be an
427 // empty string.
428 std::string hardware_class_;
430 // The list of plugins which was retrieved on the file thread.
431 std::vector<webkit::WebPluginInfo> plugins_;
433 // Google Update statistics, which were retrieved on a blocking pool thread.
434 GoogleUpdateMetrics google_update_metrics_;
436 // The initial log, used to record startup metrics.
437 scoped_ptr<MetricsLog> initial_log_;
439 // The outstanding transmission appears as a URL Fetch operation.
440 scoped_ptr<net::URLFetcher> current_fetch_;
442 // The TCP/UDP echo server to collect network connectivity stats.
443 std::string network_stats_server_;
445 // The HTTP pipelining test server.
446 std::string http_pipelining_test_server_;
448 // The identifier that's sent to the server with the log reports.
449 std::string client_id_;
451 // The non-identifying low entropy source value.
452 int low_entropy_source_;
454 // Whether the MetricsService object has received any notifications since
455 // the last time a transmission was sent.
456 bool idle_since_last_transmission_;
458 // A number that identifies the how many times the app has been launched.
459 int session_id_;
461 // Maps WebContentses (corresponding to tabs) or Browsers (corresponding to
462 // Windows) to a unique integer that we will use to identify them.
463 // |next_window_id_| is used to track which IDs we have used so far.
464 typedef std::map<uintptr_t, int> WindowMap;
465 WindowMap window_map_;
466 int next_window_id_;
468 // Buffer of child process notifications for quick access.
469 std::map<string16, ChildProcessStats> child_process_stats_buffer_;
471 // Weak pointers factory used to post task on different threads. All weak
472 // pointers managed by this factory have the same lifetime as MetricsService.
473 base::WeakPtrFactory<MetricsService> self_ptr_factory_;
475 // Weak pointers factory used for saving state. All weak pointers managed by
476 // this factory are invalidated in ScheduleNextStateSave.
477 base::WeakPtrFactory<MetricsService> state_saver_factory_;
479 // Dictionary containing all the profile specific metrics. This is set
480 // at creation time from the prefs.
481 scoped_ptr<base::DictionaryValue> profile_dictionary_;
483 // The scheduler for determining when uploads should happen.
484 scoped_ptr<MetricsReportingScheduler> scheduler_;
486 // Indicates that an asynchronous reporting step is running.
487 // This is used only for debugging.
488 bool waiting_for_asynchronous_reporting_step_;
490 #if defined(OS_CHROMEOS)
491 // The external metric service is used to log ChromeOS UMA events.
492 scoped_refptr<chromeos::ExternalMetrics> external_metrics_;
493 #endif
495 // The last entropy source returned by this service, used for testing.
496 EntropySourceReturned entropy_source_returned_;
498 // Reduntant marker to check that we completed our shutdown, and set the
499 // exited-cleanly bit in the prefs.
500 static ShutdownCleanliness clean_shutdown_status_;
502 FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, ClientIdCorrectlyFormatted);
503 FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, IsPluginProcess);
504 FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, LowEntropySource0NotReset);
505 FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest,
506 PermutedEntropyCacheClearedWhenLowEntropyReset);
507 FRIEND_TEST_ALL_PREFIXES(MetricsServiceBrowserTest,
508 CheckLowEntropySourceUsed);
509 FRIEND_TEST_ALL_PREFIXES(MetricsServiceReportingTest,
510 CheckHighEntropySourceUsed);
512 DISALLOW_COPY_AND_ASSIGN(MetricsService);
515 // This class limits and documents access to the IsMetricsReportingEnabled()
516 // method. Since the method is private, each user has to be explicitly declared
517 // as a 'friend' below.
518 class MetricsServiceHelper {
519 private:
520 friend bool prerender::IsOmniboxEnabled(Profile* profile);
521 friend class extensions::ExtensionDownloader;
522 friend class extensions::ManifestFetchData;
524 // Returns true if prefs::kMetricsReportingEnabled is set.
525 static bool IsMetricsReportingEnabled();
527 DISALLOW_IMPLICIT_CONSTRUCTORS(MetricsServiceHelper);
530 #endif // CHROME_BROWSER_METRICS_METRICS_SERVICE_H_