chromium/chrome/browser/metrics/chrome_metrics_service_client.cc

// 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.

#include "chrome/browser/metrics/chrome_metrics_service_client.h"

#include <stddef.h>

#include <memory>
#include <set>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "base/base64.h"
#include "base/check_op.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/lazy_instance.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/persistent_histogram_allocator.h"
#include "base/metrics/persistent_memory_allocator.h"
#include "base/metrics/statistics_recorder.h"
#include "base/notreached.h"
#include "base/path_service.h"
#include "base/rand_util.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/google/google_brand.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/metrics/cached_metrics_profile.h"
#include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h"
#include "chrome/browser/metrics/chrome_metrics_extensions_helper.h"
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
#include "chrome/browser/metrics/chrome_metrics_services_manager_client.h"
#include "chrome/browser/metrics/desktop_platform_features_metrics_provider.h"
#include "chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service_factory.h"
#include "chrome/browser/metrics/desktop_session_duration/desktop_session_metrics_provider.h"
#include "chrome/browser/metrics/https_engagement_metrics_provider.h"
#include "chrome/browser/metrics/metrics_reporting_state.h"
#include "chrome/browser/metrics/network_quality_estimator_provider_impl.h"
#include "chrome/browser/metrics/usertype_by_devicetype_metrics_provider.h"
#include "chrome/browser/performance_manager/metrics/metrics_provider_common.h"
#include "chrome/browser/privacy_budget/identifiability_study_state.h"
#include "chrome/browser/privacy_budget/privacy_budget_metrics_provider.h"
#include "chrome/browser/privacy_budget/privacy_budget_prefs.h"
#include "chrome/browser/privacy_budget/privacy_budget_ukm_entry_filter.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/safe_browsing/metrics/safe_browsing_metrics_provider.h"
#include "chrome/browser/sync/device_info_sync_service_factory.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/tracing/chrome_background_tracing_metrics_provider.h"
#include "chrome/browser/translate/translate_ranker_metrics_provider.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/component_updater/component_updater_service.h"
#include "components/crash/core/common/crash_keys.h"
#include "components/history/core/browser/history_service.h"
#include "components/metrics/call_stacks/call_stack_profile_metrics_provider.h"
#include "components/metrics/component_metrics_provider.h"
#include "components/metrics/content/content_stability_metrics_provider.h"
#include "components/metrics/content/gpu_metrics_provider.h"
#include "components/metrics/content/rendering_perf_metrics_provider.h"
#include "components/metrics/content/subprocess_metrics_provider.h"
#include "components/metrics/cpu_metrics_provider.h"
#include "components/metrics/demographics/demographic_metrics_provider.h"
#include "components/metrics/drive_metrics_provider.h"
#include "components/metrics/entropy_state_provider.h"
#include "components/metrics/install_date_provider.h"
#include "components/metrics/metrics_log_uploader.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_reporting_default_state.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/metrics_service_client.h"
#include "components/metrics/metrics_state_manager.h"
#include "components/metrics/metrics_switches.h"
#include "components/metrics/net/cellular_logic_helper.h"
#include "components/metrics/net/net_metrics_log_uploader.h"
#include "components/metrics/net/network_metrics_provider.h"
#include "components/metrics/persistent_histograms.h"
#include "components/metrics/persistent_synthetic_trial_observer.h"
#include "components/metrics/sampling_metrics_provider.h"
#include "components/metrics/stability_metrics_helper.h"
#include "components/metrics/structured/structured_metrics_features.h"  // nogncheck
#include "components/metrics/structured/structured_metrics_service.h"  // nogncheck
#include "components/metrics/ui/form_factor_metrics_provider.h"
#include "components/metrics/ui/screen_info_metrics_provider.h"
#include "components/metrics/url_constants.h"
#include "components/metrics/version_utils.h"
#include "components/network_time/network_time_tracker.h"
#include "components/omnibox/browser/omnibox_metrics_provider.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/buildflags.h"
#include "components/sync/service/passphrase_type_metrics_provider.h"
#include "components/sync/service/sync_service.h"
#include "components/sync_device_info/device_count_metrics_provider.h"
#include "components/ukm/field_trials_provider_helper.h"
#include "components/ukm/ukm_service.h"
#include "components/variations/synthetic_trial_registry.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/histogram_fetcher.h"
#include "content/public/browser/network_service_instance.h"
#include "google_apis/google_api_keys.h"
#include "ppapi/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"

