// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/tracing/tracing_scenario.h"

#include <memory>
#include <utility>

#include "base/hash/md5.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted_memory.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "base/token.h"
#include "base/tracing/trace_time.h"
#include "components/variations/hashing.h"
#include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/browser/tracing/triggers_data_source.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "services/tracing/public/cpp/perfetto/perfetto_config.h"
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
#include "services/tracing/public/cpp/tracing_features.h"
#include "third_party/perfetto/protos/perfetto/config/track_event/track_event_config.gen.h"

namespace content {

namespace {

constexpr uint32_t kStartupTracingTimeoutMs = 30 * 1000;  // 30 sec

}  // namespace

void TracingScenario::TracingSessionDeleter::operator()(
    perfetto::TracingSession* ptr) const {
  ptr->SetOnErrorCallback({});
  delete ptr;
}

class TracingScenario::TraceReader
    : public base::RefCountedThreadSafe<TraceReader> {
 public:
  explicit TraceReader(TracingSession tracing_session, base::Token trace_uuid)
      : tracing_session(std::move(tracing_session)), trace_uuid(trace_uuid) {}

  TracingSession tracing_session;
  base::Token trace_uuid;
  std::string serialized_trace;

  static void ReadTrace(scoped_refptr<TracingScenario::TraceReader> reader,
                        base::WeakPtr<TracingScenario> scenario,
                        scoped_refptr<base::SequencedTaskRunner> task_runner,
                        const BackgroundTracingRule* triggered_rule) {
    base::TimeTicks read_start_time = base::TimeTicks::Now();
    TRACE_EVENT_BEGIN(
        "tracing.background", "ReadTrace",
        perfetto::NamedTrack::FromPointer("Scenario.ReadTrace", reader.get()));
    reader->tracing_session->ReadTrace(
        [task_runner, scenario, reader, triggered_rule, read_start_time](
            perfetto::TracingSession::ReadTraceCallbackArgs args) mutable {
          if (args.size) {
            reader->serialized_trace.append(args.data, args.size);
          }
          if (!args.has_more) {
            TRACE_EVENT_END("tracing.background",
                            perfetto::NamedTrack::FromPointer(
                                "Scenario.ReadTrace", reader.get()));
            base::UmaHistogramMediumTimes(
                "Tracing.Background.ReadTraceDuration",
                base::TimeTicks::Now() - read_start_time);
            task_runner->PostTask(
                FROM_HERE, base::BindOnce(&TracingScenario::OnFinalizingDone,
                                          scenario, reader->trace_uuid,
                                          std::move(reader->serialized_trace),
                                          std::move(reader->tracing_session),
                                          triggered_rule));
          }
        });
  }

 private:
  friend class base::RefCountedThreadSafe<TraceReader>;

  ~TraceReader() = default;
};

using Metrics = BackgroundTracingManagerImpl::Metrics;

TracingScenarioBase::~TracingScenarioBase() = default;

void TracingScenarioBase::Disable() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  for (auto& rule : start_rules_) {
    rule->Uninstall();
  }
  for (auto& rule : stop_rules_) {
    rule->Uninstall();
  }
  for (auto& rule : upload_rules_) {
    rule->Uninstall();
  }
}

void TracingScenarioBase::Enable() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  for (auto& rule : start_rules_) {
    rule->Install(base::BindRepeating(&TracingScenarioBase::OnStartTrigger,
                                      base::Unretained(this)));
  }
}

uint32_t TracingScenarioBase::TriggerNameHash(
    const BackgroundTracingRule* triggered_rule) const {
  return variations::HashName(
      base::StrCat({scenario_name(), ".", triggered_rule->rule_name()}));
}

TracingScenarioBase::TracingScenarioBase(std::string scenario_name)
    : scenario_name_(std::move(scenario_name)),
      task_runner_(base::SequencedTaskRunner::GetCurrentDefault()) {}

// static
std::unique_ptr<NestedTracingScenario> NestedTracingScenario::Create(
    const perfetto::protos::gen::NestedScenarioConfig& config,
    Delegate* scenario_delegate) {
  auto scenario =
      base::WrapUnique(new NestedTracingScenario(config, scenario_delegate));
  if (!scenario->Initialize(config)) {
    return nullptr;
  }
  return scenario;
}

