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

#include <stddef.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/process_handle.h"
#include "base/profiler/module_cache.h"
#include "base/run_loop.h"
#include "base/strings/pattern.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_tokenizer.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h"
#include "base/test/trace_event_analyzer.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "content/browser/devtools/protocol/devtools_protocol_test_support.h"
#include "content/browser/tracing/background_startup_tracing_observer.h"
#include "content/browser/tracing/background_tracing_active_scenario.h"
#include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/browser/tracing/background_tracing_rule.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "services/tracing/perfetto/privacy_filtering_check.h"
#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
#include "services/tracing/public/cpp/tracing_features.h"
#include "third_party/re2/src/re2/re2.h"
#include "third_party/zlib/zlib.h"

#if defined(OS_POSIX)
// Used by PerfettoSystemBackgroundScenario, nogncheck is required because this
// is only included and used on Android.
#include "services/tracing/perfetto/system_test_utils.h"  // nogncheck
#include "services/tracing/perfetto/test_utils.h"         // nogncheck

namespace content {
namespace {
perfetto::TraceConfig StopTracingTriggerConfig(
    const std::string& trigger_name) {
  perfetto::TraceConfig trace_config;
  trace_config.add_buffers()->set_size_kb(1024);
  auto* ds_config = trace_config.add_data_sources()->mutable_config();
  ds_config->set_name("org.chromium.trace_event");
  ds_config = trace_config.add_data_sources()->mutable_config();
  ds_config->set_name("org.chromium.trace_metadata");
  auto* trigger_cfg = trace_config.mutable_trigger_config();
  trigger_cfg->set_trigger_mode(
      perfetto::TraceConfig::TriggerConfig::STOP_TRACING);
  trigger_cfg->set_trigger_timeout_ms(15000);
  auto* trigger = trigger_cfg->add_triggers();
  trigger->set_name(trigger_name);
  trigger->set_stop_delay_ms(1);
  return trace_config;
}

void SetSystemProducerSocketAndChecksAsync(const std::string& producer_socket) {
  // We need to let the PosixSystemProducer know the MockSystemService socket
  // address and that if we're running on Android devices older then Pie to
  // still connect.
  tracing::PerfettoTracedProcess::GetTaskRunner()
      ->GetOrCreateTaskRunner()
      ->PostTask(
          FROM_HERE,
          base::BindOnce(
              [](const std::string& producer_socket) {
                // The only other type of system producer is
                // PosixSystemProducer so this assert ensures that the
                // static_cast below is safe.
                ASSERT_FALSE(tracing::PerfettoTracedProcess::Get()
                                 ->system_producer()
                                 ->IsDummySystemProducerForTesting());
                auto* producer = static_cast<tracing::PosixSystemProducer*>(
                    tracing::PerfettoTracedProcess::Get()->system_producer());
                producer->SetNewSocketForTesting(producer_socket.c_str());
                producer->SetDisallowPreAndroidPieForTesting(false);
              },
              producer_socket));
}

std::unique_ptr<tracing::MockConsumer> CreateDefaultConsumer(
    perfetto::TraceConfig trace_config,
    perfetto::TracingService* service,
    base::RunLoop* no_more_packets) {
  return std::unique_ptr<tracing::MockConsumer>(new tracing::MockConsumer(
      {"org.chromium.trace_event", "org.chromium.trace_metadata"}, service,
      [no_more_packets](bool has_more) {
        if (!has_more) {
          no_more_packets->Quit();
        }
      },
      std::move(trace_config)));
}
}  // namespace
}  // namespace content
#endif  // defined(OS_POSIX)

using base::trace_event::TraceLog;

namespace content {
namespace {

class TestStartupPreferenceManagerImpl
    : public BackgroundStartupTracingObserver::PreferenceManager {
 public:
  void SetBackgroundStartupTracingEnabled(bool enabled) override {
    enabled_ = enabled;
  }

  bool GetBackgroundStartupTracingEnabled() const override { return enabled_; }

 private:
  bool enabled_ = false;
};

// Wait until |condition| returns true.
void WaitForCondition(base::RepeatingCallback<bool()> condition,
                      const std::string& description) {
  const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(30);
  const base::TimeTicks start_time = base::TimeTicks::Now();
  while (!condition.Run() && (base::TimeTicks::Now() - start_time < kTimeout)) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  }
  ASSERT_TRUE(condition.Run())
      << "Timeout waiting for condition: " << description;
}

// An helper class that observes tracing states transition and allows
// synchronisation with tests. The class adds itself as a tracelog
// enable state observer and provides methods to wait for a given state.
//
// Usage:
//   TestTraceLogHelper tracelog_helper;
//   [... start tracing ...]
//   tracelog_helper.WaitForStartTracing();
//   [... stop tracing ...]
//   tracing_controller->StopTracing();
//   tracelog_helper.WaitForStopTracing();
class TestTraceLogHelper : public TraceLog::EnabledStateObserver {
 public:
  TestTraceLogHelper() {
    EXPECT_FALSE(TraceLog::GetInstance()->IsEnabled());
    TraceLog::GetInstance()->AddEnabledStateObserver(this);
  }

  ~TestTraceLogHelper() override {
    EXPECT_FALSE(TraceLog::GetInstance()->IsEnabled());
    TraceLog::GetInstance()->RemoveEnabledStateObserver(this);

    // Ensures tracing got enabled/disabled only once.
    EXPECT_EQ(1, enable_count);
    EXPECT_EQ(1, disable_count);
  }

  void OnTraceLogEnabled() override {
    wait_for_start_tracing_.QuitWhenIdle();
    enable_count++;
  }

  void OnTraceLogDisabled() override {
    wait_for_stop_tracing_.QuitWhenIdle();
    disable_count++;
  }

  void WaitForStartTracing() { wait_for_start_tracing_.Run(); }
  void WaitForStopTracing() { wait_for_stop_tracing_.Run(); }