#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/metrics/chrome_android_metrics_provider.h"
#include "chrome/browser/metrics/page_load_metrics_provider.h"
#include "components/metrics/android_metrics_provider.h"
#include "components/metrics/gms_metrics_provider.h"
#else
#include "chrome/browser/metrics/browser_activity_watcher.h"
#include "chrome/browser/performance_manager/metrics/metrics_provider_desktop.h"
#endif

#if BUILDFLAG(IS_POSIX)
#include <signal.h>
#endif

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/metrics/extensions_metrics_provider.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension.h"
#endif

#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/browser/metrics/lacros_metrics_provider.h"
#include "chromeos/startup/browser_params_proxy.h"
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_features.h"
#include "base/feature_list.h"
#include "chrome/browser/ash/arc/vmm/vmm_metrics_provider.h"
#include "chrome/browser/ash/login/demo_mode/demo_session.h"
#include "chrome/browser/ash/printing/printer_metrics_provider.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/ash/settings/device_settings_service.h"
#include "chrome/browser/ash/system_web_apps/apps/personalization_app/keyboard_backlight_color_metrics_provider.h"
#include "chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_theme_metrics_provider.h"
#include "chrome/browser/ash/system_web_apps/apps/personalization_app/wallpaper_metrics_provider.h"
#include "chrome/browser/metrics/ambient_mode_metrics_provider.h"
#include "chrome/browser/metrics/assistant_service_metrics_provider.h"
#include "chrome/browser/metrics/chromeos_family_link_user_metrics_provider.h"
#include "chrome/browser/metrics/chromeos_metrics_provider.h"
#include "chrome/browser/metrics/chromeos_system_profile_provider.h"
#include "chrome/browser/metrics/cros_healthd_metrics_provider.h"
#include "chrome/browser/metrics/family_user_metrics_provider.h"
#include "chrome/browser/metrics/per_user_state_manager_chromeos.h"
#include "chrome/browser/metrics/update_engine_metrics_provider.h"
#include "chrome/browser/ui/ash/shelf/chrome_shelf_metrics_provider.h"
#include "chrome/browser/ui/webui/ash/settings/services/metrics/os_settings_metrics_provider.h"
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/metrics/structured/ash_structured_metrics_recorder.h"  // nogncheck
#else
#include "chrome/browser/metrics/structured/chrome_structured_metrics_delegate.h"  // nogncheck
#include "chrome/browser/metrics/structured/chrome_structured_metrics_recorder.h"  // nogncheck
#endif

#if BUILDFLAG(IS_WIN)
#include <windows.h>

#include "chrome/browser/metrics/antivirus_metrics_provider_win.h"
#include "chrome/browser/metrics/google_update_metrics_provider_win.h"
#include "chrome/install_static/install_util.h"
#include "chrome/installer/util/util_constants.h"
#include "chrome/notification_helper/notification_helper_constants.h"
#endif

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
#include "components/metrics/motherboard_metrics_provider.h"
#endif

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX)
#include "chrome/browser/metrics/chrome_metrics_service_crash_reporter.h"
#endif

#if !BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/metrics/family_link_user_metrics_provider.h"
#include "chrome/browser/signin/chrome_signin_and_sync_status_metrics_provider.h"
#include "components/metrics/content/accessibility_metrics_provider.h"
#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)