NestedTracingScenario::NestedTracingScenario(
    const perfetto::protos::gen::NestedScenarioConfig& config,
    Delegate* scenario_delegate)
    : TracingScenarioBase(config.scenario_name()),
      scenario_delegate_(scenario_delegate) {}

NestedTracingScenario::~NestedTracingScenario() = default;

void NestedTracingScenario::Disable() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  SetState(State::kDisabled);
  TracingScenarioBase::Disable();
}

void NestedTracingScenario::Enable() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK_EQ(current_state_, State::kDisabled);
  SetState(State::kEnabled);
  TracingScenarioBase::Enable();
}

bool NestedTracingScenario::Initialize(
    const perfetto::protos::gen::NestedScenarioConfig& config) {
  return BackgroundTracingRule::Append(config.start_rules(), start_rules_) &&
         BackgroundTracingRule::Append(config.stop_rules(), stop_rules_) &&
         BackgroundTracingRule::Append(config.upload_rules(), upload_rules_);
}

bool NestedTracingScenario::OnStartTrigger(
    const BackgroundTracingRule* triggered_rule) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (current_state() != State::kEnabled) {
    return false;
  }
  TriggersDataSource::EmitTrigger(triggered_rule);
  base::UmaHistogramSparse("Tracing.Background.Scenario.Trigger.Start",
                           TriggerNameHash(triggered_rule));
  for (auto& rule : start_rules_) {
    rule->Uninstall();
  }
  for (auto& rule : stop_rules_) {
    rule->Install(base::BindRepeating(&NestedTracingScenario::OnStopTrigger,
                                      base::Unretained(this)));
  }
  for (auto& rule : upload_rules_) {
    rule->Install(base::BindRepeating(&NestedTracingScenario::OnUploadTrigger,
                                      base::Unretained(this)));
  }
  scenario_delegate_->OnNestedScenarioStart(this);
  SetState(State::kActive);
  return true;
}

bool NestedTracingScenario::OnStopTrigger(
    const BackgroundTracingRule* triggered_rule) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  TriggersDataSource::EmitTrigger(triggered_rule);
  base::UmaHistogramSparse("Tracing.Background.Scenario.Trigger.Stop",
                           TriggerNameHash(triggered_rule));
  for (auto& rule : stop_rules_) {
    rule->Uninstall();
  }
  SetState(State::kStopping);
  scenario_delegate_->OnNestedScenarioStop(this);
  return true;
}

bool NestedTracingScenario::OnUploadTrigger(
    const BackgroundTracingRule* triggered_rule) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  TriggersDataSource::EmitTrigger(triggered_rule);
  base::UmaHistogramSparse("Tracing.Background.Scenario.Trigger.Upload",
                           TriggerNameHash(triggered_rule));

  for (auto& rule : stop_rules_) {
    rule->Uninstall();
  }
  for (auto& rule : upload_rules_) {
    rule->Uninstall();
  }
  SetState(State::kDisabled);
  scenario_delegate_->OnNestedScenarioUpload(this, triggered_rule);
  return true;
}

void NestedTracingScenario::SetState(State new_state) {
  current_state_ = new_state;
}

// static
std::unique_ptr<TracingScenario> TracingScenario::Create(
    const perfetto::protos::gen::ScenarioConfig& config,
    bool enable_privacy_filter,
    bool is_local_scenario,
    bool enable_package_name_filter,
    bool request_startup_tracing,
    Delegate* scenario_delegate) {
  auto scenario = base::WrapUnique(
      new TracingScenario(config, scenario_delegate, enable_privacy_filter,
                          is_local_scenario, request_startup_tracing));
  if (!scenario->Initialize(config, enable_package_name_filter)) {
    return nullptr;
  }
  return scenario;
}

TracingScenario::TracingScenario(
    const perfetto::protos::gen::ScenarioConfig& config,
    Delegate* scenario_delegate,
    bool enable_privacy_filter,
    bool is_local_scenario,
    bool request_startup_tracing)
    : TracingScenarioBase(config.scenario_name()),
      description_(config.scenario_description()),
      privacy_filtering_enabled_(enable_privacy_filter),
      is_local_scenario_(is_local_scenario),
      request_startup_tracing_(request_startup_tracing),
      use_system_backend_(config.use_system_backend()),
      trace_config_(config.trace_config()),
      scenario_delegate_(scenario_delegate) {}