 private:
  int enable_count = 0;
  int disable_count = 0;
  base::RunLoop wait_for_start_tracing_;
  base::RunLoop wait_for_stop_tracing_;
};

// An helper class that observes background tracing states transition and
// allows synchronisation with tests. The class adds itself as a backgrond
// tracing enabled state observer. It provides methods to wait for a given
// state.
//
// Usage:
//   TestBackgroundTracingHelper background_tracing_helper;
//   [... set a background tracing scenario ...]
//   background_tracing_helper.WaitForScenarioActivated();
//   [... trigger an event ...]
//   background_tracing_helper->WaitForTracingEnabled();
//   [... abort ...]
//   background_tracing_helper->WaitForScenarioAborted();
class TestBackgroundTracingHelper
    : public BackgroundTracingManagerImpl::EnabledStateObserver {
 public:
  TestBackgroundTracingHelper() {
    BackgroundTracingManagerImpl::GetInstance()->AddEnabledStateObserver(this);
  }

  ~TestBackgroundTracingHelper() override {
    BackgroundTracingManagerImpl::GetInstance()->RemoveEnabledStateObserver(
        this);
    EXPECT_FALSE(is_scenario_active_);
  }

  void OnScenarioActivated(const BackgroundTracingConfigImpl* config) override {
    is_scenario_active_ = true;
    wait_for_scenario_activated_.Quit();
  }

  void OnScenarioAborted() override {
    is_scenario_active_ = false;
    wait_for_scenario_aborted_.Quit();
  }

  void OnTracingEnabled(
      BackgroundTracingConfigImpl::CategoryPreset preset) override {
    wait_for_tracing_enabled_.Quit();
  }

  void WaitForScenarioActivated() { wait_for_scenario_activated_.Run(); }
  void WaitForScenarioAborted() { wait_for_scenario_aborted_.Run(); }
  void WaitForTracingEnabled() { wait_for_tracing_enabled_.Run(); }

 private:
  bool is_scenario_active_ = false;
  base::RunLoop wait_for_scenario_activated_;
  base::RunLoop wait_for_scenario_aborted_;
  base::RunLoop wait_for_tracing_enabled_;
};

// An helper class that receives uploaded trace. It allows synchronisation with
// tests.
//
// Usage:
//   TestTraceReceiverHelper trace_receiver_helper;
//   [... do tracing stuff ...]
//   trace_receiver_helper.WaitForTraceReceived();
class TestTraceReceiverHelper {
 public:
  BackgroundTracingManager::ReceiveCallback get_receive_callback() {
    return base::BindRepeating(&TestTraceReceiverHelper::Upload,
                               base::Unretained(this));
  }

  void WaitForTraceReceived() { wait_for_trace_received_.Run(); }
  bool trace_received() const { return trace_received_; }
  const std::string& file_contents() const { return file_contents_; }

  bool TraceHasMatchingString(const char* text) const {
    return file_contents_.find(text) != std::string::npos;
  }

  void Upload(
      std::unique_ptr<std::string> file_contents,
      BackgroundTracingManager::FinishedProcessingCallback done_callback) {
    EXPECT_TRUE(file_contents);
    EXPECT_FALSE(trace_received_);
    trace_received_ = true;

    // Uncompress the trace content.
    size_t compressed_length = file_contents->length();
    const size_t kOutputBufferLength = 10 * 1024 * 1024;
    std::vector<char> output_str(kOutputBufferLength);

    z_stream stream = {nullptr};
    stream.avail_in = compressed_length;
    stream.avail_out = kOutputBufferLength;
    stream.next_in =
        reinterpret_cast<Bytef*>(const_cast<char*>(file_contents->data()));
    stream.next_out = reinterpret_cast<Bytef*>(output_str.data());

    // 16 + MAX_WBITS means only decoding gzip encoded streams, and using
    // the biggest window size, according to zlib.h
    int result = inflateInit2(&stream, 16 + MAX_WBITS);
    EXPECT_EQ(Z_OK, result);
    result = inflate(&stream, Z_FINISH);
    int bytes_written = kOutputBufferLength - stream.avail_out;

    inflateEnd(&stream);
    EXPECT_EQ(Z_STREAM_END, result);

    file_contents_.assign(output_str.data(), bytes_written);

    // Post the callbacks.
    content::GetUIThreadTaskRunner({})->PostTask(
        FROM_HERE, base::BindOnce(std::move(done_callback), true));

    content::GetUIThreadTaskRunner({})->PostTask(
        FROM_HERE, wait_for_trace_received_.QuitWhenIdleClosure());
  }

 private:
  base::RunLoop wait_for_trace_received_;
  bool trace_received_ = false;
  std::string file_contents_;
};

// An helper class that receives multiple traces through the same callback.
class TestMultipleTraceReceiverHelper {
 public:
  BackgroundTracingManager::ReceiveCallback get_receive_callback() {
    return base::BindRepeating(&TestMultipleTraceReceiverHelper::Upload,
                               base::Unretained(this));
  }

  void WaitForTraceReceived(size_t offset) {
    trace_receivers_[offset].WaitForTraceReceived();
  }

  bool trace_received(size_t offset) {
    return trace_receivers_[offset].trace_received();
  }

  void Upload(
      std::unique_ptr<std::string> file_contents,
      BackgroundTracingManager::FinishedProcessingCallback done_callback) {
    trace_receivers_[current_receiver_offset_].Upload(std::move(file_contents),
                                                      std::move(done_callback));
    current_receiver_offset_++;
  }

 private:
  std::map<size_t, TestTraceReceiverHelper> trace_receivers_;
  int current_receiver_offset_ = 0;
};

// An helper class accepts a slow-report trigger callback.
//
// Usage:
//   TestTriggerHelper test_trigger_helper;
//    BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
//        handle, trigger_helper.receive_closure(true));
//   test_trigger_helper.WaitForTriggerReceived();
class TestTriggerHelper {
 public:
  BackgroundTracingManager::StartedFinalizingCallback receive_closure(
      bool expected) {
    return base::BindOnce(&TestTriggerHelper::OnTriggerReceive,
                          base::Unretained(this), expected);
  }