#if BUILDFLAG(IS_MAC)
#include "chrome/browser/metrics/power/power_metrics_provider_mac.h"
#endif

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/metrics/bluetooth_metrics_provider.h"
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

namespace {

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
const int kMaxHistogramStorageKiB = 100 << 10;  // 100 MiB
#else
const int kMaxHistogramStorageKiB =;  // 500 MiB
#endif

// This specifies the amount of time to wait for all renderers to send their
// data.
const int kMaxHistogramGatheringWaitDuration =;  // 60 seconds.

// Needs to be kept in sync with the writer in
// third_party/crashpad/crashpad/handler/handler_main.cc.
const char kCrashpadHistogramAllocatorName[] =;
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX)
base::LazyInstance<ChromeMetricsServiceCrashReporter>::Leaky g_crash_reporter =;
#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX)

#if BUILDFLAG(IS_WIN)
// Needs to be kept in sync with the writer in PlatformExperienceHelper.
const char kPlatformExperienceHelperHistogramAllocatorName[] =
    "PlatformExperienceHelperMetrics";
#endif  // BUILDFLAG(IS_WIN)

void RegisterFileMetricsPreferences(PrefRegistrySimple* registry) {}

std::unique_ptr<metrics::FileMetricsProvider> CreateFileMetricsProvider(
    bool metrics_reporting_enabled) {}

ChromeMetricsServiceClient::IsProcessRunningFunction g_is_process_running =;

bool IsProcessRunning(base::ProcessId pid) {}

// Client used by DemographicMetricsProvider to retrieve Profile information.
class ProfileClientImpl
    : public metrics::DemographicMetricsProvider::ProfileClient {};

std::unique_ptr<metrics::DemographicMetricsProvider>
MakeDemographicMetricsProvider(
    metrics::MetricsLogUploader::MetricServiceType metrics_service_type) {}

class ChromeComponentMetricsProviderDelegate
    : public metrics::ComponentMetricsProviderDelegate {};

#if BUILDFLAG(IS_CHROMEOS_ASH)
// TODO(crbug.com/40214482): Remove this and use ChangeMetricsReportingState()
// once crash no longer depends on GoogleUpdateSettings and per-user is
// available outside of Ash.
void UpdateMetricsServicesForPerUser(bool enabled) {
  // Set the local state pref because a lot of services read directly from this
  // pref to obtain metrics consent.
  //
  // This is OK on Chrome OS because this pref is set on every startup with the
  // device policy value. The previous user consent will get overwritten by
  // the correct device policy value on startup.
  //
  // TODO(crbug.com/40822509): Once a proper API is established and services no
  // longer read the pref value directly, this can be removed.
  g_browser_process->local_state()->SetBoolean(
      metrics::prefs::kMetricsReportingEnabled, enabled);

  g_browser_process->GetMetricsServicesManager()->UpdateUploadPermissions(true);
}
#endif

}  // namespace

ChromeMetricsServiceClient::ChromeMetricsServiceClient(
    metrics::MetricsStateManager* state_manager,
    variations::SyntheticTrialRegistry* synthetic_trial_registry)
    :{}

ChromeMetricsServiceClient::~ChromeMetricsServiceClient() {}

// static
std::unique_ptr<ChromeMetricsServiceClient> ChromeMetricsServiceClient::Create(
    metrics::MetricsStateManager* state_manager,
    variations::SyntheticTrialRegistry* synthetic_trial_registry) {}