TracingScenario::~TracingScenario() = default;

bool TracingScenario::Initialize(
    const perfetto::protos::gen::ScenarioConfig& config,
    bool enable_package_name_filter) {
  bool enable_system_backend =
      use_system_backend_ && tracing::SystemBackgroundTracingEnabled();
  if (!tracing::AdaptPerfettoConfigForChrome(
          &trace_config_, privacy_filtering_enabled_,
          enable_package_name_filter,
          enable_system_backend)) {
    return false;
  }
  for (const auto& nested_config : config.nested_scenarios()) {
    auto nested_scenario = NestedTracingScenario::Create(nested_config, this);
    if (!nested_scenario) {
      return false;
    }
    nested_scenarios_.push_back(std::move(nested_scenario));
  }
  return BackgroundTracingRule::Append(config.start_rules(), start_rules_) &&
         BackgroundTracingRule::Append(config.stop_rules(), stop_rules_) &&
         BackgroundTracingRule::Append(config.upload_rules(), upload_rules_) &&
         BackgroundTracingRule::Append(config.setup_rules(), setup_rules_);
}

void TracingScenario::Disable() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK_EQ(current_state_, State::kEnabled);
  SetState(State::kDisabled);
  for (auto& rule : setup_rules_) {
    rule->Uninstall();
  }
  TracingScenarioBase::Disable();
}

void TracingScenario::Enable() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK_EQ(current_state_, State::kDisabled);
  SetState(State::kEnabled);
  for (auto& rule : setup_rules_) {
    rule->Install(base::BindRepeating(&TracingScenario::OnSetupTrigger,
                                      base::Unretained(this)));
  }
  TracingScenarioBase::Enable();
}

void TracingScenario::Abort() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TracingScenarioBase::Disable();
  DisableNestedScenarios();
  SetState(State::kStopping);
  tracing_session_->Stop();
}

void TracingScenario::GenerateMetadataProto(
    perfetto::protos::pbzero::ChromeMetadataPacket* metadata) {
  auto* background_tracing_metadata =
      metadata->set_background_tracing_metadata();

  uint32_t scenario_name_hash = variations::HashName(scenario_name());
  background_tracing_metadata->set_scenario_name_hash(scenario_name_hash);

  if (triggered_rule_) {
    auto* triggered_rule = background_tracing_metadata->set_triggered_rule();
    triggered_rule_->GenerateMetadataProto(triggered_rule);
  }
}

std::unique_ptr<perfetto::TracingSession>
TracingScenario::CreateTracingSession() {
  // If the scenario is configured to use the system backend, the platform
  // should support it (see OnSetupTrigger()). Otherwise this is a configuration
  // error.
  DCHECK(!use_system_backend_ || tracing::SystemBackgroundTracingEnabled());
  auto backend_type =
      (use_system_backend_ && tracing::SystemBackgroundTracingEnabled())
          ? perfetto::BackendType::kSystemBackend
          : perfetto::BackendType::kCustomBackend;
  return perfetto::Tracing::NewTrace(backend_type);
}

void TracingScenario::SetupTracingSession() {
  DCHECK(!tracing_session_);
  tracing_session_ = CreateTracingSession();
  session_id_ = base::Token::CreateRandom();
  session_unguessable_name_ = base::UnguessableToken::Create();
  trace_config_.set_trace_uuid_lsb(session_id_.high());
  trace_config_.set_trace_uuid_msb(session_id_.low());
  trace_config_.set_unique_session_name(session_unguessable_name_.ToString());
  tracing_session_->Setup(trace_config_);
  tracing_session_->SetOnStartCallback([task_runner = task_runner_,
                                        weak_ptr = GetWeakPtr()]() {
    task_runner->PostTask(
        FROM_HERE, base::BindOnce(&TracingScenario::OnTracingStart, weak_ptr));
  });
  tracing_session_->SetOnErrorCallback(
      [task_runner = task_runner_,
       weak_ptr = GetWeakPtr()](perfetto::TracingError error) {
        task_runner->PostTask(
            FROM_HERE,
            base::BindOnce(&TracingScenario::OnTracingError, weak_ptr, error));
      });
}