  void WaitForTriggerReceived() { wait_for_trigger_received_.Run(); }

 private:
  void OnTriggerReceive(bool expected, bool value) {
    EXPECT_EQ(expected, value);
    wait_for_trigger_received_.QuitWhenIdle();
  }

  base::RunLoop wait_for_trigger_received_;
};

}  // namespace

class BackgroundTracingManagerBrowserTest : public ContentBrowserTest {
 public:
  BackgroundTracingManagerBrowserTest() {
    feature_list_.InitWithFeatures(
        /* enabled_features = */ {features::kEnablePerfettoSystemTracing},
        /* disabled_features = */ {features::kBackgroundTracingProtoOutput});
    // CreateUniqueTempDir() makes a blocking call to create the directory and
    // wait on it. This isn't allowed in a normal browser context. Therefore we
    // do this in the test constructor before the browser prevents the blocking
    // call.
    CHECK(tmp_dir_.CreateUniqueTempDir());
  }

  void PreRunTestOnMainThread() override {
    BackgroundTracingManagerImpl::GetInstance()
        ->InvalidateTriggerHandlesForTesting();

    ContentBrowserTest::PreRunTestOnMainThread();
  }

  const base::ScopedTempDir& tmp_dir() const { return tmp_dir_; }

 private:
  base::ScopedTempDir tmp_dir_;
  base::test::ScopedFeatureList feature_list_;

  DISALLOW_COPY_AND_ASSIGN(BackgroundTracingManagerBrowserTest);
};

std::unique_ptr<BackgroundTracingConfig> CreatePreemptiveConfig() {
  base::DictionaryValue dict;

  dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
  dict.SetString("category", "BENCHMARK");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
    rules_dict->SetString("trigger_name", "preemptive_test");
    rules_list->Append(std::move(rules_dict));
  }
  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));

  EXPECT_TRUE(config);
  return config;
}

std::unique_ptr<BackgroundTracingConfig> CreateReactiveConfig() {
  base::DictionaryValue dict;

  dict.SetString("mode", "REACTIVE_TRACING_MODE");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
    rules_dict->SetString("trigger_name", "reactive_test");
    rules_dict->SetBoolean("stop_tracing_on_repeated_reactive", true);
    rules_dict->SetString("category", "BENCHMARK");
    rules_list->Append(std::move(rules_dict));
  }
  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));

  EXPECT_TRUE(config);
  return config;
}

std::unique_ptr<BackgroundTracingConfig> CreateSystemConfig() {
  base::DictionaryValue dict;
  dict.SetString("mode", "SYSTEM_TRACING_MODE");
  dict.SetString("category", "BENCHMARK");

  std::unique_ptr<base::ListValue> rules_list =
      std::make_unique<base::ListValue>();
  {
    std::unique_ptr<base::DictionaryValue> rules_dict =
        std::make_unique<base::DictionaryValue>();
    rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
    rules_dict->SetString("trigger_name", "system_test");
    rules_list->Append(std::move(rules_dict));
  }
  {
    std::unique_ptr<base::DictionaryValue> rules_dict =
        std::make_unique<base::DictionaryValue>();
    rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
    rules_dict->SetString("trigger_name", "system_test_with_rule_id");
    rules_dict->SetString("rule_id", "rule_id_override");
    rules_list->Append(std::move(rules_dict));
  }
  dict.Set("configs", std::move(rules_list));
  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));

  EXPECT_TRUE(config);
  return config;
}

// This tests that the endpoint receives the final trace data.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReceiveTraceFinalContentsOnTrigger) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();

  BackgroundTracingManager::TriggerHandle handle =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
}

// This tests triggering more than once still only gathers once.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       CallTriggersMoreThanOnceOnlyGatherOnce) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();

  content::BackgroundTracingManager::TriggerHandle handle =
      content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(false));

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
}

// This tests that non-allowlisted args get stripped if required.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       NotAllowlistedArgsStripped) {
  TestTraceReceiverHelper trace_receiver_helper;
  TestBackgroundTracingHelper background_tracing_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();

  content::BackgroundTracingManager::TriggerHandle handle =
      content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::ANONYMIZE_DATA));
  background_tracing_helper.WaitForTracingEnabled();

  {
    TRACE_EVENT1("benchmark", "TestAllowlist", "test_allowlist", "abc");
    TRACE_EVENT1("benchmark", "TestNotAllowlist", "test_not_allowlist", "abc");
  }

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));
  trigger_helper.WaitForTriggerReceived();

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
  EXPECT_TRUE(trace_receiver_helper.TraceHasMatchingString("{"));
  EXPECT_TRUE(trace_receiver_helper.TraceHasMatchingString("test_allowlist"));
  EXPECT_FALSE(
      trace_receiver_helper.TraceHasMatchingString("test_not_allowlist"));
}

// Tests that events emitted by the browser process immediately after the
// SetActiveScenario call does get included in the trace, without waiting for
// the full WaitForTracingEnabled() callback (background tracing will directly
// enable the TraceLog so we get events prior to waiting for the whole IPC
// sequence to enable tracing coming back from the tracing service).
// Temporarily disabled startup tracing on Android to be able to unblock
// Perfetto-based background tracing: https://crbug.com/941318
#if defined(OS_ANDROID)
#define MAYBE_EarlyTraceEventsInTrace DISABLED_EarlyTraceEventsInTrace
#else
#define MAYBE_EarlyTraceEventsInTrace EarlyTraceEventsInTrace
#endif
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       MAYBE_EarlyTraceEventsInTrace) {
  TestTraceReceiverHelper trace_receiver_helper;
  TestBackgroundTracingHelper background_tracing_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();

  content::BackgroundTracingManager::TriggerHandle handle =
      content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::ANONYMIZE_DATA));

  { TRACE_EVENT0("benchmark", "TestEarlyEvent"); }

  background_tracing_helper.WaitForTracingEnabled();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));
  trigger_helper.WaitForTriggerReceived();

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
  EXPECT_TRUE(trace_receiver_helper.TraceHasMatchingString("{"));
  EXPECT_TRUE(trace_receiver_helper.TraceHasMatchingString("TestEarlyEvent"));
}

