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

//------------------------------------------------------------------------------
// Description of a MetricsService instance's life cycle.
//
// OVERVIEW
//
// A MetricsService instance is typically created at application startup.  It is
// the central controller for the acquisition of log data, and the automatic
// transmission of that log data to an external server.  Its major job is to
// manage logs, grouping them for transmission, and transmitting them.  As part
// of its grouping, MS finalizes logs by including some just-in-time gathered
// memory statistics, snapshotting the current stats of numerous histograms,
// closing the logs, translating to protocol buffer format, and compressing the
// results for transmission.  Transmission includes submitting a compressed log
// as data in a URL-post, and retransmitting (or retaining at process
// termination) if the attempted transmission failed.  Retention across process
// terminations is done using the PrefServices facilities. The retained logs
// (the ones that never got transmitted) are compressed and base64-encoded
// before being persisted.
//
// Logs fall into one of two categories: "initial logs," and "ongoing logs."
// There is at most one initial log sent for each complete run of Chrome (from
// startup, to browser shutdown).  An initial log is generally transmitted some
// short time (1 minute?) after startup, and includes stats such as recent crash
// info, the number and types of plugins, etc.  The external server's response
// to the initial log conceptually tells this MS if it should continue
// transmitting logs (during this session). The server response can actually be
// much more detailed, and always includes (at a minimum) how often additional
// ongoing logs should be sent.
//
// After the above initial log, a series of ongoing logs will be transmitted.
// The first ongoing log actually begins to accumulate information stating when
// the MS was first constructed.  Note that even though the initial log is
// commonly sent a full minute after startup, the initial log does not include
// much in the way of user stats.   The most common interlog period (delay)
// is 30 minutes. That time period starts when the first user action causes a
// logging event.  This means that if there is no user action, there may be long
// periods without any (ongoing) log transmissions.  Ongoing logs typically
// contain very detailed records of user activities (ex: opened tab, closed
// tab, fetched URL, maximized window, etc.)  In addition, just before an
// ongoing log is closed out, a call is made to gather memory statistics.  Those
// memory statistics are deposited into a histogram, and the log finalization
// code is then called.  In the finalization, a call to a Histogram server
// acquires a list of all local histograms that have been flagged for upload
// to the UMA server.  The finalization also acquires the most recent number
// of page loads, along with any counts of renderer or plugin crashes.
//
// When the browser shuts down, there will typically be a fragment of an ongoing
// log that has not yet been transmitted.  At shutdown time, that fragment is
// closed (including snapshotting histograms), and persisted, for potential
// transmission during a future run of the product.
//
// There are two slightly abnormal shutdown conditions.  There is a
// "disconnected scenario," and a "really fast startup and shutdown" scenario.
// In the "never connected" situation, the user has (during the running of the
// process) never established an internet connection.  As a result, attempts to
// transmit the initial log have failed, and a lot(?) of data has accumulated in
// the ongoing log (which didn't yet get closed, because there was never even a
// contemplation of sending it).  There is also a kindred "lost connection"
// situation, where a loss of connection prevented an ongoing log from being
// transmitted, and a (still open) log was stuck accumulating a lot(?) of data,
// while the earlier log retried its transmission.  In both of these
// disconnected situations, two logs need to be, and are, persistently stored
// for future transmission.
//
// The other unusual shutdown condition, termed "really fast startup and
// shutdown," involves the deliberate user termination of the process before
// the initial log is even formed or transmitted. In that situation, no logging
// is done, but the historical crash statistics remain (unlogged) for inclusion
// in a future run's initial log.  (i.e., we don't lose crash stats).
//
// With the above overview, we can now describe the state machine's various
// states, based on the State enum specified in the state_ member.  Those states
// are:
//
//  CONSTRUCTED,          // Constructor was called.
//  INITIALIZED,          // InitializeMetricsRecordingState() was called.
//  INIT_TASK_SCHEDULED,  // Waiting for deferred init tasks to finish.
//  INIT_TASK_DONE,       // Waiting for timer to send the first ongoing log.
//  SENDING_LOGS,         // Sending logs and creating new ones when we run out.
//
// In more detail, we have:
//
//    INIT_TASK_SCHEDULED,    // Waiting for deferred init tasks to finish.
// Typically about 30 seconds after startup, a task is sent to a background
// thread to perform deferred (lower priority and slower) initialization steps
// such as getting the list of plugins.  That task will (when complete) make an
// async callback (via a Task) to indicate the completion.
//
//    INIT_TASK_DONE,         // Waiting for timer to send first ongoing log.
// The callback has arrived, and it is now possible for an ongoing log to be
// created.  This callback typically arrives back less than one second after
// the deferred init task is dispatched.
//
//    SENDING_LOGS,  // Sending logs and creating new ones when we run out.
// Logs from previous sessions have been loaded, and an optional initial
// stability log has been created. We will send all of these logs, and when
// they run out, we will start cutting new logs to send.  We will also cut a new
// log if we expect a shutdown.
//
// The progression through the above states is simple, and sequential.
// States proceed from INITIALIZED to SENDING_LOGS, and remain in the latter
// until shutdown.
//
// Also note that whenever we successfully send a log, we mirror the list
// of logs into the PrefService. This ensures that IF we crash, we won't start
// up and retransmit our old logs again.
//
// Due to race conditions, it is always possible that a log file could be sent
// twice.  For example, if a log file is sent, but not yet acknowledged by
// the external server, and the user shuts down, then a copy of the log may be
// saved for re-transmission.  These duplicates could be filtered out server
// side, but are not expected to be a significant problem.
//
//
//------------------------------------------------------------------------------

#include "components/metrics/metrics_service.h"

#include <stddef.h>

#include <algorithm>
#include <memory>
#include <string_view>
#include <utility>

#include "base/callback_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_flattener.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/histogram_macros_local.h"
#include "base/metrics/histogram_samples.h"
#include "base/metrics/persistent_histogram_allocator.h"
#include "base/metrics/statistics_recorder.h"
#include "base/process/process_handle.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/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/metrics/clean_exit_beacon.h"
#include "components/metrics/environment_recorder.h"
#include "components/metrics/field_trials_provider.h"
#include "components/metrics/metrics_features.h"
#include "components/metrics/metrics_log.h"
#include "components/metrics/metrics_log_uploader.h"
#include "components/metrics/metrics_logs_event_manager.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_rotation_scheduler.h"
#include "components/metrics/metrics_service_client.h"
#include "components/metrics/metrics_service_observer.h"
#include "components/metrics/metrics_state_manager.h"
#include "components/metrics/metrics_switches.h"
#include "components/metrics/persistent_system_profile.h"
#include "components/metrics/stability_metrics_provider.h"
#include "components/metrics/url_constants.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/variations/entropy_provider.h"

#if !BUILDFLAG(IS_ANDROID)
#include "components/keep_alive_registry/keep_alive_registry.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"
#endif  // !BUILDFLAG(IS_ANDROID)

namespace metrics {
namespace {

// Used to write histogram data to a log. Does not take ownership of the log.
class IndependentFlattener : public base::HistogramFlattener {
 public:
  explicit IndependentFlattener(MetricsLog* log) : log_(log) {}

  IndependentFlattener(const IndependentFlattener&) = delete;
  IndependentFlattener& operator=(const IndependentFlattener&) = delete;

  ~IndependentFlattener() override = default;

  // base::HistogramFlattener:
  void RecordDelta(const base::HistogramBase& histogram,
                   const base::HistogramSamples& snapshot) override {
    CHECK(histogram.HasFlags(base::HistogramBase::kUmaTargetedHistogramFlag));
    log_->RecordHistogramDelta(histogram.histogram_name(), snapshot);
  }

 private:
  const raw_ptr<MetricsLog, AcrossTasksDanglingUntriaged> log_;
};

// Used to mark histogram samples as reported so that they are not included in
// the next log. A histogram's snapshot samples are simply discarded/ignored
// when attempting to record them through this |HistogramFlattener|.
class DiscardingFlattener : public base::HistogramFlattener {
 public:
  DiscardingFlattener() = default;

  DiscardingFlattener(const DiscardingFlattener&) = delete;
  DiscardingFlattener& operator=(const DiscardingFlattener&) = delete;