void TracingScenario::OnNestedScenarioStart(
    NestedTracingScenario* active_scenario) {
  CHECK_EQ(active_scenario_, nullptr);
  active_scenario_ = active_scenario;
  // Other nested scenarios are disabled.
  for (auto& scenario : nested_scenarios_) {
    if (scenario.get() == active_scenario_) {
      continue;
    }
    scenario->Disable();
  }
  // If in `kSetup`, the tracing session is started.
  if (current_state() == State::kSetup) {
    OnStartTrigger(nullptr);
  }
}

void TracingScenario::OnNestedScenarioStop(
    NestedTracingScenario* nested_scenario) {
  CHECK_EQ(active_scenario_, nested_scenario);
  // Stop the scenario asynchronously in case an upload trigger is triggered in
  // the same task.
  on_nested_stopped_.Reset(base::BindOnce(
      [](TracingScenario* self, NestedTracingScenario* nested_scenario) {
        CHECK_EQ(nested_scenario->current_state(),
                 NestedTracingScenario::State::kStopping);
        CHECK_EQ(self->current_state_, State::kRecording);
        CHECK_EQ(self->active_scenario_, nested_scenario);
        nested_scenario->Disable();
        self->active_scenario_ = nullptr;
        // All nested scenarios are re-enabled.
        for (auto& scenario : self->nested_scenarios_) {
          scenario->Enable();
        }
      },
      base::Unretained(this), nested_scenario));
  task_runner_->PostTask(FROM_HERE, on_nested_stopped_.callback());
}

void TracingScenario::OnNestedScenarioUpload(
    NestedTracingScenario* nested_scenario,
    const BackgroundTracingRule* triggered_rule) {
  DCHECK_EQ(active_scenario_, nested_scenario);
  CHECK_EQ(nested_scenario->current_state(),
           NestedTracingScenario::State::kDisabled);
  CHECK(current_state_ == State::kStarting ||
        current_state_ == State::kRecording)
      << static_cast<int>(current_state_);

  on_nested_stopped_.Cancel();
  active_scenario_ = nullptr;
  SetState(State::kCloning);
  // Skip cloning if the trace isn't allowed to save or is still starting.
  if (current_state_ == State::kStarting ||
      !scenario_delegate_->OnScenarioCloned(this)) {
    OnTracingCloned();
    return;
  }
  TracingSession cloned_session = CreateTracingSession();
  auto reader = base::MakeRefCounted<TraceReader>(std::move(cloned_session),
                                                  base::Token());
  perfetto::TracingSession::CloneTraceArgs args{
      .unique_session_name = session_unguessable_name_.ToString()};
  reader->tracing_session->CloneTrace(
      args,
      [task_runner = task_runner_, weak_ptr = GetWeakPtr(), reader,
       triggered_rule](perfetto::TracingSession::CloneTraceCallbackArgs args) {
        task_runner->PostTask(
            FROM_HERE,
            base::BindOnce(&TracingScenario::OnTracingCloned, weak_ptr));
        if (!args.success) {
          return;
        }
        reader->trace_uuid = base::Token(args.uuid_lsb, args.uuid_msb);
        TraceReader::ReadTrace(reader, weak_ptr, task_runner, triggered_rule);
      });
}

bool TracingScenario::OnSetupTrigger(
    const BackgroundTracingRule* triggered_rule) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Skip this scenario if it requires the system backend, but the system
  // backend is unavailable (a configuration error).
  if (use_system_backend_ && !tracing::SystemBackgroundTracingEnabled()) {
    return false;
  }

  if (!scenario_delegate_->OnScenarioActive(this)) {
    return false;
  }

  for (auto& rule : setup_rules_) {
    rule->Uninstall();
  }
  for (auto& rule : stop_rules_) {
    rule->Install(base::BindRepeating(&TracingScenario::OnStopTrigger,
                                      base::Unretained(this)));
  }
  for (auto& rule : upload_rules_) {
    rule->Install(base::BindRepeating(&TracingScenario::OnUploadTrigger,
                                      base::Unretained(this)));
  }
  for (auto& scenario : nested_scenarios_) {
    scenario->Enable();
  }
  SetState(State::kSetup);
  SetupTracingSession();
  return true;
}