// This tests that browser metadata gets included in the trace.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       TraceMetadataInTrace) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();

  content::BackgroundTracingManager::TriggerHandle handle =
      content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::ANONYMIZE_DATA));

  background_tracing_helper.WaitForTracingEnabled();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
  EXPECT_TRUE(trace_receiver_helper.TraceHasMatchingString("cpu-brand"));
  EXPECT_TRUE(trace_receiver_helper.TraceHasMatchingString("network-type"));
  EXPECT_TRUE(trace_receiver_helper.TraceHasMatchingString("user-agent"));
}

// Flaky on android, linux, and windows: https://crbug.com/639706 and
// https://crbug.com/643415.
// This tests subprocesses (like a navigating renderer) which gets told to
// provide a argument-filtered trace and has no predicate in place to do the
// filtering (in this case, only the browser process gets it set), will crash
// rather than return potential PII.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       DISABLED_CrashWhenSubprocessWithoutArgumentFilter) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();

  content::BackgroundTracingManager::TriggerHandle handle =
      content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::ANONYMIZE_DATA));

  background_tracing_helper.WaitForScenarioActivated();

  EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "about:blank")));

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
  // We should *not* receive anything at all from the renderer,
  // the process should've crashed rather than letting that happen.
  EXPECT_FALSE(trace_receiver_helper.TraceHasMatchingString("CrRendererMain"));
}

// This tests multiple triggers still only gathers once.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       CallMultipleTriggersOnlyGatherOnce) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
  dict.SetString("category", "BENCHMARK");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
    rules_dict->SetString("trigger_name", "test1");
    rules_list->Append(std::move(rules_dict));
  }
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
    rules_dict->SetString("trigger_name", "test2");
    rules_list->Append(std::move(rules_dict));
  }

  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  EXPECT_TRUE(config);

  BackgroundTracingManager::TriggerHandle handle1 =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType("test1");
  BackgroundTracingManager::TriggerHandle handle2 =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType("test2");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle1, trigger_helper.receive_closure(true));
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle2, trigger_helper.receive_closure(false));

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
}

// This tests that delayed histogram triggers work as expected
// with preemptive scenarios.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       CallPreemptiveTriggerWithDelay) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
  dict.SetString("category", "BENCHMARK");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule",
                          "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
    rules_dict->SetString("histogram_name", "fake");
    rules_dict->SetInteger("histogram_value", 1);
    rules_dict->SetInteger("trigger_delay", 10);
    rules_list->Append(std::move(rules_dict));
  }

  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  EXPECT_TRUE(config);

  base::RunLoop rule_triggered_runloop;
  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  BackgroundTracingManagerImpl::GetInstance()
      ->GetActiveScenarioForTesting()
      ->SetRuleTriggeredCallbackForTesting(
          rule_triggered_runloop.QuitClosure());

  // Our reference value is "1", so a value of "2" should trigger a trace.
  LOCAL_HISTOGRAM_COUNTS("fake", 2);

  rule_triggered_runloop.Run();

  // Since we specified a delay in the scenario, we should still be tracing
  // at this point.
  EXPECT_TRUE(
      BackgroundTracingManagerImpl::GetInstance()->IsTracingForTesting());

  // Fake the timer firing.
  BackgroundTracingManagerImpl::GetInstance()
      ->GetActiveScenarioForTesting()
      ->FireTimerForTesting();

  trace_receiver_helper.WaitForTraceReceived();

  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
}

// This tests that you can't trigger without a scenario set.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       CannotTriggerWithoutScenarioSet) {
  content::BackgroundTracingManager::TriggerHandle handle =
      content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(false));
  trigger_helper.WaitForTriggerReceived();
}

// This tests that no trace is triggered with a handle that isn't specified
// in the config.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       DoesNotTriggerWithWrongHandle) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();

  content::BackgroundTracingManager::TriggerHandle handle =
      content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "does_not_exist");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(false));

  // Abort the scenario.
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_FALSE(trace_receiver_helper.trace_received());
}

// This tests that no trace is triggered with an invalid handle.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       DoesNotTriggerWithInvalidHandle) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();

  content::BackgroundTracingManager::TriggerHandle handle =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  BackgroundTracingManagerImpl::GetInstance()
      ->InvalidateTriggerHandlesForTesting();

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(false));

  // Abort the scenario.
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_FALSE(trace_receiver_helper.trace_received());
}

// This tests that no preemptive trace is triggered with 0 chance set.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       PreemptiveNotTriggerWithZeroChance) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
  dict.SetString("category", "BENCHMARK");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
    rules_dict->SetString("trigger_name", "preemptive_test");
    rules_dict->SetDouble("trigger_chance", 0.0);
    rules_list->Append(std::move(rules_dict));
  }
  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  EXPECT_TRUE(config);

  content::BackgroundTracingManager::TriggerHandle handle =
      content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(false));

  // Abort the scenario.
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_FALSE(trace_receiver_helper.trace_received());
}

// This tests that no reactive trace is triggered with 0 chance set.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReactiveNotTriggerWithZeroChance) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "REACTIVE_TRACING_MODE");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
    rules_dict->SetString("trigger_name", "reactive_test1");
    rules_dict->SetString("category", "BENCHMARK");
    rules_dict->SetDouble("trigger_chance", 0.0);

    rules_list->Append(std::move(rules_dict));
  }
  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  EXPECT_TRUE(config);

  content::BackgroundTracingManager::TriggerHandle handle =
      content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(false));
  trigger_helper.WaitForTriggerReceived();

  // Abort the scenario.
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_FALSE(trace_receiver_helper.trace_received());
}