  ~DiscardingFlattener() override = default;

  void RecordDelta(const base::HistogramBase& histogram,
                   const base::HistogramSamples& snapshot) override {
    // No-op. We discard the samples.
  }
};

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
// Emits a histogram upon instantiation, and on destruction. Used to measure how
// often the browser is ungracefully killed between two different points. In
// particular, currently, this is used on mobile to measure how often the
// browser is killed while finalizing a log, right after backgrounding. This
// scenario is prone to data loss because a histogram may have been snapshotted
// and put into a log, but the browser was killed before it could be fully
// finalized and stored.
//
// TODO(crbug.com/40213327): Consider improving this. In particular, the
// "Started" bucket is emitted before finalizing the log, and the "Finished"
// bucket is emitted after. Hence, the latter will be reported in a different
// log, which may cause a "lag" and/or bias (e.g. if the latter log is more
// prone to loss). A better way to do this is to allocate an object on the
// persistent memory upon instantiation, and flip a bit in it upon destruction.
// A future session that will consume this persistent memory should take care of
// emitting the histogram samples.
class ScopedTerminationChecker {
 public:
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class Status {
    kStarted = 0,
    kFinished = 1,
    kMaxValue = kFinished,
  };

  explicit ScopedTerminationChecker(std::string_view histogram_name) {
    // Do nothing if the persistent histogram system is not being used.
    // Otherwise, the "Finished" bucket may be more prone to loss, which may
    // incorrectly make it seem like the browser was killed in between the
    // scoped code.
    if (!base::GlobalHistogramAllocator::Get()) {
      return;
    }

    active_ = true;
    histogram_name_ = histogram_name;
    base::UmaHistogramEnumeration(histogram_name_, Status::kStarted);
  }

  ScopedTerminationChecker(const ScopedTerminationChecker& other) = delete;
  ScopedTerminationChecker& operator=(const ScopedTerminationChecker& other) =
      delete;

  ~ScopedTerminationChecker() {
    if (!active_) {
      return;
    }
    base::UmaHistogramEnumeration(histogram_name_, Status::kFinished);
  }

 private:
  // Name of the histogram to emit to upon instantiation/destruction.
  std::string histogram_name_;

  // Whether or not this will emit histograms. In particular, if this browser
  // session does not make use of persistent memory, this will be false, and
  // this object will do nothing.
  bool active_ = false;
};
#endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)

// The delay, in seconds, after starting recording before doing expensive
// initialization work.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
// On mobile devices, a significant portion of sessions last less than a minute.
// Use a shorter timer on these platforms to avoid losing data.
// TODO(dfalcantara): To avoid delaying startup, tighten up initialization so
//                    that it occurs after the user gets their initial page.
const int kInitializationDelaySeconds = 5;
#else
const int kInitializationDelaySeconds = 30;
#endif

// The browser last live timestamp is updated every 15 minutes.
const int kUpdateAliveTimestampSeconds = 15 * 60;

#if BUILDFLAG(IS_CHROMEOS_ASH)
enum UserLogStoreState {
  kSetPostSendLogsState = 0,
  kSetPreSendLogsState = 1,
  kUnsetPostSendLogsState = 2,
  kUnsetPreSendLogsState = 3,
  kMaxValue = kUnsetPreSendLogsState,
};

void RecordUserLogStoreState(UserLogStoreState state) {
  base::UmaHistogramEnumeration("UMA.CrosPerUser.UserLogStoreState", state);
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

}  // namespace

// static
void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) {
  CleanExitBeacon::RegisterPrefs(registry);
  MetricsStateManager::RegisterPrefs(registry);
  MetricsLog::RegisterPrefs(registry);
  StabilityMetricsProvider::RegisterPrefs(registry);
  MetricsReportingService::RegisterPrefs(registry);

  registry->RegisterIntegerPref(prefs::kMetricsSessionID, -1);
}

MetricsService::MetricsService(MetricsStateManager* state_manager,
                               MetricsServiceClient* client,
                               PrefService* local_state)
    : reporting_service_(client, local_state, &logs_event_manager_),
      state_manager_(state_manager),
      client_(client),
      local_state_(local_state),
      recording_state_(UNSET),
      test_mode_active_(false),
      state_(CONSTRUCTED),
      idle_since_last_transmission_(false),
      session_id_(-1) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(state_manager_);
  DCHECK(client_);
  DCHECK(local_state_);

  // Emit a local histogram, which should not be reported to servers. This is
  // monitored from the serverside.
  LOCAL_HISTOGRAM_BOOLEAN("UMA.LocalHistogram", true);

  bool create_logs_event_observer;
#ifdef NDEBUG
  // For non-debug builds, we only create |logs_event_observer_| if the
  // |kExportUmaLogsToFile| command line flag is passed. This is mostly for
  // performance reasons: 1) we don't want to have to notify an observer in
  // non-debug circumstances (there may be heavy work like copying large
  // strings), and 2) we don't want logs to be lingering in memory.
  create_logs_event_observer =
      base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kExportUmaLogsToFile);
#else
  // For debug builds, always create |logs_event_observer_|.
  create_logs_event_observer = true;
#endif  // NDEBUG

  if (create_logs_event_observer) {
    logs_event_observer_ = std::make_unique<MetricsServiceObserver>(
        MetricsServiceObserver::MetricsServiceType::UMA);
    logs_event_manager_.AddObserver(logs_event_observer_.get());
  }

  cloned_install_subscription_ =
      state_manager->AddOnClonedInstallDetectedCallback(
          base::BindOnce(&MetricsService::OnClonedInstallDetected,
                         self_ptr_factory_.GetWeakPtr()));

  RegisterMetricsProvider(
      std::make_unique<StabilityMetricsProvider>(local_state_));

  RegisterMetricsProvider(state_manager_->GetProvider());
}

MetricsService::~MetricsService() {
  DisableRecording();

  if (logs_event_observer_) {
    logs_event_manager_.RemoveObserver(logs_event_observer_.get());
    const base::CommandLine* command_line =
        base::CommandLine::ForCurrentProcess();
    if (command_line->HasSwitch(switches::kExportUmaLogsToFile)) {
      // We should typically not write to files on the main thread, but since
      // this only happens when |kExportUmaLogsToFile| is passed (which
      // indicates debugging), this should be fine.
      logs_event_observer_->ExportLogsToFile(
          command_line->GetSwitchValuePath(switches::kExportUmaLogsToFile));
    }
  }

  // Emit a local histogram, which should not be reported to servers. This is
  // monitored from the serverside. Because this is emitted after closing the
  // last log before shutdown, this sample should be retrieved by the persistent
  // histograms system in a follow up session. This is to ensure independent
  // logs do not include local histograms, a previously buggy behaviour.
  LOCAL_HISTOGRAM_BOOLEAN("UMA.LocalHistogram", true);
}

void MetricsService::InitializeMetricsRecordingState() {
  DCHECK_EQ(CONSTRUCTED, state_);

  // The FieldTrialsProvider should be registered last. This ensures that
  // studies whose features are checked when providers add their information to
  // the log appear in the active field trials.
  RegisterMetricsProvider(std::make_unique<variations::FieldTrialsProvider>(
      client_->GetSyntheticTrialRegistry(), std::string_view()));

  reporting_service_.Initialize();
  InitializeMetricsState();

  base::RepeatingClosure upload_callback = base::BindRepeating(
      &MetricsService::StartScheduledUpload, self_ptr_factory_.GetWeakPtr());

  rotation_scheduler_ = std::make_unique<MetricsRotationScheduler>(
      upload_callback,
      // MetricsServiceClient outlives MetricsService, and
      // MetricsRotationScheduler is tied to the lifetime of |this|.
      base::BindRepeating(&MetricsServiceClient::GetUploadInterval,
                          base::Unretained(client_)),
      client_->ShouldStartUpFastForTesting());

  // Init() has to be called after LogCrash() in order for LogCrash() to work.
  delegating_provider_.Init();

  state_ = INITIALIZED;
}

void MetricsService::Start() {
  HandleIdleSinceLastTransmission(false);
  EnableRecording();
  EnableReporting();
}

void MetricsService::StartRecordingForTests() {
  test_mode_active_ = true;
  EnableRecording();
  DisableReporting();
}