bool TracingScenario::OnStartTrigger(
    const BackgroundTracingRule* triggered_rule) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (triggered_rule) {
    base::UmaHistogramSparse("Tracing.Background.Scenario.Trigger.Start",
                             TriggerNameHash(triggered_rule));
  }

  if (current_state() == State::kEnabled) {
    // Move to setup before starting the session below.
    if (!OnSetupTrigger(triggered_rule)) {
      return false;
    }
  } else if (current_state() != State::kSetup) {
    return false;
  }

  for (auto& rule : start_rules_) {
    rule->Uninstall();
  }

  SetState(State::kStarting);

  if (request_startup_tracing_) {
    perfetto::Tracing::SetupStartupTracingOpts opts;
    opts.timeout_ms = kStartupTracingTimeoutMs;
    opts.backend = perfetto::kCustomBackend;
    perfetto::Tracing::SetupStartupTracingBlocking(trace_config_, opts);
  }

  tracing_session_->SetOnStopCallback([task_runner = task_runner_,
                                       weak_ptr = GetWeakPtr()]() {
    task_runner->PostTask(
        FROM_HERE, base::BindOnce(&TracingScenario::OnTracingStop, weak_ptr));
  });
  tracing_session_->Start();
  if (triggered_rule) {
    TriggersDataSource::EmitTrigger(triggered_rule);
  }
  return true;
}

bool TracingScenario::OnStopTrigger(
    const BackgroundTracingRule* triggered_rule) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TriggersDataSource::EmitTrigger(triggered_rule);
  base::UmaHistogramSparse("Tracing.Background.Scenario.Trigger.Stop",
                           TriggerNameHash(triggered_rule));
  for (auto& rule : stop_rules_) {
    rule->Uninstall();
  }
  if (active_scenario_) {
    on_nested_stopped_.Cancel();
    active_scenario_->Disable();
    active_scenario_ = nullptr;
  } else {
    for (auto& nested_scenario : nested_scenarios_) {
      nested_scenario->Disable();
    }
  }
  if (current_state_ == State::kSetup) {
    CHECK_EQ(nullptr, active_scenario_);
    // Tear down the session since we haven't been tracing yet.
    for (auto& rule : upload_rules_) {
      rule->Uninstall();
    }
    for (auto& rule : start_rules_) {
      rule->Uninstall();
    }
    tracing_session_.reset();
    SetState(State::kDisabled);
    scenario_delegate_->OnScenarioIdle(this);
    return true;
  } else if (current_state_ == State::kStarting) {
    for (auto& rule : upload_rules_) {
      rule->Uninstall();
    }
  }
  tracing_session_->Stop();
  SetState(State::kStopping);
  return true;
}

bool TracingScenario::OnUploadTrigger(
    const BackgroundTracingRule* triggered_rule) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TriggersDataSource::EmitTrigger(triggered_rule);
  base::UmaHistogramSparse("Tracing.Background.Scenario.Trigger.Upload",
                           TriggerNameHash(triggered_rule));
  for (auto& rule : stop_rules_) {
    rule->Uninstall();
  }
  for (auto& rule : upload_rules_) {
    rule->Uninstall();
  }
  DisableNestedScenarios();
  // Setup is ignored.
  if (current_state_ == State::kSetup) {
    for (auto& rule : start_rules_) {
      rule->Uninstall();
    }
    tracing_session_.reset();
    SetState(State::kDisabled);
    scenario_delegate_->OnScenarioIdle(this);
    return true;
  } else if (current_state_ == State::kStarting) {
    SetState(State::kStopping);
    tracing_session_->Stop();
    return true;
  }
  CHECK(current_state_ == State::kRecording ||
        current_state_ == State::kStopping || current_state_ == State::kCloning)
      << static_cast<int>(current_state_);
  triggered_rule_ = triggered_rule;
  if (current_state_ != State::kStopping) {
    tracing_session_->Stop();
  }
  SetState(State::kFinalizing);
  return true;
}