// This tests that histogram triggers for preemptive mode configs.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReceiveTraceSucceedsOnHigherHistogramSample) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
  dict.SetString("category", "BENCHMARK");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule",
                          "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
    rules_dict->SetString("histogram_name", "fake");
    rules_dict->SetInteger("histogram_value", 1);
    rules_list->Append(std::move(rules_dict));
  }

  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  EXPECT_TRUE(config);

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  // Our reference value is "1", so a value of "2" should trigger a trace.
  LOCAL_HISTOGRAM_COUNTS("fake", 2);

  trace_receiver_helper.WaitForTraceReceived();

  EXPECT_TRUE(trace_receiver_helper.trace_received());

  base::Optional<base::Value> trace_json =
      base::JSONReader::Read(trace_receiver_helper.file_contents());
  ASSERT_TRUE(trace_json);
  auto* metadata_json = static_cast<base::DictionaryValue*>(
      trace_json->FindKeyOfType("metadata", base::Value::Type::DICTIONARY));
  ASSERT_TRUE(metadata_json);

  const std::string* trace_config =
      metadata_json->FindStringKey("trace-config");
  ASSERT_TRUE(trace_config);
  EXPECT_NE(trace_config->find("record-continuously"), trace_config->npos)
      << *trace_config;

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->HasActiveScenario());

  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest, CustomConfig) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
  dict.SetString("category", "BENCHMARK");
  dict.SetKey("trace_config", std::move(*base::JSONReader::Read(R"(
        {
          "included_categories": ["*"],
          "record_mode": "record-until-full"
        })")));

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule",
                          "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
    rules_dict->SetString("histogram_name", "fake");
    rules_dict->SetInteger("histogram_value", 1);
    rules_list->Append(std::move(rules_dict));
  }

  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  EXPECT_TRUE(config);

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  // Our reference value is "1", so a value of "2" should trigger a trace.
  LOCAL_HISTOGRAM_COUNTS("fake", 2);

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());

  base::Optional<base::Value> trace_json =
      base::JSONReader::Read(trace_receiver_helper.file_contents());
  ASSERT_TRUE(trace_json);
  auto* metadata_json = static_cast<base::DictionaryValue*>(
      trace_json->FindKeyOfType("metadata", base::Value::Type::DICTIONARY));
  ASSERT_TRUE(metadata_json);

  const std::string* trace_config =
      metadata_json->FindStringKey("trace-config");
  ASSERT_TRUE(trace_config);
  EXPECT_NE(trace_config->find("record-until-full"), trace_config->npos)
      << *trace_config;
}

// Used as a known symbol to look up the current module.
void DummyFunc() {}

// Test that the tracing sampler profiler running in background tracing mode,
// produces stack frames in the expected JSON format.
// TODO(https://crbug.com/1062581) Disabled for being flaky.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       DISABLED_EndToEndStackSampling) {
  // In the browser process, the tracing sampler profiler gets constructed by
  // the chrome/ layer, so we need to do the same manually for testing purposes.
  auto tracing_sampler_profiler =
      tracing::TracingSamplerProfiler::CreateOnMainThread();

  // There won't be any samples if stack unwinding isn't supported.
  if (!tracing::TracingSamplerProfiler::IsStackUnwindingSupported()) {
    return;
  }

  base::RunLoop wait_for_sample;
  tracing_sampler_profiler->SetSampleCallbackForTesting(
      wait_for_sample.QuitClosure());

  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
  dict.SetString("category", "CUSTOM");
  dict.SetString("custom_categories", "disabled-by-default-cpu_profiler,-*");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
    rules_dict->SetString("trigger_name", "preemptive_test");
    rules_list->Append(std::move(rules_dict));
  }

  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  EXPECT_TRUE(config);

  content::BackgroundTracingManager::TriggerHandle handle =
      content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::ANONYMIZE_DATA));

  background_tracing_helper.WaitForTracingEnabled();

  wait_for_sample.Run();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());

  trace_analyzer::TraceEventVector events;
  std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer(
      trace_analyzer::TraceAnalyzer::Create(
          trace_receiver_helper.file_contents()));
  ASSERT_TRUE(analyzer);

  base::ModuleCache module_cache;
  const base::ModuleCache::Module* this_module =
      module_cache.GetModuleForAddress(reinterpret_cast<uintptr_t>(&DummyFunc));
  ASSERT_TRUE(this_module);

  std::string module_id = this_module->GetId();
  tracing::TracingSamplerProfiler::MangleModuleIDIfNeeded(&module_id);

  std::string desired_frame_pattern = base::StrCat(
      {"0x[[:xdigit:]]+ - /?", this_module->GetDebugBasename().MaybeAsASCII(),
       " \\[", module_id, "\\]"});

  analyzer->FindEvents(trace_analyzer::Query::EventName() ==
                           trace_analyzer::Query::String("StackCpuSampling"),
                       &events);
  EXPECT_GT(events.size(), 0u);

  bool found_match = false;
  for (const trace_analyzer::TraceEvent* event : events) {
    if (found_match) {
      break;
    }

    std::string frames = event->GetKnownArgAsString("frames");
    EXPECT_FALSE(frames.empty());
    base::StringTokenizer values_tokenizer(frames, "\n");
    while (values_tokenizer.GetNext()) {
      if (values_tokenizer.token_is_delim()) {
        continue;
      }

      if (RE2::FullMatch(values_tokenizer.token(), desired_frame_pattern)) {
        found_match = true;
        break;
      }
    }
  }

  EXPECT_TRUE(found_match);
}