// static
void ChromeMetricsServiceClient::RegisterPrefs(PrefRegistrySimple* registry) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
void ChromeMetricsServiceClient::RegisterProfilePrefs(
    user_prefs::PrefRegistrySyncable* registry) {
  metrics::PerUserStateManagerChromeOS::RegisterProfilePrefs(registry);
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

variations::SyntheticTrialRegistry*
ChromeMetricsServiceClient::GetSyntheticTrialRegistry() {}

metrics::MetricsService* ChromeMetricsServiceClient::GetMetricsService() {}

ukm::UkmService* ChromeMetricsServiceClient::GetUkmService() {}

IdentifiabilityStudyState*
ChromeMetricsServiceClient::GetIdentifiabilityStudyState() {}

metrics::structured::StructuredMetricsService*
ChromeMetricsServiceClient::GetStructuredMetricsService() {}

void ChromeMetricsServiceClient::SetMetricsClientId(
    const std::string& client_id) {}

int32_t ChromeMetricsServiceClient::GetProduct() {}

std::string ChromeMetricsServiceClient::GetApplicationLocale() {}

const network_time::NetworkTimeTracker*
ChromeMetricsServiceClient::GetNetworkTimeTracker() {}

bool ChromeMetricsServiceClient::GetBrand(std::string* brand_code) {}

metrics::SystemProfileProto::Channel ChromeMetricsServiceClient::GetChannel() {}

bool ChromeMetricsServiceClient::IsExtendedStableChannel() {}

std::string ChromeMetricsServiceClient::GetVersionString() {}

void ChromeMetricsServiceClient::OnEnvironmentUpdate(std::string* environment) {}

void ChromeMetricsServiceClient::MergeSubprocessHistograms() {}

void ChromeMetricsServiceClient::CollectFinalMetricsForLog(
    base::OnceClosure done_callback) {}

std::unique_ptr<metrics::MetricsLogUploader>
ChromeMetricsServiceClient::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) {}

base::TimeDelta ChromeMetricsServiceClient::GetStandardUploadInterval() {}

bool ChromeMetricsServiceClient::IsReportingPolicyManaged() {}

metrics::EnableMetricsDefault
ChromeMetricsServiceClient::GetMetricsReportingDefaultState() {}

void ChromeMetricsServiceClient::Initialize() {}

void ChromeMetricsServiceClient::RegisterMetricsServiceProviders() {}

void ChromeMetricsServiceClient::RegisterUKMProviders() {}

void ChromeMetricsServiceClient::NotifyApplicationNotIdle() {}

void ChromeMetricsServiceClient::CollectFinalHistograms() {}

void ChromeMetricsServiceClient::OnMemoryDetailCollectionDone() {}

void ChromeMetricsServiceClient::OnHistogramSynchronizationDone() {}

bool ChromeMetricsServiceClient::RegisterObservers() {}

bool ChromeMetricsServiceClient::RegisterForProfileEvents(Profile* profile) {}

void ChromeMetricsServiceClient::OnProfileAdded(Profile* profile) {}

void ChromeMetricsServiceClient::OnProfileManagerDestroying() {}

void ChromeMetricsServiceClient::OnUserActivity(const ui::Event* event) {}

void ChromeMetricsServiceClient::LoadingStateChanged(bool /*is_loading*/) {}

void ChromeMetricsServiceClient::OnURLOpenedFromOmnibox(OmniboxLog* log) {}

bool ChromeMetricsServiceClient::IsOnCellularConnection() {}

void ChromeMetricsServiceClient::OnHistoryDeleted() {}

void ChromeMetricsServiceClient::OnUkmAllowedStateChanged(
    bool total_purge,
    ukm::UkmConsentState previous_consent_state) {}

void ChromeMetricsServiceClient::OnRenderProcessHostCreated(
    content::RenderProcessHost* host) {}

void ChromeMetricsServiceClient::RenderProcessExited(
    content::RenderProcessHost* host,
    const content::ChildProcessTerminationInfo& info) {}

void ChromeMetricsServiceClient::RenderProcessHostDestroyed(
    content::RenderProcessHost* host) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
void ChromeMetricsServiceClient::AsyncInitSystemProfileProvider() {
  DCHECK(cros_system_profile_provider_);
  cros_system_profile_provider_->AsyncInit(base::BindOnce([]() {
    // Structured metrics needs to know when the SystemProfile is
    // available since events should have SystemProfile populated.
    // Notify structured metrics recorder that SystemProfile is available to
    // start sending events.
    metrics::structured::Recorder::GetInstance()->OnSystemProfileInitialized();
  }));
}
#endif

