| // Copyright 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. |
| |
| // This file defines a service that collects information about the user |
| // experience in order to help improve future versions of the app. |
| |
| #ifndef COMPONENTS_METRICS_METRICS_SERVICE_H_ |
| #define COMPONENTS_METRICS_METRICS_SERVICE_H_ |
| |
| #include <stdint.h> |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/gtest_prod_util.h" |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/metrics/field_trial.h" |
| #include "base/metrics/histogram_flattener.h" |
| #include "base/metrics/histogram_snapshot_manager.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/sequence_checker.h" |
| #include "base/time/time.h" |
| #include "build/build_config.h" |
| #include "components/metrics/clean_exit_beacon.h" |
| #include "components/metrics/delegating_provider.h" |
| #include "components/metrics/execution_phase.h" |
| #include "components/metrics/metrics_log.h" |
| #include "components/metrics/metrics_log_manager.h" |
| #include "components/metrics/metrics_log_store.h" |
| #include "components/metrics/metrics_provider.h" |
| #include "components/metrics/metrics_reporting_service.h" |
| #include "components/metrics/net/network_metrics_provider.h" |
| #include "components/variations/synthetic_trial_registry.h" |
| |
| class PrefService; |
| class PrefRegistrySimple; |
| |
| namespace base { |
| class HistogramSamples; |
| class PrefService; |
| } |
| |
| namespace metrics { |
| |
| class MetricsRotationScheduler; |
| class MetricsServiceClient; |
| class MetricsStateManager; |
| |
| // See metrics_service.cc for a detailed description. |
| class MetricsService : public base::HistogramFlattener { |
| public: |
| // Creates the MetricsService with the given |state_manager|, |client|, and |
| // |local_state|. Does not take ownership of the paramaters; instead stores |
| // a weak pointer to each. Caller should ensure that the parameters are valid |
| // for the lifetime of this class. |
| MetricsService(MetricsStateManager* state_manager, |
| MetricsServiceClient* client, |
| PrefService* local_state); |
| ~MetricsService() override; |
| |
| // Initializes metrics recording state. Updates various bookkeeping values in |
| // prefs and sets up the scheduler. This is a separate function rather than |
| // being done by the constructor so that field trials could be created before |
| // this is run. |
| void InitializeMetricsRecordingState(); |
| |
| // Starts the metrics system, turning on recording and uploading of metrics. |
| // Should be called when starting up with metrics enabled, or when metrics |
| // are turned on. |
| void Start(); |
| |
| // Starts the metrics system in a special test-only mode. Metrics won't ever |
| // be uploaded or persisted in this mode, but metrics will be recorded in |
| // memory. |
| void StartRecordingForTests(); |
| |
| // Starts updating the "last live" browser timestamp. |
| void StartUpdatingLastLiveTimestamp(); |
| |
| // Shuts down the metrics system. Should be called at shutdown, or if metrics |
| // are turned off. |
| void Stop(); |
| |
| // Enable/disable transmission of accumulated logs and crash reports (dumps). |
| // Calling Start() automatically enables reporting, but sending is |
| // asyncronous so this can be called immediately after Start() to prevent |
| // any uploading. |
| void EnableReporting(); |
| void DisableReporting(); |
| |
| // Returns the client ID for this client, or the empty string if metrics |
| // recording is not currently running. |
| std::string GetClientId(); |
| |
| // Returns the install date of the application, in seconds since the epoch. |
| int64_t GetInstallDate(); |
| |
| // Returns the date at which the current metrics client ID was created as |
| // an int64_t containing seconds since the epoch. |
| int64_t GetMetricsReportingEnabledDate(); |
| |
| // Returns true if the last session exited cleanly. |
| bool WasLastShutdownClean() const; |
| |
| // Registers local state prefs used by this class. |
| static void RegisterPrefs(PrefRegistrySimple* registry); |
| |
| // HistogramFlattener: |
| void RecordDelta(const base::HistogramBase& histogram, |
| const base::HistogramSamples& snapshot) override; |
| |
| // This should be called when the application is not idle, i.e. the user seems |
| // to be interacting with the application. |
| void OnApplicationNotIdle(); |
| |
| // Invoked when we get a WM_SESSIONEND. This places a value in prefs that is |
| // reset when RecordCompletedSessionEnd is invoked. |
| void RecordStartOfSessionEnd(); |
| |
| // This should be called when the application is shutting down. It records |
| // that session end was successful. |
| void RecordCompletedSessionEnd(); |
| |
| #if defined(OS_ANDROID) || defined(OS_IOS) |
| // Called when the application is going into background mode. |
| void OnAppEnterBackground(); |
| |
| // Called when the application is coming out of background mode. |
| void OnAppEnterForeground(); |
| #else |
| // Set the dirty flag, which will require a later call to LogCleanShutdown(). |
| void LogNeedForCleanShutdown(); |
| #endif // defined(OS_ANDROID) || defined(OS_IOS) |
| |
| static void SetExecutionPhase(ExecutionPhase execution_phase, |
| PrefService* local_state); |
| |
| // Saves in the preferences if the crash report registration was successful. |
| // This count is eventually send via UMA logs. |
| void RecordBreakpadRegistration(bool success); |
| |
| // Saves in the preferences if the browser is running under a debugger. |
| // This count is eventually send via UMA logs. |
| void RecordBreakpadHasDebugger(bool has_debugger); |
| |
| bool recording_active() const; |
| bool reporting_active() const; |
| bool has_unsent_logs() const; |
| |
| // Redundant test to ensure that we are notified of a clean exit. |
| // This value should be true when process has completed shutdown. |
| static bool UmaMetricsProperlyShutdown(); |
| |
| // Register the specified |provider| to provide additional metrics into the |
| // UMA log. Should be called during MetricsService initialization only. |
| void RegisterMetricsProvider(std::unique_ptr<MetricsProvider> provider); |
| |
| // Check if this install was cloned or imaged from another machine. If a |
| // clone is detected, reset the client id and low entropy source. This |
| // should not be called more than once. |
| void CheckForClonedInstall(); |
| |
| // Clears the stability metrics that are saved in local state. |
| void ClearSavedStabilityMetrics(); |
| |
| // Pushes a log that has been generated by an external component. |
| void PushExternalLog(const std::string& log); |
| |
| // Updates data usage tracking prefs with the specified values. |
| void UpdateMetricsUsagePrefs(const std::string& service_name, |
| int message_size, |
| bool is_cellular); |
| |
| variations::SyntheticTrialRegistry* synthetic_trial_registry() { |
| return &synthetic_trial_registry_; |
| } |
| |
| protected: |
| // Exposed for testing. |
| MetricsLogManager* log_manager() { return &log_manager_; } |
| MetricsLogStore* log_store() { |
| return reporting_service_.metrics_log_store(); |
| } |
| |
| // Records the current environment (system profile) in |log|, and persists |
| // the results in prefs. |
| // Exposed for testing. |
| static std::string RecordCurrentEnvironmentHelper( |
| MetricsLog* log, |
| PrefService* local_state, |
| DelegatingProvider* delegating_provider); |
| |
| private: |
| // The MetricsService has a lifecycle that is stored as a state. |
| // See metrics_service.cc for description of this lifecycle. |
| enum State { |
| INITIALIZED, // Constructor was called. |
| INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to finish. |
| INIT_TASK_DONE, // Waiting for timer to send initial log. |
| SENDING_LOGS, // Sending logs an creating new ones when we run out. |
| }; |
| |
| enum ShutdownCleanliness { |
| CLEANLY_SHUTDOWN = 0xdeadbeef, |
| NEED_TO_SHUTDOWN = ~CLEANLY_SHUTDOWN |
| }; |
| |
| // The current state of recording for the MetricsService. The state is UNSET |
| // until set to something else, at which point it remains INACTIVE or ACTIVE |
| // for the lifetime of the object. |
| enum RecordingState { |
| INACTIVE, |
| ACTIVE, |
| UNSET |
| }; |
| |
| // Calls into the client to initialize some system profile metrics. |
| void StartInitTask(); |
| |
| // Callback that moves the state to INIT_TASK_DONE. When this is called, the |
| // state should be INIT_TASK_SCHEDULED. |
| void FinishedInitTask(); |
| |
| void OnUserAction(const std::string& action); |
| |
| // Get the amount of uptime since this process started and since the last |
| // call to this function. Also updates the cumulative uptime metric (stored |
| // as a pref) for uninstall. Uptimes are measured using TimeTicks, which |
| // guarantees that it is monotonic and does not jump if the user changes |
| // their clock. The TimeTicks implementation also makes the clock not |
| // count time the computer is suspended. |
| void GetUptimes(PrefService* pref, |
| base::TimeDelta* incremental_uptime, |
| base::TimeDelta* uptime); |
| |
| // Turns recording on or off. |
| // DisableRecording() also forces a persistent save of logging state (if |
| // anything has been recorded, or transmitted). |
| void EnableRecording(); |
| void DisableRecording(); |
| |
| // If in_idle is true, sets idle_since_last_transmission to true. |
| // If in_idle is false and idle_since_last_transmission_ is true, sets |
| // idle_since_last_transmission to false and starts the timer (provided |
| // starting the timer is permitted). |
| void HandleIdleSinceLastTransmission(bool in_idle); |
| |
| // Set up client ID, session ID, etc. |
| void InitializeMetricsState(); |
| |
| // Opens a new log for recording user experience metrics. |
| void OpenNewLog(); |
| |
| // Closes out the current log after adding any last information. |
| void CloseCurrentLog(); |
| |
| // Pushes the text of the current and staged logs into persistent storage. |
| // Called when Chrome shuts down. |
| void PushPendingLogsToPersistentStorage(); |
| |
| // Ensures that scheduler is running, assuming the current settings are such |
| // that metrics should be reported. If not, this is a no-op. |
| void StartSchedulerIfNecessary(); |
| |
| // Starts the process of uploading metrics data. |
| void StartScheduledUpload(); |
| |
| // Called by the client via a callback when final log info collection is |
| // complete. |
| void OnFinalLogInfoCollectionDone(); |
| |
| // Prepares the initial stability log, which is only logged when the previous |
| // run of Chrome crashed. This log contains any stability metrics left over |
| // from that previous run, and only these stability metrics. It uses the |
| // system profile from the previous session. |prefs_previous_version| is used |
| // to validate the version number recovered from the system profile. Returns |
| // true if a log was created. |
| bool PrepareInitialStabilityLog(const std::string& prefs_previous_version); |
| |
| // Prepares the initial metrics log, which includes startup histograms and |
| // profiler data, as well as incremental stability-related metrics. |
| void PrepareInitialMetricsLog(); |
| |
| // Reads, increments and then sets the specified long preference that is |
| // stored as a string. |
| void IncrementLongPrefsValue(const char* path); |
| |
| // Records that the browser was shut down cleanly. |
| void LogCleanShutdown(bool end_completed); |
| |
| // Creates a new MetricsLog instance with the given |log_type|. |
| std::unique_ptr<MetricsLog> CreateLog(MetricsLog::LogType log_type); |
| |
| // Records the current environment (system profile) in |log|, and persists |
| // the results in prefs and GlobalPersistentSystemProfile. |
| // Exposed for testing. |
| void RecordCurrentEnvironment(MetricsLog* log); |
| |
| // Record complete list of histograms into the current log. |
| // Called when we close a log. |
| void RecordCurrentHistograms(); |
| |
| // Record complete list of stability histograms into the current log, |
| // i.e., histograms with the |kUmaStabilityHistogramFlag| flag set. |
| void RecordCurrentStabilityHistograms(); |
| |
| // Record a single independent profile and associated histogram from |
| // metrics providers. If this returns true, one was found and there may |
| // be more. |
| bool PrepareProviderMetricsLog(); |
| |
| // Records one independent histogram log and then reschedules itself to |
| // check for others. The interval is so as to not adversely impact the UI. |
| void PrepareProviderMetricsTask(); |
| |
| // Updates the "last live" browser timestamp and schedules the next update. |
| void UpdateLastLiveTimestampTask(); |
| |
| // Sub-service for uploading logs. |
| MetricsReportingService reporting_service_; |
| |
| // Manager for the various in-flight logs. |
| MetricsLogManager log_manager_; |
| |
| // |histogram_snapshot_manager_| prepares histogram deltas for transmission. |
| base::HistogramSnapshotManager histogram_snapshot_manager_; |
| |
| // Used to manage various metrics reporting state prefs, such as client id, |
| // low entropy source and whether metrics reporting is enabled. Weak pointer. |
| MetricsStateManager* const state_manager_; |
| |
| // Used to interact with the embedder. Weak pointer; must outlive |this| |
| // instance. |
| MetricsServiceClient* const client_; |
| |
| // Registered metrics providers. |
| DelegatingProvider delegating_provider_; |
| |
| PrefService* local_state_; |
| |
| base::ActionCallback action_callback_; |
| |
| // Indicate whether recording and reporting are currently happening. |
| // These should not be set directly, but by calling SetRecording and |
| // SetReporting. |
| RecordingState recording_state_; |
| |
| // Indicate whether test mode is enabled, where the initial log should never |
| // be cut, and logs are neither persisted nor uploaded. |
| bool test_mode_active_; |
| |
| // The progression of states made by the browser are recorded in the following |
| // state. |
| State state_; |
| |
| // The initial metrics log, used to record startup metrics (histograms and |
| // profiler data). Note that if a crash occurred in the previous session, an |
| // initial stability log may be sent before this. |
| std::unique_ptr<MetricsLog> initial_metrics_log_; |
| |
| // Whether the MetricsService object has received any notifications since |
| // the last time a transmission was sent. |
| bool idle_since_last_transmission_; |
| |
| // A number that identifies the how many times the app has been launched. |
| int session_id_; |
| |
| // The scheduler for determining when log rotations should happen. |
| std::unique_ptr<MetricsRotationScheduler> rotation_scheduler_; |
| |
| // Stores the time of the first call to |GetUptimes()|. |
| base::TimeTicks first_updated_time_; |
| |
| // Stores the time of the last call to |GetUptimes()|. |
| base::TimeTicks last_updated_time_; |
| |
| variations::SyntheticTrialRegistry synthetic_trial_registry_; |
| |
| // Redundant marker to check that we completed our shutdown, and set the |
| // exited-cleanly bit in the prefs. |
| static ShutdownCleanliness clean_shutdown_status_; |
| |
| FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, IsPluginProcess); |
| FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, |
| PermutedEntropyCacheClearedWhenLowEntropyReset); |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| // Weak pointers factory used to post task on different threads. All weak |
| // pointers managed by this factory have the same lifetime as MetricsService. |
| base::WeakPtrFactory<MetricsService> self_ptr_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MetricsService); |
| }; |
| |
| } // namespace metrics |
| |
| #endif // COMPONENTS_METRICS_METRICS_SERVICE_H_ |