// This tests that histogram triggers for reactive mode configs.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReceiveReactiveTraceSucceedsOnHigherHistogramSample) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "REACTIVE_TRACING_MODE");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule",
                          "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
    rules_dict->SetString("histogram_name", "fake");
    rules_dict->SetInteger("histogram_value", 1);
    rules_dict->SetString("category", "BENCHMARK");
    rules_list->Append(std::move(rules_dict));
  }

  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  EXPECT_TRUE(config);

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForScenarioActivated();

  // Our reference value is "1", so a value of "2" should trigger a trace.
  LOCAL_HISTOGRAM_COUNTS("fake", 2);

  trace_receiver_helper.WaitForTraceReceived();

  // Abort the scenario.
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
}

// This tests that histogram values < reference value don't trigger.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReceiveTraceFailsOnLowerHistogramSample) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
  dict.SetString("category", "BENCHMARK");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule",
                          "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
    rules_dict->SetString("histogram_name", "fake");
    rules_dict->SetInteger("histogram_value", 1);
    rules_list->Append(std::move(rules_dict));
  }

  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  EXPECT_TRUE(config);

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  // This should fail to trigger a trace since the sample value < the
  // the reference value above.
  LOCAL_HISTOGRAM_COUNTS("fake", 0);

  // Abort the scenario.
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_FALSE(trace_receiver_helper.trace_received());
}

// This tests that histogram values > upper reference value don't trigger.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReceiveTraceFailsOnHigherHistogramSample) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
  dict.SetString("category", "BENCHMARK");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule",
                          "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
    rules_dict->SetString("histogram_name", "fake");
    rules_dict->SetInteger("histogram_lower_value", 1);
    rules_dict->SetInteger("histogram_upper_value", 3);
    rules_list->Append(std::move(rules_dict));
  }

  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  EXPECT_TRUE(config);

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  // This should fail to trigger a trace since the sample value > the
  // the upper reference value above.
  LOCAL_HISTOGRAM_COUNTS("fake", 0);

  // Abort the scenario.
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_FALSE(trace_receiver_helper.trace_received());
}

// This tests that invalid preemptive mode configs will fail.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       SetActiveScenarioFailsWithInvalidPreemptiveConfig) {
  base::DictionaryValue dict;
  dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
  dict.SetString("category", "BENCHMARK");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "INVALID_RULE");
    rules_list->Append(std::move(rules_dict));
  }

  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));
  // An invalid config should always return a nullptr here.
  EXPECT_FALSE(config);
}

// This tests that reactive mode records and terminates with timeout.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReactiveTimeoutTermination) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreateReactiveConfig();

  BackgroundTracingManager::TriggerHandle handle =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "reactive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));

  BackgroundTracingManagerImpl::GetInstance()
      ->GetActiveScenarioForTesting()
      ->FireTimerForTesting();

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
}

// This tests that reactive mode records and terminates with a second trigger.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReactiveSecondTriggerTermination) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreateReactiveConfig();

  BackgroundTracingManager::TriggerHandle handle =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "reactive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));
  // second trigger to terminate.
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
}

// This tests that reactive mode uploads on a second set of triggers.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReactiveSecondUpload) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestMultipleTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreateReactiveConfig();

  BackgroundTracingManager::TriggerHandle handle =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "reactive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForScenarioActivated();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));

  // second trigger to terminate.
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));

  trace_receiver_helper.WaitForTraceReceived(0);
  EXPECT_TRUE(trace_receiver_helper.trace_received(0));

  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));
  // second trigger to terminate.
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));

  trace_receiver_helper.WaitForTraceReceived(1);
  EXPECT_TRUE(trace_receiver_helper.trace_received(1));

  // Abort the scenario.
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();
}

// This tests that reactive mode only terminates with the same trigger.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReactiveSecondTriggerMustMatchForTermination) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "REACTIVE_TRACING_MODE");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
    rules_dict->SetString("trigger_name", "reactive_test1");
    rules_dict->SetBoolean("stop_tracing_on_repeated_reactive", true);
    rules_dict->SetInteger("trigger_delay", 10);
    rules_dict->SetString("category", "BENCHMARK");
    rules_list->Append(std::move(rules_dict));
  }
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
    rules_dict->SetString("trigger_name", "reactive_test2");
    rules_dict->SetBoolean("stop_tracing_on_repeated_reactive", true);
    rules_dict->SetInteger("trigger_delay", 10);
    rules_dict->SetString("category", "BENCHMARK");
    rules_list->Append(std::move(rules_dict));
  }
  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));

  BackgroundTracingManager::TriggerHandle handle1 =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "reactive_test1");
  BackgroundTracingManager::TriggerHandle handle2 =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "reactive_test2");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForScenarioActivated();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle1, trigger_helper.receive_closure(true));

  // This is expected to fail since we triggered with handle1.
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle2, trigger_helper.receive_closure(false));

  // second trigger to terminate.
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle1, trigger_helper.receive_closure(true));

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
}

// This tests a third trigger in reactive more does not start another trace.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReactiveThirdTriggerTimeout) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreateReactiveConfig();

  BackgroundTracingManager::TriggerHandle handle =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "reactive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForScenarioActivated();

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));
  // second trigger to terminate.
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));
  // third trigger to trigger again, fails as it is still gathering.
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(false));

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
}