// static
bool ChromeMetricsServiceClient::IsWebstoreExtension(std::string_view id) {}

// static
metrics::FileMetricsProvider::FilterAction
ChromeMetricsServiceClient::FilterBrowserMetricsFiles(
    const base::FilePath& path) {}

// static
void ChromeMetricsServiceClient::SetIsProcessRunningForTesting(
    ChromeMetricsServiceClient::IsProcessRunningFunction func) {}

bool ChromeMetricsServiceClient::IsUkmAllowedForAllProfiles() {}

bool g_observer_registration_failed =;
void ChromeMetricsServiceClient::SetNotificationListenerSetupFailedForTesting(
    bool simulate_failure) {}

bool ChromeMetricsServiceClient::
    AreNotificationListenersEnabledOnAllProfiles() {}

std::string ChromeMetricsServiceClient::GetAppPackageNameIfLoggable() {}

std::string ChromeMetricsServiceClient::GetUploadSigningKey() {}

bool ChromeMetricsServiceClient::ShouldResetClientIdsOnClonedInstall() {}

base::CallbackListSubscription
ChromeMetricsServiceClient::AddOnClonedInstallDetectedCallback(
    base::OnceClosure callback) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)

bool ChromeMetricsServiceClient::ShouldUploadMetricsForUserId(
    const uint64_t user_id) {
  // Metrics logs with user ids should be stored in a user cryptohome so this
  // function should only be called after a user logins.
  // |per_user_state_manager_| is initialized before a user can login.
  DCHECK(per_user_state_manager_);

  // This function should only be called if reporting is enabled.
  DCHECK(ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());

  auto current_user_id = per_user_state_manager_->GetCurrentUserId();

  // Do not upload logs that are missing |user_id| during this session.
  if (!current_user_id.has_value()) {
    return false;
  }

  // If |user_id| is different from the currently logged in user, log
  // associated with different |user_id| should not be uploaded. This can
  // happen if a user goes from enable->disable->enable state as user ID is
  // reset going from enable->disable state.
  //
  // The log will be dropped since it may contain data collected during a
  // point in which metrics reporting consent was disabled.
  return user_id == metrics::MetricsLog::Hash(current_user_id.value());
}

void ChromeMetricsServiceClient::UpdateCurrentUserMetricsConsent(
    bool user_metrics_consent) {
  DCHECK(per_user_state_manager_);
  per_user_state_manager_->SetCurrentUserMetricsConsent(user_metrics_consent);
}

void ChromeMetricsServiceClient::InitPerUserMetrics() {
  per_user_state_manager_ =
      std::make_unique<metrics::PerUserStateManagerChromeOS>(
          this, g_browser_process->local_state());
  per_user_consent_change_subscription_ = per_user_state_manager_->AddObserver(
      base::BindRepeating(&UpdateMetricsServicesForPerUser));
}

std::optional<bool> ChromeMetricsServiceClient::GetCurrentUserMetricsConsent()
    const {
  if (per_user_state_manager_) {
    return per_user_state_manager_
        ->GetCurrentUserReportingConsentIfApplicable();
  }

  return std::nullopt;
}

std::optional<std::string> ChromeMetricsServiceClient::GetCurrentUserId()
    const {
  if (per_user_state_manager_) {
    return per_user_state_manager_->GetCurrentUserId();
  }

  return std::nullopt;
}

#endif  //  BUILDFLAG(IS_CHROMEOS_ASH)

void ChromeMetricsServiceClient::ResetClientStateWhenMsbbOrAppConsentIsRevoked(
    ukm::UkmConsentState previous_consent_state) {}

void ChromeMetricsServiceClient::CreateStructuredMetricsService() {}