void TracingScenario::OnTracingError(perfetto::TracingError error) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!tracing_session_) {
    CHECK(current_state_ == State::kDisabled ||
          current_state_ == State::kEnabled)
        << static_cast<int>(current_state_);
    return;
  }
  for (auto& rule : start_rules_) {
    rule->Uninstall();
  }
  for (auto& rule : stop_rules_) {
    rule->Uninstall();
  }
  for (auto& rule : upload_rules_) {
    rule->Uninstall();
  }
  DisableNestedScenarios();
  SetState(State::kStopping);
  tracing_session_->Stop();
  scenario_delegate_->OnScenarioError(this, error);
}

void TracingScenario::OnTracingStart() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  SetState(State::kRecording);
  scenario_delegate_->OnScenarioRecording(this);
}

void TracingScenario::OnTracingStop() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (current_state_ != State::kStopping &&
      current_state_ != State::kFinalizing) {
    // Tracing was stopped internally.
    CHECK(current_state_ == State::kSetup ||
          current_state_ == State::kStarting ||
          current_state_ == State::kRecording ||
          current_state_ == State::kCloning)
        << static_cast<int>(current_state_);
    for (auto& rule : start_rules_) {
      rule->Uninstall();
    }
    for (auto& rule : stop_rules_) {
      rule->Uninstall();
    }
  }
  for (auto& rule : upload_rules_) {
    rule->Uninstall();
  }
  DisableNestedScenarios();
  bool should_upload = (current_state_ == State::kFinalizing);
  auto tracing_session = std::move(tracing_session_);
  SetState(State::kDisabled);
  if (!scenario_delegate_->OnScenarioIdle(this)) {
    should_upload = false;
  }
  if (!should_upload) {
    tracing_session.reset();
    return;
  }
  DCHECK(triggered_rule_);
  auto reader = base::MakeRefCounted<TraceReader>(std::move(tracing_session),
                                                  session_id_);
  TraceReader::ReadTrace(reader, GetWeakPtr(), task_runner_,
                         triggered_rule_.get());
}

void TracingScenario::OnTracingCloned() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (current_state_ == State::kCloning) {
    SetState(State::kRecording);
  }
  if (current_state_ != State::kStarting &&
      current_state_ != State::kRecording) {
    // Tracing was stopped.
    return;
  }
  // All nested scenarios are re-enabled.
  for (auto& scenario : nested_scenarios_) {
    scenario->Enable();
  }
}

void TracingScenario::OnFinalizingDone(
    base::Token trace_uuid,
    std::string&& serialized_trace,
    TracingSession tracing_session,
    const BackgroundTracingRule* triggered_rule) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  tracing_session.reset();
  scenario_delegate_->SaveTrace(this, trace_uuid, triggered_rule,
                                std::move(serialized_trace));
}

void TracingScenario::DisableNestedScenarios() {
  if (active_scenario_) {
    CHECK(current_state_ == State::kRecording ||
          current_state_ == State::kStarting ||
          current_state_ == State::kStopping)
        << static_cast<int>(current_state_);
    on_nested_stopped_.Cancel();
    active_scenario_->Disable();
    active_scenario_ = nullptr;
  } else if (current_state_ == State::kRecording ||
             current_state_ == State::kSetup ||
             current_state_ == State::kStarting) {
    for (auto& nested_scenario : nested_scenarios_) {
      nested_scenario->Disable();
    }
  }
}

void TracingScenario::SetState(State new_state) {
  if (new_state == State::kEnabled || new_state == State::kDisabled ||
      new_state == State::kCloning) {
    if (new_state == State::kEnabled || new_state == State::kDisabled) {
      CHECK_EQ(nullptr, tracing_session_);
    }
    CHECK_EQ(nullptr, active_scenario_);
    for (auto& scenario : nested_scenarios_) {
      CHECK_EQ(NestedTracingScenario::State::kDisabled,
               scenario->current_state());
    }
  }
  current_state_ = new_state;
}

base::WeakPtr<TracingScenario> TracingScenario::GetWeakPtr() {
  return weak_ptr_factory_.GetWeakPtr();
}

}  // namespace content