void MetricsService::StartUpdatingLastLiveTimestamp() {
  base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
      FROM_HERE,
      base::BindOnce(&MetricsService::UpdateLastLiveTimestampTask,
                     self_ptr_factory_.GetWeakPtr()),
      GetUpdateLastAliveTimestampDelay());
}

void MetricsService::Stop() {
  HandleIdleSinceLastTransmission(false);
  DisableReporting();
  DisableRecording();
}

void MetricsService::EnableReporting() {
  if (reporting_service_.reporting_active())
    return;
  reporting_service_.EnableReporting();
  StartSchedulerIfNecessary();
}

void MetricsService::DisableReporting() {
  reporting_service_.DisableReporting();
}

std::string MetricsService::GetClientId() const {
  return state_manager_->client_id();
}

int MetricsService::GetLowEntropySource() {
  return state_manager_->GetLowEntropySource();
}

int MetricsService::GetOldLowEntropySource() {
  return state_manager_->GetOldLowEntropySource();
}

int MetricsService::GetPseudoLowEntropySource() {
  return state_manager_->GetPseudoLowEntropySource();
}

std::string_view MetricsService::GetLimitedEntropyRandomizationSource() {
  return state_manager_->GetLimitedEntropyRandomizationSource();
}

void MetricsService::SetExternalClientId(const std::string& id) {
  state_manager_->SetExternalClientId(id);
}

bool MetricsService::WasLastShutdownClean() const {
  return state_manager_->clean_exit_beacon()->exited_cleanly();
}

void MetricsService::EnableRecording() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (recording_state_ == ACTIVE)
    return;
  recording_state_ = ACTIVE;

  state_manager_->ForceClientIdCreation();
  client_->SetMetricsClientId(state_manager_->client_id());

  if (!current_log_) {
    OpenNewLog();
  }

  delegating_provider_.OnRecordingEnabled();

  // Fill in the system profile in the log and persist it (to prefs, .pma
  // and crashpad). This includes running the providers so that information
  // like field trials and hardware info is provided. If Chrome crashes
  // before this log is completed, the .pma file will have this system
  // profile.
  RecordCurrentEnvironment(current_log_.get(), /*complete=*/false);

  base::RemoveActionCallback(action_callback_);
  action_callback_ = base::BindRepeating(&MetricsService::OnUserAction,
                                         base::Unretained(this));
  base::AddActionCallback(action_callback_);

  enablement_observers_.Notify(/*enabled=*/true);
}

void MetricsService::DisableRecording() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (recording_state_ == INACTIVE)
    return;
  recording_state_ = INACTIVE;

  base::RemoveActionCallback(action_callback_);

  delegating_provider_.OnRecordingDisabled();

  base::UmaHistogramBoolean("UMA.MetricsService.PendingOngoingLogOnDisable",
                            pending_ongoing_log_);
  PushPendingLogsToPersistentStorage(
      MetricsLogsEventManager::CreateReason::kServiceShutdown);

  // Because histograms may still be emitted after the last log was closed, an
  // independent log may be created in a future session in order to report
  // those histograms. To ensure that this independent log contains histograms
  // that we wish to appear in every log, call OnDidCreateMetricsLog().
  delegating_provider_.OnDidCreateMetricsLog();

  enablement_observers_.Notify(/*enabled=*/false);
}

bool MetricsService::recording_active() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return recording_state_ == ACTIVE;
}

bool MetricsService::reporting_active() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return reporting_service_.reporting_active();
}

bool MetricsService::has_unsent_logs() const {
  return reporting_service_.metrics_log_store()->has_unsent_logs();
}

bool MetricsService::IsMetricsReportingEnabled() const {
  return state_manager_->IsMetricsReportingEnabled();
}

void MetricsService::HandleIdleSinceLastTransmission(bool in_idle) {
  // If there wasn't a lot of action, maybe the computer was asleep, in which
  // case, the log transmissions should have stopped.  Here we start them up
  // again.
  if (!in_idle && idle_since_last_transmission_)
    StartSchedulerIfNecessary();
  idle_since_last_transmission_ = in_idle;
}

void MetricsService::OnApplicationNotIdle() {
  if (recording_state_ == ACTIVE)
    HandleIdleSinceLastTransmission(false);
}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
void MetricsService::OnAppEnterBackground(bool keep_recording_in_background) {
  is_in_foreground_ = false;
  reporting_service_.SetIsInForegound(false);
  if (!keep_recording_in_background) {
    rotation_scheduler_->Stop();
    reporting_service_.Stop();
  }

  state_manager_->LogHasSessionShutdownCleanly(true);
  // Schedule a write, which happens on a different thread.
  local_state_->CommitPendingWrite();

  // Give providers a chance to persist histograms as part of being
  // backgrounded.
  delegating_provider_.OnAppEnterBackground();

  // At this point, there's no way of knowing when the process will be killed,
  // so this has to be treated similar to a shutdown, closing and persisting all
  // logs. Unlike a shutdown, the state is primed to be ready to continue
  // logging and uploading if the process does return.
  if (recording_active() && !IsTooEarlyToCloseLog()) {
    base::UmaHistogramBoolean(
        "UMA.MetricsService.PendingOngoingLogOnBackgrounded",
        pending_ongoing_log_);
#if BUILDFLAG(IS_ANDROID)
    client_->MergeSubprocessHistograms();
#endif  // BUILDFLAG(IS_ANDROID)
    {
      ScopedTerminationChecker scoped_termination_checker(
          "UMA.MetricsService.OnBackgroundedScopedTerminationChecker");
      PushPendingLogsToPersistentStorage(
          MetricsLogsEventManager::CreateReason::kBackgrounded);
    }
    // Persisting logs closes the current log, so start recording a new log
    // immediately to capture any background work that might be done before the
    // process is killed.
    OpenNewLog();
  }
}

void MetricsService::OnAppEnterForeground(bool force_open_new_log) {
  is_in_foreground_ = true;
  reporting_service_.SetIsInForegound(true);
  state_manager_->LogHasSessionShutdownCleanly(false);
  StartSchedulerIfNecessary();

  if (force_open_new_log && recording_active() && !IsTooEarlyToCloseLog()) {
    base::UmaHistogramBoolean(
        "UMA.MetricsService.PendingOngoingLogOnForegrounded",
        pending_ongoing_log_);
#if BUILDFLAG(IS_ANDROID)
    client_->MergeSubprocessHistograms();
#endif  // BUILDFLAG(IS_ANDROID)
    // Because state_ >= SENDING_LOGS, PushPendingLogsToPersistentStorage()
    // will close the log, allowing a new log to be opened.
    PushPendingLogsToPersistentStorage(
        MetricsLogsEventManager::CreateReason::kForegrounded);
    OpenNewLog();
  }
}
#endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)

void MetricsService::OnPageLoadStarted() {
  delegating_provider_.OnPageLoadStarted();
}

void MetricsService::LogCleanShutdown() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  state_manager_->LogHasSessionShutdownCleanly(true);
}

void MetricsService::ClearSavedStabilityMetrics() {
  delegating_provider_.ClearSavedStabilityMetrics();
  // Stability metrics are stored in Local State prefs, so schedule a Local
  // State write to flush the updated prefs.
  local_state_->CommitPendingWrite();
}

void MetricsService::MarkCurrentHistogramsAsReported() {
  DiscardingFlattener flattener;
  base::HistogramSnapshotManager snapshot_manager(&flattener);
  base::StatisticsRecorder::PrepareDeltas(
      /*include_persistent=*/true, /*flags_to_set=*/base::Histogram::kNoFlags,
      /*required_flags=*/base::Histogram::kUmaTargetedHistogramFlag,
      &snapshot_manager);
}