// This tests that reactive mode only terminates with a repeated trigger
// if the config specifies that it should.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       ReactiveSecondTriggerIgnored) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  base::DictionaryValue dict;
  dict.SetString("mode", "REACTIVE_TRACING_MODE");

  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
    rules_dict->SetString("trigger_name", "reactive_test");
    rules_dict->SetBoolean("stop_tracing_on_repeated_reactive", false);
    rules_dict->SetInteger("trigger_delay", 10);
    rules_dict->SetString("category", "BENCHMARK");
    rules_list->Append(std::move(rules_dict));
  }
  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::FromDict(&dict));

  BackgroundTracingManager::TriggerHandle trigger_handle =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "reactive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      trigger_handle, trigger_helper.receive_closure(true));

  background_tracing_helper.WaitForTracingEnabled();

  // This is expected to fail since we already triggered.
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      trigger_handle, trigger_helper.receive_closure(false));

  // Since we specified a delay in the scenario, we should still be tracing
  // at this point.
  EXPECT_TRUE(
      BackgroundTracingManagerImpl::GetInstance()->IsTracingForTesting());

  BackgroundTracingManagerImpl::GetInstance()
      ->GetActiveScenarioForTesting()
      ->FireTimerForTesting();

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       SetupStartupTracing) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<TestStartupPreferenceManagerImpl> preferences_moved(
      new TestStartupPreferenceManagerImpl);
  TestStartupPreferenceManagerImpl* preferences = preferences_moved.get();
  BackgroundStartupTracingObserver::GetInstance()
      ->SetPreferenceManagerForTesting(std::move(preferences_moved));
  preferences->SetBackgroundStartupTracingEnabled(false);

  base::DictionaryValue dict;
  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
    rules_dict->SetString("trigger_name", "startup-config");
    rules_dict->SetBoolean("stop_tracing_on_repeated_reactive", false);
    rules_dict->SetInteger("trigger_delay", 600);
    rules_dict->SetString("category", "BENCHMARK_STARTUP");
    rules_list->Append(std::move(rules_dict));
  }
  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::ReactiveFromDict(&dict));

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForScenarioActivated();

  // Since we specified a delay in the scenario, we should still be tracing
  // at this point.
  EXPECT_FALSE(
      BackgroundTracingManagerImpl::GetInstance()->IsTracingForTesting());
  EXPECT_TRUE(preferences->GetBackgroundStartupTracingEnabled());

  // Abort the scenario.
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_FALSE(trace_receiver_helper.trace_received());
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest, RunStartupTracing) {
  TestTraceLogHelper tracelog_helper;
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<TestStartupPreferenceManagerImpl> preferences_moved(
      new TestStartupPreferenceManagerImpl);
  TestStartupPreferenceManagerImpl* preferences = preferences_moved.get();
  BackgroundStartupTracingObserver::GetInstance()
      ->SetPreferenceManagerForTesting(std::move(preferences_moved));
  preferences->SetBackgroundStartupTracingEnabled(true);

  base::DictionaryValue dict;
  std::unique_ptr<base::ListValue> rules_list(new base::ListValue());
  {
    std::unique_ptr<base::DictionaryValue> rules_dict(
        new base::DictionaryValue());
    rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
    rules_dict->SetString("trigger_name", "gpu-config");
    rules_dict->SetBoolean("stop_tracing_on_repeated_reactive", false);
    rules_dict->SetInteger("trigger_delay", 10);
    rules_dict->SetString("category", "BENCHMARK_GPU");
    rules_list->Append(std::move(rules_dict));
  }
  dict.Set("configs", std::move(rules_list));

  std::unique_ptr<BackgroundTracingConfig> config(
      BackgroundTracingConfigImpl::ReactiveFromDict(&dict));

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::ANONYMIZE_DATA));

  tracelog_helper.WaitForStartTracing();
  background_tracing_helper.WaitForTracingEnabled();

  EXPECT_TRUE(BackgroundTracingManagerImpl::GetInstance()
                  ->GetActiveScenarioForTesting()
                  ->GetConfig()
                  ->requires_anonymized_data());

  // Since we specified a delay in the scenario, we should still be tracing
  // at this point.
  EXPECT_TRUE(
      BackgroundTracingManagerImpl::GetInstance()->IsTracingForTesting());

  BackgroundTracingManagerImpl::GetInstance()
      ->GetActiveScenarioForTesting()
      ->FireTimerForTesting();

  trace_receiver_helper.WaitForTraceReceived();
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  EXPECT_TRUE(trace_receiver_helper.trace_received());
  EXPECT_FALSE(preferences->GetBackgroundStartupTracingEnabled());
}

namespace {

class ProtoBackgroundTracingTest : public DevToolsProtocolTest {
 public:
  ProtoBackgroundTracingTest() {
    scoped_feature_list_.InitWithFeatures(
        /*enabled_features=*/{features::kBackgroundTracingProtoOutput},
        /*disabled_features=*/{});
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

}  // namespace

IN_PROC_BROWSER_TEST_F(ProtoBackgroundTracingTest,
                       DevtoolsInterruptsBackgroundTracing) {
  TestBackgroundTracingHelper background_tracing_helper;
  TestTraceReceiverHelper trace_receiver_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  background_tracing_helper.WaitForTracingEnabled();

  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();

  base::Value* start_tracing_result =
      SendCommand("Tracing.start", nullptr, true);
  ASSERT_TRUE(start_tracing_result);
  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();
}

IN_PROC_BROWSER_TEST_F(ProtoBackgroundTracingTest, ProtoTraceReceived) {
  TestBackgroundTracingHelper background_tracing_helper;

  std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();

  BackgroundTracingManager::TriggerHandle handle =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "preemptive_test");

  EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), base::DoNothing(),
      BackgroundTracingManager::ANONYMIZE_DATA));

  background_tracing_helper.WaitForTracingEnabled();

  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);

  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));

  WaitForCondition(
      base::BindRepeating([]() {
        return BackgroundTracingManager::GetInstance()->HasTraceToUpload();
      }),
      "trace received");

  std::string trace_data =
      BackgroundTracingManager::GetInstance()->GetLatestTraceToUpload();

  BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioAborted();

  tracing::PrivacyFilteringCheck checker;
  checker.CheckProtoForUnexpectedFields(trace_data);
  EXPECT_GT(checker.stats().track_event, 0u);
  EXPECT_GT(checker.stats().process_desc, 0u);
  EXPECT_GT(checker.stats().thread_desc, 0u);
  EXPECT_TRUE(checker.stats().has_interned_names);
  EXPECT_TRUE(checker.stats().has_interned_categories);
  EXPECT_TRUE(checker.stats().has_interned_source_locations);
}

