blob: af0e73c934fc3faf7ce2ee9ddffa2dd4367eb965 [file] [log] [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_METRICS_CHROME_METRICS_SERVICE_CLIENT_H_
#define CHROME_BROWSER_METRICS_CHROME_METRICS_SERVICE_CLIENT_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <string_view>
#include "base/callback_list.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_multi_source_observation.h"
#include "base/scoped_observation.h"
#include "base/sequence_checker.h"
#include "build/build_config.h"
#include "chrome/browser/metrics/incognito_observer.h"
#include "chrome/browser/metrics/metrics_memory_details.h"
#include "chrome/browser/privacy_budget/identifiability_study_state.h"
#include "chrome/browser/profiles/profile_manager_observer.h"
#include "components/metrics/file_metrics_provider.h"
#include "components/metrics/metrics_log_uploader.h"
#include "components/metrics/metrics_service_client.h"
#include "components/metrics/persistent_synthetic_trial_observer.h"
#include "components/omnibox/browser/omnibox_event_global_tracker.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/ukm/observers/history_delete_observer.h"
#include "components/ukm/observers/ukm_consent_state_observer.h"
#include "components/variations/synthetic_trial_registry.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_creation_observer.h"
#include "content/public/browser/render_process_host_observer.h"
#include "third_party/metrics_proto/system_profile.pb.h"
#include "ui/base/user_activity/user_activity_detector.h"
#include "ui/base/user_activity/user_activity_observer.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/metrics/cros_pre_consent_metrics_manager.h"
#endif
class BrowserActivityWatcher;
class Profile;
class ProfileManager;
class PrefRegistrySimple;
namespace network_time {
class NetworkTimeTracker;
} // namespace network_time
namespace metrics {
class MetricsService;
class MetricsStateManager;
#if BUILDFLAG(IS_CHROMEOS)
class PerUserStateManagerChromeOS;
#endif
} // namespace metrics
// ChromeMetricsServiceClient provides an implementation of MetricsServiceClient
// that depends on chrome/.
class ChromeMetricsServiceClient
: public metrics::MetricsServiceClient,
public ukm::HistoryDeleteObserver,
public ukm::UkmConsentStateObserver,
public content::RenderProcessHostObserver,
public content::RenderProcessHostCreationObserver,
public ProfileManagerObserver,
public ui::UserActivityObserver {
public:
ChromeMetricsServiceClient(const ChromeMetricsServiceClient&) = delete;
ChromeMetricsServiceClient& operator=(const ChromeMetricsServiceClient&) =
delete;
~ChromeMetricsServiceClient() override;
// Factory function.
static std::unique_ptr<ChromeMetricsServiceClient> Create(
metrics::MetricsStateManager* state_manager,
variations::SyntheticTrialRegistry* synthetic_trial_registry);
// Registers local state prefs used by this class.
static void RegisterPrefs(PrefRegistrySimple* registry);
#if BUILDFLAG(IS_CHROMEOS)
// Registers profile prefs used by this class.
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
#endif // BUILDFLAG(IS_CHROMEOS)
// metrics::MetricsServiceClient:
variations::SyntheticTrialRegistry* GetSyntheticTrialRegistry() override;
metrics::MetricsService* GetMetricsService() override;
ukm::UkmService* GetUkmService() override;
metrics::dwa::DwaService* GetDwaService() override;
IdentifiabilityStudyState* GetIdentifiabilityStudyState() override;
metrics::structured::StructuredMetricsService* GetStructuredMetricsService()
override;
void SetMetricsClientId(const std::string& client_id) override;
int32_t GetProduct() override;
std::string GetApplicationLocale() override;
const network_time::NetworkTimeTracker* GetNetworkTimeTracker() override;
bool GetBrand(std::string* brand_code) override;
metrics::SystemProfileProto::Channel GetChannel() override;
bool IsExtendedStableChannel() override;
std::string GetVersionString() override;
void OnEnvironmentUpdate(std::string* serialized_environment) override;
void MergeSubprocessHistograms() override;
void CollectFinalMetricsForLog(base::OnceClosure done_callback) override;
std::unique_ptr<metrics::MetricsLogUploader> CreateUploader(
const GURL& server_url,
const GURL& insecure_server_url,
std::string_view mime_type,
metrics::MetricsLogUploader::MetricServiceType service_type,
const metrics::MetricsLogUploader::UploadCallback& on_upload_complete)
override;
base::TimeDelta GetStandardUploadInterval() override;
std::optional<base::TimeDelta> GetCustomUploadInterval() const override;
void LoadingStateChanged(bool is_loading) override;
bool IsReportingPolicyManaged() override;
metrics::EnableMetricsDefault GetMetricsReportingDefaultState() override;
bool IsOnCellularConnection() override;
bool IsUkmAllowedForAllProfiles() override;
bool IsDwaAllowedForAllProfiles() override;
bool AreNotificationListenersEnabledOnAllProfiles() override;
std::string GetAppPackageNameIfLoggable() override;
std::string GetUploadSigningKey() override;
static void SetNotificationListenerSetupFailedForTesting(
bool simulate_failure);
bool ShouldResetClientIdsOnClonedInstall() override;
base::CallbackListSubscription AddOnClonedInstallDetectedCallback(
base::OnceClosure callback) override;
#if BUILDFLAG(IS_CHROMEOS)
bool ShouldUploadMetricsForUserId(const uint64_t user_id) override;
void InitPerUserMetrics() override;
void UpdateCurrentUserMetricsConsent(bool user_metrics_consent) override;
std::optional<bool> GetCurrentUserMetricsConsent() const override;
std::optional<std::string> GetCurrentUserId() const override;
#endif // BUILDFLAG(IS_CHROMEOS)
// ukm::HistoryDeleteObserver:
void OnHistoryDeleted() override;
// ukm::UkmConsentStateObserver:
void OnUkmAllowedStateChanged(
bool must_purge,
ukm::UkmConsentState previous_consent_state) override;
// content::RenderProcessHostCreationObserver:
void OnRenderProcessHostCreated(content::RenderProcessHost* host) override;
// content::RenderProcessHostObserver:
void RenderProcessExited(
content::RenderProcessHost* host,
const content::ChildProcessTerminationInfo& info) override;
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
// ProfileManagerObserver:
void OnProfileAdded(Profile* profile) override;
void OnProfileManagerDestroying() override;
// ui::UserActivityObserver:
void OnUserActivity(const ui::Event* event) override;
// Determine what to do with a file based on filename. Visible for testing.
using IsProcessRunningFunction = bool (*)(base::ProcessId);
static metrics::FileMetricsProvider::FilterAction FilterBrowserMetricsFiles(
const base::FilePath& path);
static void SetIsProcessRunningForTesting(IsProcessRunningFunction func);
protected:
explicit ChromeMetricsServiceClient(
metrics::MetricsStateManager* state_manager,
variations::SyntheticTrialRegistry* synthetic_trial_registry);
// Completes the two-phase initialization of ChromeMetricsServiceClient.
void Initialize();
private:
friend class ChromeMetricsServiceClientTest;
friend class ChromeMetricsServiceClientTestIgnoredForAppMetrics;
friend class ChromeMetricsServiceClientTestWithoutUKMProviders;
FRIEND_TEST_ALL_PREFIXES(ChromeMetricsServiceClientTest, IsWebstoreExtension);
// Registers providers to the MetricsService. These provide data from
// alternate sources.
void RegisterMetricsServiceProviders();
// Registers providers to the UkmService. These provide data from alternate
// sources.
virtual void RegisterUKMProviders();
// Notifies the metrics service that user activity has been detected.
virtual void NotifyApplicationNotIdle();
// Returns true iff profiler data should be included in the next metrics log.
// NOTE: This method is probabilistic and also updates internal state as a
// side-effect when called, so it should only be called once per log.
bool ShouldIncludeProfilerDataInLog();
// Callbacks for various stages of final log info collection. Do not call
// these directly.
void CollectFinalHistograms();
void OnMemoryDetailCollectionDone();
void OnHistogramSynchronizationDone();
// Registers |this| as an observer for notifications which indicate that a
// user is performing work. This is useful to allow some features to sleep,
// until the machine becomes active, such as precluding UMA uploads unless
// there was recent activity.
// Returns true if registration was successful for all profiles.
bool RegisterObservers();
// Call to listen for events on the selected profile's services.
// Returns true if we registered all observers successfully.
bool RegisterForProfileEvents(Profile* profile);
// Called when a URL is opened from the Omnibox.
void OnURLOpenedFromOmnibox(OmniboxLog* log);
#if BUILDFLAG(IS_CHROMEOS)
// Helper function for initialization of system profile provider.
virtual void AsyncInitSystemProfileProvider();
#endif
// Check if an extension is installed via the Web Store.
static bool IsWebstoreExtension(std::string_view id);
// Resets client state (i.e. client id) if MSBB or App-sync consent
// is changed from on to off. For non-ChromeOS platforms, this will no-op.
void ResetClientStateWhenMsbbOrAppConsentIsRevoked(
ukm::UkmConsentState previous_consent_state);
// Creates the Structured Metrics Service based on the platform.
void CreateStructuredMetricsService();
SEQUENCE_CHECKER(sequence_checker_);
// Chrome's privacy budget identifiability study state.
std::unique_ptr<IdentifiabilityStudyState> identifiability_study_state_;
// Weak pointer to the MetricsStateManager.
const raw_ptr<metrics::MetricsStateManager> metrics_state_manager_;
// The synthetic trial registry shared by metrics_service_ and ukm_service_.
const raw_ptr<variations::SyntheticTrialRegistry> synthetic_trial_registry_;
// Metrics service observer for synthetic trials.
metrics::PersistentSyntheticTrialObserver synthetic_trial_observer_;
base::ScopedObservation<variations::SyntheticTrialRegistry,
variations::SyntheticTrialObserver>
synthetic_trial_observation_{&synthetic_trial_observer_};
// |cros_system_profile_provider_| must be declared before |ukm_service_| due
// to some metrics providers have a dependency on |system_profile_provider_|
// and it must be destroyed after they are. Manages SystemProfile information
// needed by other metrics providers.
std::unique_ptr<metrics::MetricsProvider> cros_system_profile_provider_;
// The StructuredMetricsService that |this| is a client of.
std::unique_ptr<metrics::structured::StructuredMetricsService>
structured_metrics_service_;
// The MetricsService that |this| is a client of.
std::unique_ptr<metrics::MetricsService> metrics_service_;
// The UkmService that |this| is a client of.
std::unique_ptr<ukm::UkmService> ukm_service_;
// The DwaService that |this| is a client of.
std::unique_ptr<metrics::dwa::DwaService> dwa_service_;
// Listener for changes in incognito activity.
std::unique_ptr<IncognitoObserver> incognito_observer_;
// Whether we successfully registered all observers of various types.
bool observers_active_ = false;
// Saved callback received from CollectFinalMetricsForLog().
base::OnceClosure collect_final_metrics_done_callback_;
// Indicates that collect final metrics step is running.
bool waiting_for_collect_final_metrics_step_ = false;
// Number of async histogram fetch requests in progress.
int num_async_histogram_fetches_in_progress_ = 0;
// Subscription for receiving callbacks that a URL was opened from the
// omnibox.
base::CallbackListSubscription omnibox_url_opened_subscription_;
#if !BUILDFLAG(IS_ANDROID)
std::unique_ptr<BrowserActivityWatcher> browser_activity_watcher_;
#endif
#if BUILDFLAG(IS_CHROMEOS)
// PerUserStateManagerChromeOS that |this| is a client of.
std::unique_ptr<metrics::PerUserStateManagerChromeOS> per_user_state_manager_;
// Subscription for receiving callbacks that user metrics consent has changed.
base::CallbackListSubscription per_user_consent_change_subscription_;
// Used to notify metrics service if user activity has been detected on the
// system.
base::ScopedObservation<ui::UserActivityDetector, ui::UserActivityObserver>
user_activity_observation_{this};
// Manages the consent of UMA before the user has been created. This object is
// only created during OOBE before the primary user has given intent to
// metrics consent.
std::unique_ptr<metrics::CrOSPreConsentMetricsManager>
cros_pre_consent_manager_;
#endif
base::ScopedMultiSourceObservation<content::RenderProcessHost,
content::RenderProcessHostObserver>
scoped_observations_{this};
base::ScopedObservation<ProfileManager, ProfileManagerObserver>
profile_manager_observer_{this};
base::WeakPtrFactory<ChromeMetricsServiceClient> weak_ptr_factory_{this};
};
#endif // CHROME_BROWSER_METRICS_CHROME_METRICS_SERVICE_CLIENT_H_