#if BUILDFLAG(IS_CHROMEOS_ASH)
void MetricsService::SetUserLogStore(
    std::unique_ptr<UnsentLogStore> user_log_store) {
  if (log_store()->has_alternate_ongoing_log_store())
    return;

  if (state_ >= SENDING_LOGS) {
    // Closes the current log so that a new log can be opened in the user log
    // store.
    PushPendingLogsToPersistentStorage(
        MetricsLogsEventManager::CreateReason::kAlternateOngoingLogStoreSet);
    log_store()->SetAlternateOngoingLogStore(std::move(user_log_store));
    OpenNewLog();
    RecordUserLogStoreState(kSetPostSendLogsState);
  } else {
    // Initial log has not yet been created and flushing now would result in
    // incomplete information in the current log.
    //
    // Logs recorded before a user login will be appended to user logs. This
    // should not happen frequently.
    //
    // TODO(crbug.com/40203458): Look for a way to "pause" pre-login logs and
    // flush when INIT_TASK is done.
    log_store()->SetAlternateOngoingLogStore(std::move(user_log_store));
    RecordUserLogStoreState(kSetPreSendLogsState);
  }
}

void MetricsService::UnsetUserLogStore() {
  if (!log_store()->has_alternate_ongoing_log_store())
    return;

  if (state_ >= SENDING_LOGS) {
    PushPendingLogsToPersistentStorage(
        MetricsLogsEventManager::CreateReason::kAlternateOngoingLogStoreUnset);
    log_store()->UnsetAlternateOngoingLogStore();
    OpenNewLog();
    RecordUserLogStoreState(kUnsetPostSendLogsState);
    return;
  }

  // Fast startup and logout case. We flush all histograms and discard the
  // current log. This is to prevent histograms captured during the user
  // session from leaking into local state logs.
  // TODO(crbug.com/40245274): Consider not flushing histograms here.

  // Discard histograms.
  DiscardingFlattener flattener;
  base::HistogramSnapshotManager histogram_snapshot_manager(&flattener);
  delegating_provider_.RecordHistogramSnapshots(&histogram_snapshot_manager);
  base::StatisticsRecorder::PrepareDeltas(
      /*include_persistent=*/true, /*flags_to_set=*/base::Histogram::kNoFlags,
      /*required_flags=*/base::Histogram::kUmaTargetedHistogramFlag,
      &histogram_snapshot_manager);

  // Discard the current log and don't store it.
  CHECK(current_log_);
  current_log_.reset();

  log_store()->UnsetAlternateOngoingLogStore();
  RecordUserLogStoreState(kUnsetPreSendLogsState);
}

bool MetricsService::HasUserLogStore() {
  return log_store()->has_alternate_ongoing_log_store();
}

void MetricsService::InitPerUserMetrics() {
  client_->InitPerUserMetrics();
}

std::optional<bool> MetricsService::GetCurrentUserMetricsConsent() const {
  return client_->GetCurrentUserMetricsConsent();
}

std::optional<std::string> MetricsService::GetCurrentUserId() const {
  return client_->GetCurrentUserId();
}

void MetricsService::UpdateCurrentUserMetricsConsent(
    bool user_metrics_consent) {
  client_->UpdateCurrentUserMetricsConsent(user_metrics_consent);
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

#if BUILDFLAG(IS_CHROMEOS)
void MetricsService::ResetClientId() {
  // Pref must be cleared in order for ForceClientIdCreation to generate a new
  // client ID.
  local_state_->ClearPref(prefs::kMetricsClientID);
  local_state_->ClearPref(prefs::kMetricsLogFinalizedRecordId);
  local_state_->ClearPref(prefs::kMetricsLogRecordId);
  state_manager_->ForceClientIdCreation();
  client_->SetMetricsClientId(state_manager_->client_id());
}
#endif  // BUILDFLAG(IS_CHROMEOS)

variations::SyntheticTrialRegistry*
MetricsService::GetSyntheticTrialRegistry() {
  return client_->GetSyntheticTrialRegistry();
}

base::TimeDelta MetricsService::GetInitializationDelay() {
  return base::Seconds(
      client_->ShouldStartUpFastForTesting() ? 0 : kInitializationDelaySeconds);
}

base::TimeDelta MetricsService::GetUpdateLastAliveTimestampDelay() {
  return base::Seconds(kUpdateAliveTimestampSeconds);
}

bool MetricsService::StageCurrentLogForTest() {
  CloseCurrentLog(/*async=*/false,
                  MetricsLogsEventManager::CreateReason::kUnknown);

  MetricsLogStore* const log_store = reporting_service_.metrics_log_store();
  log_store->StageNextLog();
  if (!log_store->has_staged_log())
    return false;

  OpenNewLog();
  return true;
}

//------------------------------------------------------------------------------
// private methods
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Initialization methods

void MetricsService::InitializeMetricsState() {
  SCOPED_UMA_HISTOGRAM_TIMER_MICROS("UMA.MetricsService.Initialize.Time");

  const int64_t buildtime = MetricsLog::GetBuildTime();
  const std::string version = client_->GetVersionString();

  bool version_changed = false;
  EnvironmentRecorder recorder(local_state_);
  int64_t previous_buildtime = recorder.GetLastBuildtime();
  std::string previous_version = recorder.GetLastVersion();
  if (previous_buildtime != buildtime || previous_version != version) {
    recorder.SetBuildtimeAndVersion(buildtime, version);
    version_changed = true;
  }

  session_id_ = local_state_->GetInteger(prefs::kMetricsSessionID);

  StabilityMetricsProvider provider(local_state_);
  const bool was_last_shutdown_clean = WasLastShutdownClean();
  if (!was_last_shutdown_clean) {
    provider.LogCrash(
        state_manager_->clean_exit_beacon()->browser_last_live_timestamp());
#if BUILDFLAG(IS_ANDROID)
    if (!state_manager_->is_foreground_session()) {
      // Android can have background sessions in which the app may not come to
      // the foreground, so signal that Chrome should stop watching for crashes
      // here. This ensures that the termination of such sessions is not
      // considered a crash. If and when the app enters the foreground, Chrome
      // starts watching for crashes via MetricsService::OnAppEnterForeground().
      //
      // TODO(crbug.com/40190949): Such sessions do not yet exist on iOS. When
      // they do, it may not be possible to know at this point whether a session
      // is a background session.
      //
      // TODO(crbug.com/40788576): On WebLayer, it is not possible to know
      // whether it's a background session at this point.
      //
      // TODO(crbug.com/40196247): Ditto for WebView.
      state_manager_->clean_exit_beacon()->WriteBeaconValue(true);
    }
#endif  // BUILDFLAG(IS_ANDROID)
  }

  // HasPreviousSessionData is called first to ensure it is never bypassed.
  const bool is_initial_stability_log_required =
      delegating_provider_.HasPreviousSessionData() || !was_last_shutdown_clean;
  bool has_initial_stability_log = false;
  if (is_initial_stability_log_required) {
    // If the previous session didn't exit cleanly, or if any provider
    // explicitly requests it, prepare an initial stability log -
    // provided UMA is enabled.
    if (state_manager_->IsMetricsReportingEnabled()) {
      has_initial_stability_log = PrepareInitialStabilityLog(previous_version);
    }
  }

  // If the version changed, but no initial stability log was generated, clear
  // the stability stats from the previous version (so that they don't get
  // attributed to the current version). This could otherwise happen due to a
  // number of different edge cases, such as if the last version crashed before
  // it could save off a system profile or if UMA reporting is disabled (which
  // normally results in stats being accumulated).
  if (version_changed && !has_initial_stability_log)
    ClearSavedStabilityMetrics();

  // If the version changed, the system profile is obsolete and needs to be
  // cleared. This is to avoid the stability data misattribution that could
  // occur if the current version crashed before saving its own system profile.
  // Note however this clearing occurs only after preparing the initial
  // stability log, an operation that requires the previous version's system
  // profile. At this point, stability metrics pertaining to the previous
  // version have been cleared.
  if (version_changed)
    recorder.ClearEnvironmentFromPrefs();

  // Update session ID.
  ++session_id_;
  local_state_->SetInteger(prefs::kMetricsSessionID, session_id_);

  // Notify stability metrics providers about the launch.
  provider.LogLaunch();

  // Call GetUptimes() for the first time, thus allowing all later calls
  // to record incremental uptimes accurately.
  base::TimeDelta ignored_uptime_parameter;
  base::TimeDelta startup_uptime;
  GetUptimes(local_state_, &startup_uptime, &ignored_uptime_parameter);
  DCHECK_EQ(0, startup_uptime.InMicroseconds());
}

void MetricsService::OnUserAction(const std::string& action,
                                  base::TimeTicks action_time) {
  current_log_->RecordUserAction(action, action_time);
  HandleIdleSinceLastTransmission(false);
}

void MetricsService::FinishedInitTask() {
  DCHECK_EQ(INIT_TASK_SCHEDULED, state_);
  state_ = INIT_TASK_DONE;
  rotation_scheduler_->InitTaskComplete();
}

void MetricsService::GetUptimes(PrefService* pref,
                                base::TimeDelta* incremental_uptime,
                                base::TimeDelta* uptime) {
  base::TimeTicks now = base::TimeTicks::Now();
  // If this is the first call, init |first_updated_time_| and
  // |last_updated_time_|.
  if (last_updated_time_.is_null()) {
    first_updated_time_ = now;
    last_updated_time_ = now;
  }
  *incremental_uptime = now - last_updated_time_;
  *uptime = now - first_updated_time_;
  last_updated_time_ = now;
}

//------------------------------------------------------------------------------
// Recording control methods

void MetricsService::OpenNewLog(bool call_providers) {
  CHECK(!current_log_);

  current_log_ = CreateLog(MetricsLog::ONGOING_LOG);
  if (call_providers) {
    delegating_provider_.OnDidCreateMetricsLog();
  }

  DCHECK_NE(CONSTRUCTED, state_);
  if (state_ == INITIALIZED) {
    // We only need to schedule that run once.
    state_ = INIT_TASK_SCHEDULED;

    base::TimeDelta initialization_delay = GetInitializationDelay();
    base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&MetricsService::StartInitTask,
                       self_ptr_factory_.GetWeakPtr()),
        initialization_delay);

    base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&MetricsService::PrepareProviderMetricsTask,
                       self_ptr_factory_.GetWeakPtr()),
        2 * initialization_delay);
  }
}

