blob: 17ea70a1362a6a273c619cead4148836c099705a [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 <queue>
#include <string>
#include "base/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 "build/chromeos_buildflags.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.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/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 "ppapi/buildflags/buildflags.h"
#include "third_party/metrics_proto/system_profile.pb.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/metrics/per_user_state_manager_chromeos.h"
#endif
class BrowserActivityWatcher;
class Profile;
class PrefRegistrySimple;
namespace network_time {
class NetworkTimeTracker;
} // namespace network_time
namespace metrics {
class MetricsService;
class MetricsStateManager;
} // 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:
ChromeMetricsServiceClient(const ChromeMetricsServiceClient&) = delete;
ChromeMetricsServiceClient& operator=(const ChromeMetricsServiceClient&) =
delete;
~ChromeMetricsServiceClient() override;
// Factory function.
static std::unique_ptr<ChromeMetricsServiceClient> Create(
metrics::MetricsStateManager* state_manager);
// Registers local state prefs used by this class.
static void RegisterPrefs(PrefRegistrySimple* registry);
#if BUILDFLAG(IS_CHROMEOS_ASH)
// Registers profile prefs used by this class.
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
// metrics::MetricsServiceClient:
variations::SyntheticTrialRegistry* GetSyntheticTrialRegistry() override;
metrics::MetricsService* GetMetricsService() override;
ukm::UkmService* GetUkmService() 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 CollectFinalMetricsForLog(base::OnceClosure done_callback) override;
std::unique_ptr<metrics::MetricsLogUploader> CreateUploader(
const GURL& server_url,
const GURL& insecure_server_url,
base::StringPiece mime_type,
metrics::MetricsLogUploader::MetricServiceType service_type,
const metrics::MetricsLogUploader::UploadCallback& on_upload_complete)
override;
base::TimeDelta GetStandardUploadInterval() override;
void LoadingStateChanged(bool is_loading) override;
bool IsReportingPolicyManaged() override;
metrics::EnableMetricsDefault GetMetricsReportingDefaultState() override;
bool IsUMACellularUploadLogicEnabled() override;
bool IsUkmAllowedForAllProfiles() override;
bool AreNotificationListenersEnabledOnAllProfiles() override;
std::string GetAppPackageNameIfLoggable() override;
std::string GetUploadSigningKey() override;
static void SetNotificationListenerSetupFailedForTesting(
bool simulate_failure);
bool ShouldResetClientIdsOnClonedInstall() override;
#if BUILDFLAG(IS_CHROMEOS_ASH)
bool ShouldUploadMetricsForUserId(const uint64_t user_id) override;
void InitPerUserMetrics() override;
void UpdateCurrentUserMetricsConsent(bool user_metrics_consent) override;
absl::optional<bool> GetCurrentUserMetricsConsent() const override;
absl::optional<std::string> GetCurrentUserId() const override;
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
// 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;
// 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);
// 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();
// 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();
// Records metrics about the switches present on the command line.
void RecordCommandLineMetrics();
// 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_WIN)
// Counts (and removes) the browser crash dump attempt signals left behind by
// any previous browser processes which generated a crash dump.
void CountBrowserCrashDumpAttempts();
#endif // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_CHROMEOS_ASH)
// 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(base::StringPiece id);
// Resets client state (i.e. client id) if MSBB or App-sync consent
// is changed from on to off. NOOP when kAppMetricsOnlyRelyOnAppSync is
// disabled.
void ResetClientStateWhenMsbbOrAppConsentIsRevoked(
ukm::UkmConsentState previous_consent_state);
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_.
std::unique_ptr<variations::SyntheticTrialRegistry> synthetic_trial_registry_;
// |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 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_;
// 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_ASH)
// 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_;
#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_