#if defined(OS_POSIX)
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       PerfettoSystemBackgroundScenarioDefaultName) {
  // This test will ensure that a BackgroundTracing scenario set to SYSTEM mode
  // can issue a SystemTrigger using the default name to let the Android
  // Perfetto service know the trace is interesting.
  //
  // This requires setting up a Perfetto Service which runs two unix sockets on
  // the android device. Chrome will be configured to connect to the producer
  // socket and treat it like the System tracing service. The test will connect
  // to the consumer to start a system trace and also to read back the results.
  //
  // This test is broken up into sections for readability:
  //
  // 1) Setup the sideloaded Perfetto System service
  // 2) Start System trace
  // 3) Setup & Run SYSTEM background scenario
  // 4) Wait and verify packets received & clean up

  // *********** Setup the sideloaded Perfetto System service **********
  auto system_service = std::make_unique<tracing::MockSystemService>(tmp_dir());
  SetSystemProducerSocketAndChecksAsync(system_service->producer());

  //  ******************** Start System trace **********************
  perfetto::TraceConfig trace_config =
      StopTracingTriggerConfig("org.chromium.background_tracing.system_test");
  base::RunLoop system_no_more_packets_runloop;
  auto system_consumer = CreateDefaultConsumer(std::move(trace_config),
                                               system_service->GetService(),
                                               &system_no_more_packets_runloop);
  system_consumer->WaitForAllDataSourcesStarted();

  // ************* Setup & Run SYSTEM background scenario ******************

  // "system_test" is a NamedTriggerRule in CreateSystemConfig().
  BackgroundTracingManager::TriggerHandle handle =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "system_test");

  // trace_receiver_helper's function will not be called for SYSTEM background
  // trace.
  TestTraceReceiverHelper trace_receiver_helper;
  std::unique_ptr<BackgroundTracingConfig> config = CreateSystemConfig();
  ASSERT_TRUE(config);
  ASSERT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));

  // Actually send the trigger into the system.
  base::RunLoop rule_triggered_runloop;
  BackgroundTracingManagerImpl::GetInstance()
      ->GetActiveScenarioForTesting()
      ->SetRuleTriggeredCallbackForTesting(
          rule_triggered_runloop.QuitClosure());
  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));
  rule_triggered_runloop.Run();

  // ************ Wait and verify packets received & clean up ************
  system_consumer->WaitForAllDataSourcesStopped();
  system_consumer->ReadBuffers();
  system_no_more_packets_runloop.Run();
  // We should at the very least receive the system packets if the trigger was
  // properly received by the trace. However if the background trigger was not
  // received we won't see any packets and |received_packets()| will be 0.
  EXPECT_GT(system_consumer->received_packets(), 0u);
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       PerfettoSystemBackgroundScenarioRuleId) {
  // This test will ensure that a BackgroundTracing scenario set to SYSTEM mode
  // can issue a SystemTrigger that users the |rule_id| json field to let the
  // Android Perfetto service know the trace is interesting.
  //
  // This requires setting up a Perfetto Service which runs two unix sockets on
  // the android device. Chrome will be configured to connect to the producer
  // socket and treat it like the System tracing service. The test will connect
  // to the consumer to start a system trace and also to read back the results.
  //
  // This test is broken up into sections for readability:
  //
  // 1) Setup the sideloaded Perfetto System service
  // 2) Start System trace
  // 3) Setup & Run SYSTEM background scenario
  // 4) Wait and verify packets received & clean up

  // *********** Setup the sideloaded Perfetto System service **********
  auto system_service = std::make_unique<tracing::MockSystemService>(tmp_dir());
  SetSystemProducerSocketAndChecksAsync(system_service->producer());

  //  ******************** Start System trace **********************
  perfetto::TraceConfig trace_config =
      StopTracingTriggerConfig("rule_id_override");
  base::RunLoop system_no_more_packets_runloop;
  auto system_consumer = CreateDefaultConsumer(std::move(trace_config),
                                               system_service->GetService(),
                                               &system_no_more_packets_runloop);
  system_consumer->WaitForAllDataSourcesStarted();

  // ************* Setup & Run SYSTEM background scenario ******************

  // "system_test" is a NamedTriggerRule in CreateSystemConfig().
  BackgroundTracingManager::TriggerHandle handle =
      BackgroundTracingManager::GetInstance()->RegisterTriggerType(
          "system_test_with_rule_id");
  // trace_receiver_helper's function will not be called for SYSTEM background
  // trace.
  TestTraceReceiverHelper trace_receiver_helper;
  std::unique_ptr<BackgroundTracingConfig> config = CreateSystemConfig();
  ASSERT_TRUE(config);
  ASSERT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
      std::move(config), trace_receiver_helper.get_receive_callback(),
      BackgroundTracingManager::NO_DATA_FILTERING));
  // Actually send the trigger into the system.
  base::RunLoop rule_triggered_runloop;
  BackgroundTracingManagerImpl::GetInstance()
      ->GetActiveScenarioForTesting()
      ->SetRuleTriggeredCallbackForTesting(
          rule_triggered_runloop.QuitClosure());
  TestTriggerHelper trigger_helper;
  BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
      handle, trigger_helper.receive_closure(true));
  rule_triggered_runloop.Run();

  // ************ Wait and verify packets received & clean up ************
  system_consumer->WaitForAllDataSourcesStopped();
  system_consumer->ReadBuffers();
  system_no_more_packets_runloop.Run();
  // We should at the very least receive the system packets if the trigger was
  // properly received by the trace. However if the background trigger was not
  // received we won't see any packets and |received_packets()| will be 0.
  EXPECT_LT(0u, system_consumer->received_packets());
}
#endif  // defined(OS_POSIX)

}  // namespace content