MetricsService::FinalizedLog::FinalizedLog() = default;
MetricsService::FinalizedLog::~FinalizedLog() = default;
MetricsService::FinalizedLog::FinalizedLog(FinalizedLog&& other) = default;
MetricsService::FinalizedLog& MetricsService::FinalizedLog::operator=(
    FinalizedLog&& other) = default;

MetricsService::MetricsLogHistogramWriter::MetricsLogHistogramWriter(
    MetricsLog* log)
    : MetricsLogHistogramWriter(log,
                                base::Histogram::kUmaTargetedHistogramFlag) {}

MetricsService::MetricsLogHistogramWriter::MetricsLogHistogramWriter(
    MetricsLog* log,
    base::HistogramBase::Flags required_flags)
    : required_flags_(required_flags),
      flattener_(std::make_unique<IndependentFlattener>(log)),
      histogram_snapshot_manager_(
          std::make_unique<base::HistogramSnapshotManager>(flattener_.get())),
      snapshot_transaction_id_(0) {}

MetricsService::MetricsLogHistogramWriter::~MetricsLogHistogramWriter() =
    default;

void MetricsService::MetricsLogHistogramWriter::
    SnapshotStatisticsRecorderDeltas() {
  SCOPED_UMA_HISTOGRAM_TIMER("UMA.MetricsService.SnapshotDeltasTime");
  snapshot_transaction_id_ = base::StatisticsRecorder::PrepareDeltas(
      /*include_persistent=*/true,
      /*flags_to_set=*/base::Histogram::kNoFlags, required_flags_,
      histogram_snapshot_manager_.get());
}

void MetricsService::MetricsLogHistogramWriter::
    SnapshotStatisticsRecorderUnloggedSamples() {
  snapshot_transaction_id_ = base::StatisticsRecorder::SnapshotUnloggedSamples(
      required_flags_, histogram_snapshot_manager_.get());
}

MetricsService::IndependentMetricsLoader::IndependentMetricsLoader(
    std::unique_ptr<MetricsLog> log,
    std::string app_version,
    std::string signing_key)
    : log_(std::move(log)),
      flattener_(new IndependentFlattener(log_.get())),
      snapshot_manager_(new base::HistogramSnapshotManager(flattener_.get())),
      app_version_(std::move(app_version)),
      signing_key_(std::move(signing_key)) {
  CHECK(log_);
  CHECK_EQ(log_->log_type(), MetricsLog::INDEPENDENT_LOG);
}

MetricsService::IndependentMetricsLoader::~IndependentMetricsLoader() = default;

void MetricsService::IndependentMetricsLoader::Run(
    base::OnceCallback<void(bool)> done_callback,
    MetricsProvider* metrics_provider) {
  CHECK(!run_called_);
  run_called_ = true;

  metrics_provider->ProvideIndependentMetrics(
      // Unretained is safe because this callback is either called before
      // |done_callback|, or in |done_callback|. Either case is fine because
      // |done_callback| owns |this|.
      base::BindOnce(&MetricsService::IndependentMetricsLoader::FinalizeLog,
                     base::Unretained(this)),
      std::move(done_callback), log_->uma_proto(), snapshot_manager_.get());
}

void MetricsService::IndependentMetricsLoader::FinalizeLog() {
  CHECK(run_called_);
  CHECK(!finalize_log_called_);
  finalize_log_called_ = true;

  // Release |snapshot_manager_| and then |flattener_| to prevent dangling
  // pointers, since |log_| will be released in MetricsService::FinalizeLog().
  snapshot_manager_.reset();
  flattener_.reset();

  // Note that the close_time param must not be set for independent logs.
  finalized_log_ = MetricsService::FinalizeLog(
      std::move(log_), /*truncate_events=*/false, /*close_time=*/std::nullopt,
      app_version_, signing_key_);
}

bool MetricsService::IndependentMetricsLoader::HasFinalizedLog() {
  return finalize_log_called_ && !release_finalized_log_called_;
}

MetricsService::FinalizedLog
MetricsService::IndependentMetricsLoader::ReleaseFinalizedLog() {
  CHECK(HasFinalizedLog());

  release_finalized_log_called_ = true;
  return std::move(finalized_log_);
}

void MetricsService::StartInitTask() {
  delegating_provider_.AsyncInit(base::BindOnce(
      &MetricsService::FinishedInitTask, self_ptr_factory_.GetWeakPtr()));
}

