Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / metrics / metrics_service.h
1 // Copyright 2014 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 // This file defines a service that collects information about the user
6 // experience in order to help improve future versions of the app.
7
8 #ifndef COMPONENTS_METRICS_METRICS_SERVICE_H_
9 #define COMPONENTS_METRICS_METRICS_SERVICE_H_
10
11 #include <map>
12 #include <string>
13 #include <vector>
14
15 #include "base/basictypes.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/scoped_vector.h"
19 #include "base/memory/weak_ptr.h"
20 #include "base/metrics/field_trial.h"
21 #include "base/metrics/histogram_flattener.h"
22 #include "base/metrics/histogram_snapshot_manager.h"
23 #include "base/metrics/user_metrics.h"
24 #include "base/observer_list.h"
25 #include "base/strings/string16.h"
26 #include "base/threading/thread_checker.h"
27 #include "base/time/time.h"
28 #include "components/metrics/metrics_log.h"
29 #include "components/metrics/metrics_log_manager.h"
30 #include "components/metrics/metrics_provider.h"
31 #include "components/metrics/metrics_service_observer.h"
32 #include "components/variations/active_field_trials.h"
33
34 class MetricsReportingScheduler;
35 class PrefService;
36 class PrefRegistrySimple;
37
38 namespace base {
39 class DictionaryValue;
40 class HistogramSamples;
41 class MessageLoopProxy;
42 class PrefService;
43 }
44
45 namespace variations {
46 struct ActiveGroupId;
47 }
48
49 namespace metrics {
50 class MetricsLogUploader;
51 class MetricsServiceClient;
52 class MetricsStateManager;
53 }
54
55 namespace net {
56 class URLFetcher;
57 }
58
59 // A Field Trial and its selected group, which represent a particular
60 // Chrome configuration state. For example, the trial name could map to
61 // a preference name, and the group name could map to a preference value.
62 struct SyntheticTrialGroup {
63  public:
64   ~SyntheticTrialGroup();
65
66   variations::ActiveGroupId id;
67   base::TimeTicks start_time;
68
69  private:
70   // Synthetic field trial users:
71   friend class MetricsServiceAccessor;
72   friend class MetricsService;
73   FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, RegisterSyntheticTrial);
74
75   // This constructor is private specifically so as to control which code is
76   // able to access it. New code that wishes to use it should be added as a
77   // friend class.
78   SyntheticTrialGroup(uint32 trial, uint32 group);
79 };
80
81 // See metrics_service.cc for a detailed description.
82 class MetricsService : public base::HistogramFlattener {
83  public:
84   // The execution phase of the browser.
85   enum ExecutionPhase {
86     UNINITIALIZED_PHASE = 0,
87     START_METRICS_RECORDING = 100,
88     CREATE_PROFILE = 200,
89     STARTUP_TIMEBOMB_ARM = 300,
90     THREAD_WATCHER_START = 400,
91     MAIN_MESSAGE_LOOP_RUN = 500,
92     SHUTDOWN_TIMEBOMB_ARM = 600,
93     SHUTDOWN_COMPLETE = 700,
94   };
95
96   // Creates the MetricsService with the given |state_manager|, |client|, and
97   // |local_state|.  Does not take ownership of the paramaters; instead stores
98   // a weak pointer to each. Caller should ensure that the parameters are valid
99   // for the lifetime of this class.
100   MetricsService(metrics::MetricsStateManager* state_manager,
101                  metrics::MetricsServiceClient* client,
102                  PrefService* local_state);
103   virtual ~MetricsService();
104
105   // Initializes metrics recording state. Updates various bookkeeping values in
106   // prefs and sets up the scheduler. This is a separate function rather than
107   // being done by the constructor so that field trials could be created before
108   // this is run.
109   void InitializeMetricsRecordingState();
110
111   // Starts the metrics system, turning on recording and uploading of metrics.
112   // Should be called when starting up with metrics enabled, or when metrics
113   // are turned on.
114   void Start();
115
116   // If metrics reporting is enabled, starts the metrics service. Returns
117   // whether the metrics service was started.
118   bool StartIfMetricsReportingEnabled();
119
120   // Starts the metrics system in a special test-only mode. Metrics won't ever
121   // be uploaded or persisted in this mode, but metrics will be recorded in
122   // memory.
123   void StartRecordingForTests();
124
125   // Shuts down the metrics system. Should be called at shutdown, or if metrics
126   // are turned off.
127   void Stop();
128
129   // Enable/disable transmission of accumulated logs and crash reports (dumps).
130   // Calling Start() automatically enables reporting, but sending is
131   // asyncronous so this can be called immediately after Start() to prevent
132   // any uploading.
133   void EnableReporting();
134   void DisableReporting();
135
136   // Returns the client ID for this client, or the empty string if metrics
137   // recording is not currently running.
138   std::string GetClientId();
139
140   // Returns the install date of the application, in seconds since the epoch.
141   int64 GetInstallDate();
142
143   // Returns the preferred entropy provider used to seed persistent activities
144   // based on whether or not metrics reporting will be permitted on this client.
145   //
146   // If metrics reporting is enabled, this method returns an entropy provider
147   // that has a high source of entropy, partially based on the client ID.
148   // Otherwise, it returns an entropy provider that is based on a low entropy
149   // source.
150   scoped_ptr<const base::FieldTrial::EntropyProvider> CreateEntropyProvider();
151
152   // At startup, prefs needs to be called with a list of all the pref names and
153   // types we'll be using.
154   static void RegisterPrefs(PrefRegistrySimple* registry);
155
156   // HistogramFlattener:
157   virtual void RecordDelta(const base::HistogramBase& histogram,
158                            const base::HistogramSamples& snapshot) OVERRIDE;
159   virtual void InconsistencyDetected(
160       base::HistogramBase::Inconsistency problem) OVERRIDE;
161   virtual void UniqueInconsistencyDetected(
162       base::HistogramBase::Inconsistency problem) OVERRIDE;
163   virtual void InconsistencyDetectedInLoggedCount(int amount) OVERRIDE;
164
165   // This should be called when the application is not idle, i.e. the user seems
166   // to be interacting with the application.
167   void OnApplicationNotIdle();
168
169   // Invoked when we get a WM_SESSIONEND. This places a value in prefs that is
170   // reset when RecordCompletedSessionEnd is invoked.
171   void RecordStartOfSessionEnd();
172
173   // This should be called when the application is shutting down. It records
174   // that session end was successful.
175   void RecordCompletedSessionEnd();
176
177 #if defined(OS_ANDROID) || defined(OS_IOS)
178   // Called when the application is going into background mode.
179   void OnAppEnterBackground();
180
181   // Called when the application is coming out of background mode.
182   void OnAppEnterForeground();
183 #else
184   // Set the dirty flag, which will require a later call to LogCleanShutdown().
185   static void LogNeedForCleanShutdown(PrefService* local_state);
186 #endif  // defined(OS_ANDROID) || defined(OS_IOS)
187
188   static void SetExecutionPhase(ExecutionPhase execution_phase,
189                                 PrefService* local_state);
190
191   // Saves in the preferences if the crash report registration was successful.
192   // This count is eventually send via UMA logs.
193   void RecordBreakpadRegistration(bool success);
194
195   // Saves in the preferences if the browser is running under a debugger.
196   // This count is eventually send via UMA logs.
197   void RecordBreakpadHasDebugger(bool has_debugger);
198
199   bool recording_active() const;
200   bool reporting_active() const;
201
202   // Redundant test to ensure that we are notified of a clean exit.
203   // This value should be true when process has completed shutdown.
204   static bool UmaMetricsProperlyShutdown();
205
206   // Registers a field trial name and group to be used to annotate a UMA report
207   // with a particular Chrome configuration state. A UMA report will be
208   // annotated with this trial group if and only if all events in the report
209   // were created after the trial is registered. Only one group name may be
210   // registered at a time for a given trial_name. Only the last group name that
211   // is registered for a given trial name will be recorded. The values passed
212   // in must not correspond to any real field trial in the code.
213   // To use this method, SyntheticTrialGroup should friend your class.
214   void RegisterSyntheticFieldTrial(const SyntheticTrialGroup& trial_group);
215
216   // Register the specified |provider| to provide additional metrics into the
217   // UMA log. Should be called during MetricsService initialization only.
218   void RegisterMetricsProvider(scoped_ptr<metrics::MetricsProvider> provider);
219
220   // Check if this install was cloned or imaged from another machine. If a
221   // clone is detected, reset the client id and low entropy source. This
222   // should not be called more than once.
223   void CheckForClonedInstall(
224       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
225
226  protected:
227   // Exposed for testing.
228   metrics::MetricsLogManager* log_manager() { return &log_manager_; }
229
230  private:
231   // The MetricsService has a lifecycle that is stored as a state.
232   // See metrics_service.cc for description of this lifecycle.
233   enum State {
234     INITIALIZED,                    // Constructor was called.
235     INIT_TASK_SCHEDULED,            // Waiting for deferred init tasks to
236                                     // complete.
237     INIT_TASK_DONE,                 // Waiting for timer to send initial log.
238     SENDING_INITIAL_STABILITY_LOG,  // Initial stability log being sent.
239     SENDING_INITIAL_METRICS_LOG,    // Initial metrics log being sent.
240     SENDING_OLD_LOGS,               // Sending unsent logs from last session.
241     SENDING_CURRENT_LOGS,           // Sending ongoing logs as they accrue.
242   };
243
244   enum ShutdownCleanliness {
245     CLEANLY_SHUTDOWN = 0xdeadbeef,
246     NEED_TO_SHUTDOWN = ~CLEANLY_SHUTDOWN
247   };
248
249   typedef std::vector<SyntheticTrialGroup> SyntheticTrialGroups;
250
251   // Calls into the client to start metrics gathering.
252   void StartGatheringMetrics();
253
254   // Callback that moves the state to INIT_TASK_DONE. When this is called, the
255   // state should be INIT_TASK_SCHEDULED.
256   void FinishedGatheringInitialMetrics();
257
258   void OnUserAction(const std::string& action);
259
260   // Get the amount of uptime since this process started and since the last
261   // call to this function.  Also updates the cumulative uptime metric (stored
262   // as a pref) for uninstall.  Uptimes are measured using TimeTicks, which
263   // guarantees that it is monotonic and does not jump if the user changes
264   // his/her clock.  The TimeTicks implementation also makes the clock not
265   // count time the computer is suspended.
266   void GetUptimes(PrefService* pref,
267                   base::TimeDelta* incremental_uptime,
268                   base::TimeDelta* uptime);
269
270   // Turns recording on or off.
271   // DisableRecording() also forces a persistent save of logging state (if
272   // anything has been recorded, or transmitted).
273   void EnableRecording();
274   void DisableRecording();
275
276   // If in_idle is true, sets idle_since_last_transmission to true.
277   // If in_idle is false and idle_since_last_transmission_ is true, sets
278   // idle_since_last_transmission to false and starts the timer (provided
279   // starting the timer is permitted).
280   void HandleIdleSinceLastTransmission(bool in_idle);
281
282   // Set up client ID, session ID, etc.
283   void InitializeMetricsState();
284
285   // Registers/unregisters |observer| to receive MetricsLog notifications.
286   void AddObserver(MetricsServiceObserver* observer);
287   void RemoveObserver(MetricsServiceObserver* observer);
288   void NotifyOnDidCreateMetricsLog();
289
290   // Schedule the next save of LocalState information.  This is called
291   // automatically by the task that performs each save to schedule the next one.
292   void ScheduleNextStateSave();
293
294   // Save the LocalState information immediately. This should not be called by
295   // anybody other than the scheduler to avoid doing too many writes. When you
296   // make a change, call ScheduleNextStateSave() instead.
297   void SaveLocalState();
298
299   // Opens a new log for recording user experience metrics.
300   void OpenNewLog();
301
302   // Closes out the current log after adding any last information.
303   void CloseCurrentLog();
304
305   // Pushes the text of the current and staged logs into persistent storage.
306   // Called when Chrome shuts down.
307   void PushPendingLogsToPersistentStorage();
308
309   // Ensures that scheduler is running, assuming the current settings are such
310   // that metrics should be reported. If not, this is a no-op.
311   void StartSchedulerIfNecessary();
312
313   // Starts the process of uploading metrics data.
314   void StartScheduledUpload();
315
316   // Called by the client when final log info collection is complete.
317   void OnFinalLogInfoCollectionDone();
318
319   // Either closes the current log or creates and closes the initial log
320   // (depending on |state_|), and stages it for upload.
321   void StageNewLog();
322
323   // Prepares the initial stability log, which is only logged when the previous
324   // run of Chrome crashed.  This log contains any stability metrics left over
325   // from that previous run, and only these stability metrics.  It uses the
326   // system profile from the previous session.
327   void PrepareInitialStabilityLog();
328
329   // Prepares the initial metrics log, which includes startup histograms and
330   // profiler data, as well as incremental stability-related metrics.
331   void PrepareInitialMetricsLog();
332
333   // Uploads the currently staged log (which must be non-null).
334   void SendStagedLog();
335
336   // Called after transmission completes (either successfully or with failure).
337   void OnLogUploadComplete(int response_code);
338
339   // Reads, increments and then sets the specified integer preference.
340   void IncrementPrefValue(const char* path);
341
342   // Reads, increments and then sets the specified long preference that is
343   // stored as a string.
344   void IncrementLongPrefsValue(const char* path);
345
346   // Records that the browser was shut down cleanly.
347   void LogCleanShutdown();
348
349   // Records state that should be periodically saved, like uptime and
350   // buffered plugin stability statistics.
351   void RecordCurrentState(PrefService* pref);
352
353   // Checks whether events should currently be logged.
354   bool ShouldLogEvents();
355
356   // Sets the value of the specified path in prefs and schedules a save.
357   void RecordBooleanPrefValue(const char* path, bool value);
358
359   // Returns a list of synthetic field trials that were active for the entire
360   // duration of the current log.
361   void GetCurrentSyntheticFieldTrials(
362       std::vector<variations::ActiveGroupId>* synthetic_trials);
363
364   // Creates a new MetricsLog instance with the given |log_type|.
365   scoped_ptr<MetricsLog> CreateLog(MetricsLog::LogType log_type);
366
367   // Record complete list of histograms into the current log.
368   // Called when we close a log.
369   void RecordCurrentHistograms();
370
371   // Record complete list of stability histograms into the current log,
372   // i.e., histograms with the |kUmaStabilityHistogramFlag| flag set.
373   void RecordCurrentStabilityHistograms();
374
375   // Manager for the various in-flight logs.
376   metrics::MetricsLogManager log_manager_;
377
378   // |histogram_snapshot_manager_| prepares histogram deltas for transmission.
379   base::HistogramSnapshotManager histogram_snapshot_manager_;
380
381   // Used to manage various metrics reporting state prefs, such as client id,
382   // low entropy source and whether metrics reporting is enabled. Weak pointer.
383   metrics::MetricsStateManager* const state_manager_;
384
385   // Used to interact with the embedder. Weak pointer; must outlive |this|
386   // instance.
387   metrics::MetricsServiceClient* const client_;
388
389   // Registered metrics providers.
390   ScopedVector<metrics::MetricsProvider> metrics_providers_;
391
392   PrefService* local_state_;
393
394   base::ActionCallback action_callback_;
395
396   // Indicate whether recording and reporting are currently happening.
397   // These should not be set directly, but by calling SetRecording and
398   // SetReporting.
399   bool recording_active_;
400   bool reporting_active_;
401
402   // Indicate whether test mode is enabled, where the initial log should never
403   // be cut, and logs are neither persisted nor uploaded.
404   bool test_mode_active_;
405
406   // The progression of states made by the browser are recorded in the following
407   // state.
408   State state_;
409
410   // Whether the initial stability log has been recorded during startup.
411   bool has_initial_stability_log_;
412
413   // The initial metrics log, used to record startup metrics (histograms and
414   // profiler data). Note that if a crash occurred in the previous session, an
415   // initial stability log may be sent before this.
416   scoped_ptr<MetricsLog> initial_metrics_log_;
417
418   // Instance of the helper class for uploading logs.
419   scoped_ptr<metrics::MetricsLogUploader> log_uploader_;
420
421   // Whether there is a current log upload in progress.
422   bool log_upload_in_progress_;
423
424   // Whether the MetricsService object has received any notifications since
425   // the last time a transmission was sent.
426   bool idle_since_last_transmission_;
427
428   // A number that identifies the how many times the app has been launched.
429   int session_id_;
430
431   // Weak pointers factory used to post task on different threads. All weak
432   // pointers managed by this factory have the same lifetime as MetricsService.
433   base::WeakPtrFactory<MetricsService> self_ptr_factory_;
434
435   // Weak pointers factory used for saving state. All weak pointers managed by
436   // this factory are invalidated in ScheduleNextStateSave.
437   base::WeakPtrFactory<MetricsService> state_saver_factory_;
438
439   // The scheduler for determining when uploads should happen.
440   scoped_ptr<MetricsReportingScheduler> scheduler_;
441
442   // Stores the time of the first call to |GetUptimes()|.
443   base::TimeTicks first_updated_time_;
444
445   // Stores the time of the last call to |GetUptimes()|.
446   base::TimeTicks last_updated_time_;
447
448   // Execution phase the browser is in.
449   static ExecutionPhase execution_phase_;
450
451   // Reduntant marker to check that we completed our shutdown, and set the
452   // exited-cleanly bit in the prefs.
453   static ShutdownCleanliness clean_shutdown_status_;
454
455   // Field trial groups that map to Chrome configuration states.
456   SyntheticTrialGroups synthetic_trial_groups_;
457
458   ObserverList<MetricsServiceObserver> observers_;
459
460   // Confirms single-threaded access to |observers_| in debug builds.
461   base::ThreadChecker thread_checker_;
462
463   friend class MetricsServiceAccessor;
464
465   FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, IsPluginProcess);
466   FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, MetricsServiceObserver);
467   FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest,
468                            PermutedEntropyCacheClearedWhenLowEntropyReset);
469   FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, RegisterSyntheticTrial);
470
471   DISALLOW_COPY_AND_ASSIGN(MetricsService);
472 };
473
474 #endif  // COMPONENTS_METRICS_METRICS_SERVICE_H_