void MetricsService::CloseCurrentLog(
    bool async,
    MetricsLogsEventManager::CreateReason reason,
    base::OnceClosure log_stored_callback) {
  if (!current_log_) {
    return;
  }

  // If a persistent allocator is in use, update its internal histograms (such
  // as how much memory is being used) before reporting.
  base::PersistentHistogramAllocator* allocator =
      base::GlobalHistogramAllocator::Get();
  if (allocator)
    allocator->UpdateTrackingHistograms();

  // Put incremental data (histogram deltas, and realtime stats deltas) at the
  // end of all log transmissions (initial log handles this separately).
  // RecordIncrementalStabilityElements only exists on the derived
  // MetricsLog class.
  std::unique_ptr<MetricsLog> current_log(std::move(current_log_));
  RecordCurrentEnvironment(current_log.get(), /*complete=*/true);
  base::TimeDelta incremental_uptime;
  base::TimeDelta uptime;
  GetUptimes(local_state_, &incremental_uptime, &uptime);
  current_log->RecordCurrentSessionData(incremental_uptime, uptime,
                                        &delegating_provider_, local_state_);
  current_log->AssignFinalizedRecordId(local_state_);

  auto log_histogram_writer =
      std::make_unique<MetricsLogHistogramWriter>(current_log.get());

  // Let metrics providers provide histogram snapshots independently if they
  // have any. This is done synchronously.
  delegating_provider_.RecordHistogramSnapshots(
      log_histogram_writer->histogram_snapshot_manager());

  MetricsLog::LogType log_type = current_log->log_type();
  CHECK_EQ(log_type, MetricsLog::ONGOING_LOG);
  ChromeUserMetricsExtension::RealLocalTime close_time =
      current_log->GetCurrentClockTime(/*record_time_zone=*/true);
  std::string signing_key = log_store()->GetSigningKeyForLogType(log_type);
  std::string current_app_version = client_->GetVersionString();

#if !BUILDFLAG(IS_ANDROID)
  if (base::FeatureList::IsEnabled(
          features::kMetricsServiceDeltaSnapshotInBg)) {
    // If this is an async periodic log, and the browser is about to be shut
    // down (determined by KeepAliveRegistry::IsShuttingDown(), indicating that
    // there is nothing else to keep the browser alive), then do the work
    // synchronously instead. Otherwise, creating a ScopedKeepAlive below while
    // the KeepAliveRegistry has already started shutting down will trigger a
    // CHECK. Alternatively, the ScopedKeepAlive below could be omitted when the
    // KeepAliveRegistry is shutting down, but since the browser is shutting
    // down soon, then it is likely that the asynchronous task to close the
    // current the log will be cut short, causing data loss.
    if (async && KeepAliveRegistry::GetInstance()->IsShuttingDown()) {
      async = false;
    }
  }
#endif

  if (async) {
    if (base::FeatureList::IsEnabled(
            features::kMetricsServiceDeltaSnapshotInBg)) {
      // In this mode, we perform the full "delta snapshot" (snapshotting
      // unlogged samples and marking them as logged) in the background, in
      // contrast to snapshotting unlogged samples in the background and marking
      // them as logged when back on the main thread, as is done in the else
      // branch.

      auto background_task = base::BindOnce(
          &MetricsService::SnapshotDeltasAndFinalizeLog,
          std::move(log_histogram_writer), std::move(current_log),
          /*truncate_events=*/true, std::move(close_time),
          std::move(current_app_version), std::move(signing_key));
      auto reply_task = base::BindOnce(&MetricsService::StoreFinalizedLog,
                                       self_ptr_factory_.GetWeakPtr(), log_type,
                                       reason, std::move(log_stored_callback));

#if !BUILDFLAG(IS_ANDROID)
      // Prevent the browser from shutting down while creating the log in the
      // background. This is done by creating a ScopedKeepAlive that is only
      // destroyed after the log has been stored. Not used on Android because it
      // has no shutdown code path.
      reply_task = std::move(reply_task)
                       .Then(base::BindOnce(
                           [](std::unique_ptr<ScopedKeepAlive>) {
                             // This function does nothing but keep the
                             // ScopedKeepAlive param alive until we have
                             // finished storing the log.
                           },
                           std::make_unique<ScopedKeepAlive>(
                               KeepAliveOrigin::UMA_LOG,
                               KeepAliveRestartOption::DISABLED)));
#endif  // !BUILDFLAG(IS_ANDROID)

      base::ThreadPool::PostTaskAndReplyWithResult(
          FROM_HERE,
          {base::TaskPriority::USER_BLOCKING,
           base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
          std::move(background_task), std::move(reply_task));
    } else {
      // To finalize the log asynchronously, we snapshot the unlogged samples of
      // histograms and fill them into the log, without actually marking the
      // samples as logged. We only mark them as logged after running the main
      // thread reply task to store the log. This way, we will not lose the
      // samples in case Chrome closes while the background task is running.
      // Note that while this async log is being finalized, it is possible that
      // another log is finalized and stored synchronously, which could
      // potentially cause the same samples to be in two different logs, and
      // hence sent twice. To prevent this, if a synchronous log is stored while
      // the async one is being finalized, we discard the async log as it would
      // be a subset of the synchronous one (in terms of histograms). For more
      // details, see MaybeCleanUpAndStoreFinalizedLog().
      //
      // TODO(crbug.com/40119012): Find a way to save the other data such as
      // user actions and omnibox events when we discard an async log.
      MetricsLogHistogramWriter* log_histogram_writer_ptr =
          log_histogram_writer.get();
      base::ThreadPool::PostTaskAndReplyWithResult(
          FROM_HERE,
          // CONTINUE_ON_SHUTDOWN because the work done is only useful once the
          // reply task is run (and there are no side effects). So, no need to
          // block shutdown since the reply task won't be run anyway.
          // NOTE: If attempting to change the USER_BLOCKING priority, do a
          // study on the impact first since it might affect the number of logs
          // being uploaded (which might have secondary effects, e.g. on metrics
          // that rely on number of logs uploaded).
          {base::TaskPriority::USER_BLOCKING,
           base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
          base::BindOnce(&MetricsService::SnapshotUnloggedSamplesAndFinalizeLog,
                         log_histogram_writer_ptr, std::move(current_log),
                         /*truncate_events=*/true, std::move(close_time),
                         std::move(current_app_version),
                         std::move(signing_key)),
          base::BindOnce(&MetricsService::MaybeCleanUpAndStoreFinalizedLog,
                         self_ptr_factory_.GetWeakPtr(),
                         std::move(log_histogram_writer), log_type, reason,
                         std::move(log_stored_callback)));
      async_ongoing_log_posted_time_ = base::TimeTicks::Now();
    }
  } else {
    FinalizedLog finalized_log = SnapshotDeltasAndFinalizeLog(
        std::move(log_histogram_writer), std::move(current_log),
        /*truncate_events=*/true, std::move(close_time),
        std::move(current_app_version), std::move(signing_key));
    StoreFinalizedLog(log_type, reason, std::move(log_stored_callback),
                      std::move(finalized_log));
  }
}

void MetricsService::StoreFinalizedLog(
    MetricsLog::LogType log_type,
    MetricsLogsEventManager::CreateReason reason,
    base::OnceClosure done_callback,
    FinalizedLog finalized_log) {
  log_store()->StoreLogInfo(std::move(finalized_log.log_info),
                            finalized_log.uncompressed_log_size, log_type,
                            reason);
  std::move(done_callback).Run();
}

void MetricsService::MaybeCleanUpAndStoreFinalizedLog(
    std::unique_ptr<MetricsLogHistogramWriter> log_histogram_writer,
    MetricsLog::LogType log_type,
    MetricsLogsEventManager::CreateReason reason,
    base::OnceClosure done_callback,
    FinalizedLog finalized_log) {
  UMA_HISTOGRAM_TIMES("UMA.MetricsService.PeriodicOngoingLog.ReplyTime",
                      base::TimeTicks::Now() - async_ongoing_log_posted_time_);

  // Store the finalized log only if the StatisticRecorder's last transaction ID
  // is the same as the one from |log_histogram_writer|. If they are not the
  // same, then it indicates that another log was created while creating
  // |finalized_log| (that log would be a superset of |finalized_log| in terms
  // of histograms, so we discard |finalized_log| by not storing it).
  //
  // TODO(crbug.com/40119012): Find a way to save the other data such as user
  // actions and omnibox events when we discard |finalized_log|.
  //
  // Note that the call to StatisticsRecorder::GetLastSnapshotTransactionId()
  // here should not have to wait for a lock since there should not be any async
  // logs being created (|rotation_scheduler_| is only re-scheduled at the end
  // of this method).
  bool should_store_log =
      (base::StatisticsRecorder::GetLastSnapshotTransactionId() ==
       log_histogram_writer->snapshot_transaction_id());
  base::UmaHistogramBoolean("UMA.MetricsService.ShouldStoreAsyncLog",
                            should_store_log);

  if (!should_store_log) {
    // We still need to run |done_callback| even if we do not store the log.
    std::move(done_callback).Run();
    return;
  }

  SCOPED_UMA_HISTOGRAM_TIMER(
      "UMA.MetricsService.MaybeCleanUpAndStoreFinalizedLog.Time");

  log_histogram_writer->histogram_snapshot_manager()
      ->MarkUnloggedSamplesAsLogged();
  StoreFinalizedLog(log_type, reason, std::move(done_callback),
                    std::move(finalized_log));
}

void MetricsService::PushPendingLogsToPersistentStorage(
    MetricsLogsEventManager::CreateReason reason) {
  if (IsTooEarlyToCloseLog()) {
    return;
  }

  base::UmaHistogramBoolean("UMA.MetricsService.PendingOngoingLog",
                            pending_ongoing_log_);

  // Close and store a log synchronously because this is usually called in
  // critical code paths (e.g., shutdown) where we may not have time to run
  // background tasks.
  CloseCurrentLog(/*async=*/false, reason);
  log_store()->TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
}

//------------------------------------------------------------------------------
// Transmission of logs methods

void MetricsService::StartSchedulerIfNecessary() {
  // Never schedule cutting or uploading of logs in test mode.
  if (test_mode_active_)
    return;

  // Even if reporting is disabled, the scheduler is needed to trigger the
  // creation of the first ongoing log, which must be done in order for any logs
  // to be persisted on shutdown or backgrounding.
  if (recording_active() && (reporting_active() || state_ < SENDING_LOGS)) {
    rotation_scheduler_->Start();
    reporting_service_.Start();
  }
}

void MetricsService::StartScheduledUpload() {
  DVLOG(1) << "StartScheduledUpload";
  DCHECK(state_ >= INIT_TASK_DONE);

  // If we're getting no notifications, then the log won't have much in it, and
  // it's possible the computer is about to go to sleep, so don't upload and
  // stop the scheduler.
  // If recording has been turned off, the scheduler doesn't need to run.
  // If reporting is off, proceed if the first ongoing log hasn't been created,
  // since that has to happen in order for logs to be cut and stored when
  // persisting.
  // TODO(stuartmorgan): Call Stop() on the scheduler when reporting and/or
  // recording are turned off instead of letting it fire and then aborting.
  if (idle_since_last_transmission_ || !recording_active() ||
      (!reporting_active() && state_ >= SENDING_LOGS)) {
    rotation_scheduler_->Stop();
    rotation_scheduler_->RotationFinished();
    return;
  }

  // The first ongoing log should be collected prior to sending any unsent logs.
  if (state_ == INIT_TASK_DONE) {
    client_->CollectFinalMetricsForLog(
        base::BindOnce(&MetricsService::OnFinalLogInfoCollectionDone,
                       self_ptr_factory_.GetWeakPtr()));
    return;
  }

  // If there are unsent logs, send the next one. If not, start the asynchronous
  // process of finalizing the current log for upload.
  if (has_unsent_logs()) {
    reporting_service_.Start();
    rotation_scheduler_->RotationFinished();
  } else {
    // There are no logs left to send, so start creating a new one.
    client_->CollectFinalMetricsForLog(
        base::BindOnce(&MetricsService::OnFinalLogInfoCollectionDone,
                       self_ptr_factory_.GetWeakPtr()));
  }
}

void MetricsService::OnFinalLogInfoCollectionDone() {
  DVLOG(1) << "OnFinalLogInfoCollectionDone";
  DCHECK(state_ >= INIT_TASK_DONE);
  state_ = SENDING_LOGS;

  // Abort if metrics were turned off during the final info gathering.
  if (!recording_active()) {
    rotation_scheduler_->Stop();
    rotation_scheduler_->RotationFinished();
    return;
  }

  SCOPED_UMA_HISTOGRAM_TIMER("UMA.MetricsService.PeriodicOngoingLog.CloseTime");

  // There shouldn't be two periodic ongoing logs being finalized in the
  // background simultaneously. This is currently enforced because:
  // 1. Only periodic ongoing logs are finalized asynchronously (i.e., logs
  //    created by the MetricsRotationScheduler).
  // 2. We only re-schedule the MetricsRotationScheduler after storing a
  //    periodic ongoing log.
  //
  // TODO(crbug.com/40119012): Consider making it possible to have multiple
  // simultaneous async logs by having some queueing system (e.g., if we want
  // the log created when foregrounding Chrome to be async).
  DCHECK(!pending_ongoing_log_);
  pending_ongoing_log_ = true;

  base::OnceClosure log_stored_callback =
      base::BindOnce(&MetricsService::OnAsyncPeriodicOngoingLogStored,
                     self_ptr_factory_.GetWeakPtr());
  CloseCurrentLog(/*async=*/true,
                  MetricsLogsEventManager::CreateReason::kPeriodic,
                  std::move(log_stored_callback));
  OpenNewLog(/*call_providers=*/false);
}

void MetricsService::OnAsyncPeriodicOngoingLogStored() {
  pending_ongoing_log_ = false;

  // Call OnDidCreateMetricsLog() after storing a log instead of directly after
  // opening a log. Otherwise, the async log that was created would potentially
  // have mistakenly snapshotted the histograms intended for the newly opened
  // log.
  delegating_provider_.OnDidCreateMetricsLog();

  // Trim and store unsent logs, including the log that was just closed, so that
  // they're not lost in case of a crash before upload time. However, the
  // in-memory log store is unchanged. I.e., logs that are trimmed will still be
  // available in memory. This is to give the log that was just created a chance
  // to be sent in case it is trimmed. After uploading (whether successful or
  // not), the log store is trimmed and stored again, and at that time, the
  // in-memory log store will be updated.
  log_store()->TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/false);

  // Do not re-schedule if metrics were turned off while finalizing the log.
  if (!recording_active()) {
    rotation_scheduler_->Stop();
    rotation_scheduler_->RotationFinished();
  } else {
    // Only re-schedule |rotation_scheduler_| *after* the log was stored to
    // ensure that only one log is created asynchronously at a time.
    reporting_service_.Start();
    rotation_scheduler_->RotationFinished();
    HandleIdleSinceLastTransmission(true);
  }
}

bool MetricsService::PrepareInitialStabilityLog(
    const std::string& prefs_previous_version) {
  DCHECK_EQ(CONSTRUCTED, state_);

  constexpr MetricsLog::LogType log_type = MetricsLog::INITIAL_STABILITY_LOG;
  std::unique_ptr<MetricsLog> initial_stability_log = CreateLog(log_type);

  // Do not call OnDidCreateMetricsLog here because the stability log describes
  // stats from the _previous_ session.

  if (!initial_stability_log->LoadSavedEnvironmentFromPrefs(local_state_))
    return false;

  initial_stability_log->RecordPreviousSessionData(&delegating_provider_,
                                                   local_state_);
  initial_stability_log->AssignFinalizedRecordId(local_state_);

  auto log_histogram_writer = std::make_unique<MetricsLogHistogramWriter>(
      initial_stability_log.get(), base::Histogram::kUmaStabilityHistogramFlag);

  // Add a beacon to this record to indicate that it's part of the initial
  // stability log.
  UMA_STABILITY_HISTOGRAM_BOOLEAN("UMA.InitialStabilityRecordBeacon", true);

  // Let metrics providers provide histogram snapshots independently if they
  // have any. This is done synchronously.
  delegating_provider_.RecordInitialHistogramSnapshots(
      log_histogram_writer->histogram_snapshot_manager());

  std::string signing_key = log_store()->GetSigningKeyForLogType(log_type);

  // Synchronously create the initial stability log in order to ensure that the
  // stability histograms are filled into this specific log. Note that the
  // close_time param must not be set for initial stability logs.
  FinalizedLog finalized_log = SnapshotDeltasAndFinalizeLog(
      std::move(log_histogram_writer), std::move(initial_stability_log),
      /*truncate_events=*/false, /*close_time=*/std::nullopt,
      client_->GetVersionString(), std::move(signing_key));
  StoreFinalizedLog(log_type, MetricsLogsEventManager::CreateReason::kStability,
                    base::DoNothing(), std::move(finalized_log));

  // Store unsent logs, including the stability log that was just saved, so
  // that they're not lost in case of a crash before upload time.
  log_store()->TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);

  return true;
}

void MetricsService::RegisterMetricsProvider(
    std::unique_ptr<MetricsProvider> provider) {
  DCHECK_EQ(CONSTRUCTED, state_);
  delegating_provider_.RegisterMetricsProvider(std::move(provider));
}

void MetricsService::CheckForClonedInstall() {
  state_manager_->CheckForClonedInstall();
}

bool MetricsService::ShouldResetClientIdsOnClonedInstall() {
  return state_manager_->ShouldResetClientIdsOnClonedInstall();
}

std::unique_ptr<MetricsLog> MetricsService::CreateLog(
    MetricsLog::LogType log_type) {
  auto new_metrics_log = std::make_unique<MetricsLog>(
      state_manager_->client_id(), session_id_, log_type, client_);
  new_metrics_log->AssignRecordId(local_state_);

#if BUILDFLAG(IS_CHROMEOS_ASH)
  std::optional<std::string> user_id = GetCurrentUserId();
  if (user_id.has_value())
    new_metrics_log->SetUserId(user_id.value());
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

  return new_metrics_log;
}

void MetricsService::AddLogsObserver(
    MetricsLogsEventManager::Observer* observer) {
  logs_event_manager_.AddObserver(observer);
}

void MetricsService::RemoveLogsObserver(
    MetricsLogsEventManager::Observer* observer) {
  logs_event_manager_.RemoveObserver(observer);
}

base::CallbackListSubscription MetricsService::AddEnablementObserver(
    const base::RepeatingCallback<void(bool)>& observer) {
  return enablement_observers_.Add(observer);
}

void MetricsService::SetPersistentSystemProfile(
    const std::string& serialized_proto,
    bool complete) {
  GlobalPersistentSystemProfile::GetInstance()->SetSystemProfile(
      serialized_proto, complete);
}

// static
std::string MetricsService::RecordCurrentEnvironmentHelper(
    MetricsLog* log,
    PrefService* local_state,
    DelegatingProvider* delegating_provider) {
  const SystemProfileProto& system_profile =
      log->RecordEnvironment(delegating_provider);
  EnvironmentRecorder recorder(local_state);
  return recorder.SerializeAndRecordEnvironmentToPrefs(system_profile);
}

void MetricsService::RecordCurrentEnvironment(MetricsLog* log, bool complete) {
  DCHECK(client_);
  std::string serialized_proto =
      RecordCurrentEnvironmentHelper(log, local_state_, &delegating_provider_);

  SetPersistentSystemProfile(serialized_proto, complete);
  client_->OnEnvironmentUpdate(&serialized_proto);

  // The call to SetPersistentSystemProfile() above will have written the
  // current system profile to persistent memory. Because it may span over
  // multiple pages, it is possible that the system profile may become corrupted
  // if only certain pages were flushed to disk. For example, say we overwrite
  // the persistent memory's system profile with a newer one, and that it spans
  // over two pages. Then, the OS flushes the second page, but not the first
  // page. If the device is shut down unexpectedly, e.g. due to a power outage,
  // then the first page will contain the beginning of the old system profile,
  // while the second page will contain the ending of the new system profile,
  // resulting in an unparsable system profile and rendering the whole file
  // useless. So, manually schedule a flush every time we overwrite the system
  // profile with a new one to ensure we don't ever get a corrupted one.
  if (base::FeatureList::IsEnabled(
          features::kFlushPersistentSystemProfileOnWrite)) {
    base::ThreadPool::PostTask(
        FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()},
        base::BindOnce([]() {
          if (auto* allocator = base::GlobalHistogramAllocator::Get()) {
            // Ideally, we'd just call Flush() with the |sync| parameter set to
            // false on the main thread, but Windows does not support async
            // flushing, so do this synchronously on a background thread
            // instead.
            allocator->memory_allocator()->Flush(/*sync=*/true);
          }
        }));
  }
}

void MetricsService::PrepareProviderMetricsLogDone(
    std::unique_ptr<IndependentMetricsLoader> loader,
    bool success) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(independent_loader_active_);
  DCHECK(loader);

  if (success) {
    // If not already done, finalize the log that was created independently by
    // the metrics provider.
    if (!loader->HasFinalizedLog()) {
      loader->FinalizeLog();
    }

    StoreFinalizedLog(MetricsLog::INDEPENDENT_LOG,
                      MetricsLogsEventManager::CreateReason::kIndependent,
                      /*done_callback=*/base::DoNothing(),
                      loader->ReleaseFinalizedLog());
  }

  independent_loader_active_ = false;
}

bool MetricsService::PrepareProviderMetricsLog() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // If something is still pending, stop now and indicate that there is
  // still work to do.
  if (independent_loader_active_)
    return true;

  // Check each provider in turn for data.
  for (auto& provider : delegating_provider_.GetProviders()) {
    if (provider->HasIndependentMetrics()) {
      // Create a new log. This will have some default values injected in it
      // but those will be overwritten when an embedded profile is extracted.
      constexpr MetricsLog::LogType log_type = MetricsLog::INDEPENDENT_LOG;
      std::unique_ptr<MetricsLog> log = CreateLog(log_type);
      log->AssignFinalizedRecordId(local_state_);

      // Note that something is happening. This must be set before the
      // operation is requested in case the loader decides to do everything
      // immediately rather than as a background task.
      independent_loader_active_ = true;

      // Give the new log to a loader for management and then run it on the
      // provider that has something to give. A copy of the pointer is needed
      // because the unique_ptr may get moved before the value can be used
      // to call Run().
      std::unique_ptr<IndependentMetricsLoader> loader =
          std::make_unique<IndependentMetricsLoader>(
              std::move(log), client_->GetVersionString(),
              log_store()->GetSigningKeyForLogType(log_type));
      IndependentMetricsLoader* loader_ptr = loader.get();
      loader_ptr->Run(
          base::BindOnce(&MetricsService::PrepareProviderMetricsLogDone,
                         self_ptr_factory_.GetWeakPtr(), std::move(loader)),
          provider.get());

      // Something was found so there may still be more work to do.
      return true;
    }
  }

  // Nothing was found so indicate there is no more work to do.
  return false;
}

void MetricsService::PrepareProviderMetricsTask() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  bool found = PrepareProviderMetricsLog();
  base::TimeDelta next_check = found ? base::Seconds(5) : base::Minutes(15);
  base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
      FROM_HERE,
      base::BindOnce(&MetricsService::PrepareProviderMetricsTask,
                     self_ptr_factory_.GetWeakPtr()),
      next_check);
}

void MetricsService::UpdateLastLiveTimestampTask() {
  state_manager_->clean_exit_beacon()->UpdateLastLiveTimestamp();

  // Schecule the next update.
  StartUpdatingLastLiveTimestamp();
}

bool MetricsService::IsTooEarlyToCloseLog() {
  // When kMetricsServiceAllowEarlyLogClose is enabled, start closing logs as
  // soon as the first log is opened (|state_| is set to INIT_TASK_SCHEDULED
  // when the first log is opened, see OpenNewLog()). Otherwise, only start
  // closing logs when logs have started being sent.
  return base::FeatureList::IsEnabled(
             features::kMetricsServiceAllowEarlyLogClose)
             ? state_ < INIT_TASK_SCHEDULED
             : state_ < SENDING_LOGS;
}

void MetricsService::OnClonedInstallDetected() {
  // Purge all logs, as they may come from a previous install. Unfortunately,
  // since the cloned install detector works asynchronously, it is possible that
  // this is called after logs were already sent. However, practically speaking,
  // this should not happen, since logs are only sent late into the session.
  reporting_service_.metrics_log_store()->Purge();
}

// static
MetricsService::FinalizedLog MetricsService::SnapshotDeltasAndFinalizeLog(
    std::unique_ptr<MetricsLogHistogramWriter> log_histogram_writer,
    std::unique_ptr<MetricsLog> log,
    bool truncate_events,
    std::optional<ChromeUserMetricsExtension::RealLocalTime> close_time,
    std::string&& current_app_version,
    std::string&& signing_key) {
  log_histogram_writer->SnapshotStatisticsRecorderDeltas();
  return FinalizeLog(std::move(log), truncate_events, std::move(close_time),
                     current_app_version, signing_key);
}

// static
MetricsService::FinalizedLog
MetricsService::SnapshotUnloggedSamplesAndFinalizeLog(
    MetricsLogHistogramWriter* log_histogram_writer,
    std::unique_ptr<MetricsLog> log,
    bool truncate_events,
    std::optional<ChromeUserMetricsExtension::RealLocalTime> close_time,
    std::string&& current_app_version,
    std::string&& signing_key) {
  log_histogram_writer->SnapshotStatisticsRecorderUnloggedSamples();
  return FinalizeLog(std::move(log), truncate_events, std::move(close_time),
                     current_app_version, signing_key);
}

// static
MetricsService::FinalizedLog MetricsService::FinalizeLog(
    std::unique_ptr<MetricsLog> log,
    bool truncate_events,
    std::optional<ChromeUserMetricsExtension::RealLocalTime> close_time,
    const std::string& current_app_version,
    const std::string& signing_key) {
  DCHECK(log->uma_proto()->has_record_id());
  std::string log_data;
  log->FinalizeLog(truncate_events, current_app_version, std::move(close_time),
                   &log_data);

  FinalizedLog finalized_log;
  finalized_log.uncompressed_log_size = log_data.size();
  finalized_log.log_info = std::make_unique<UnsentLogStore::LogInfo>();
  finalized_log.log_info->Init(log_data, signing_key, log->log_metadata());
  return finalized_log;
}

}  // namespace metrics
