// Copyright 2015 The Chromium Authors
// 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/command_line.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_reader.h"
#include "base/memory/ref_counted_memory.h"
#include "base/metrics/histogram_macros.h"
#include "base/path_service.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/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/run_until.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_proto_loader.h"
#include "base/test/trace_event_analyzer.h"
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/interned_args_helper.h"
#include "base/trace_event/named_trigger.h"
#include "base/trace_event/typed_macros.h"
#include "build/build_config.h"
#include "content/browser/devtools/protocol/devtools_protocol_test_support.h"
#include "content/browser/renderer_host/render_frame_host_impl.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/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/background_tracing_test_support.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.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 "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.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/trace_startup_config.h"
#include "services/tracing/public/cpp/tracing_features.h"
#include "third_party/perfetto/include/perfetto/ext/trace_processor/export_json.h"
#include "third_party/perfetto/include/perfetto/trace_processor/trace_processor_storage.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/log_message.pbzero.h"
#include "third_party/re2/src/re2/re2.h"
#include "third_party/zlib/google/compression_utils.h"
#include "third_party/zlib/zlib.h"

namespace content {
namespace {

using testing::_;

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

  bool GetBackgroundStartupTracingEnabled() const override { return enabled_; }

 private:
  bool enabled_ = false;
};

// A helper class that observes background tracing states transition, receives
// uploaded trace and allows synchronisation with tests. The class adds itself
// as a background tracing enabled state observer. It provides methods to wait
// for a given state.
//
// Usage:
//   TestBackgroundTracingHelper background_tracing_helper;
//   [... set a background tracing scenario ...]
//   [... trigger an event ...]
//   background_tracing_helper->WaitForTraceStarted();
//   background_tracing_helper->ExpectOnScenarioIdle("scenario_name");
//   [... abort ...]
//   background_tracing_helper->WaitForScenarioIdle();
class TestBackgroundTracingHelper
    : public BackgroundTracingManager::EnabledStateTestObserver,
      public perfetto::trace_processor::json::OutputWriter {
 public:
  TestBackgroundTracingHelper() {
    BackgroundTracingManagerImpl::GetInstance()
        .AddEnabledStateObserverForTesting(this);
  }

  ~TestBackgroundTracingHelper() override {
    BackgroundTracingManagerImpl::GetInstance()
        .RemoveEnabledStateObserverForTesting(this);
  }

  MOCK_METHOD(void,
              OnScenarioActive,
              (const std::string& scenario_name),
              (override));
  MOCK_METHOD(void,
              OnScenarioIdle,
              (const std::string& scenario_name),
              (override));
  void OnTraceStarted() override { wait_for_trace_started_.Quit(); }
  void OnTraceReceived(const std::string& proto_content) override {
    ProcessTraceContent(proto_content);
  }
  void OnTraceSaved() override { wait_for_trace_saved_.Quit(); }

  void ExpectOnScenarioActive(const std::string& scenario_name) {
    EXPECT_CALL(*this, OnScenarioActive(scenario_name)).Times(1);
  }
  void ExpectOnScenarioIdle(const std::string& scenario_name) {
    EXPECT_CALL(*this, OnScenarioIdle(scenario_name))
        .WillOnce(
            base::test::RunOnceClosure(wait_for_scenario_idle_.QuitClosure()));
  }
  void WaitForScenarioIdle() { wait_for_scenario_idle_.Run(); }
  void WaitForTraceStarted() { wait_for_trace_started_.Run(); }
  void WaitForTraceReceived() { wait_for_trace_received_.Run(); }
  void WaitForTraceSaved() { wait_for_trace_saved_.Run(); }

  bool trace_received() const { return trace_received_; }
  const std::string& json_file_contents() const { return json_file_contents_; }
  const std::string& proto_file_contents() const {
    return proto_file_contents_;
  }
  bool TraceHasMatchingString(const char* text) const {
    return json_file_contents_.find(text) != std::string::npos;
  }

 private:
  void ProcessTraceContent(const std::string& file_contents) {
    EXPECT_FALSE(trace_received_);
    trace_received_ = true;
    proto_file_contents_ = file_contents;

    std::unique_ptr<perfetto::trace_processor::TraceProcessorStorage>
        trace_processor =
            perfetto::trace_processor::TraceProcessorStorage::CreateInstance(
                perfetto::trace_processor::Config());

    perfetto::trace_processor::TraceBlob blob =
        perfetto::trace_processor::TraceBlob::CopyFrom(
            proto_file_contents_.data(), proto_file_contents_.length());

    auto parse_status = trace_processor->Parse(
        perfetto::trace_processor::TraceBlobView(std::move(blob)));
    ASSERT_TRUE(parse_status.ok()) << parse_status.message();

    auto end_status = trace_processor->NotifyEndOfFile();
    ASSERT_TRUE(end_status.ok()) << end_status.message();

    auto export_status = perfetto::trace_processor::json::ExportJson(
        trace_processor.get(), this,
        perfetto::trace_processor::json::ArgumentFilterPredicate(),
        perfetto::trace_processor::json::MetadataFilterPredicate(),
        perfetto::trace_processor::json::LabelFilterPredicate());
    ASSERT_TRUE(export_status.ok()) << export_status.message();

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

  // perfetto::trace_processor::json::OutputWriter
  perfetto::trace_processor::util::Status AppendString(
      const std::string& json) override {
    json_file_contents_ += json;
    return perfetto::trace_processor::util::OkStatus();
  }

  base::RunLoop wait_for_scenario_idle_;
  base::RunLoop wait_for_trace_started_;
  base::RunLoop wait_for_trace_received_;
  base::RunLoop wait_for_trace_saved_;

  bool trace_received_ = false;
  std::string proto_file_contents_;
  std::string json_file_contents_;
};

perfetto::protos::gen::ChromeFieldTracingConfig ParseFieldTracingConfigFromText(
    const std::string& proto_text) {
  base::ScopedAllowBlockingForTesting allow_blocking;
  base::TestProtoLoader config_loader(
      base::PathService::CheckedGet(base::DIR_GEN_TEST_DATA_ROOT)
          .Append(
              FILE_PATH_LITERAL("third_party/perfetto/protos/perfetto/"
                                "config/chrome/scenario_config.descriptor")),
      "perfetto.protos.ChromeFieldTracingConfig");
  std::string serialized_message;
  config_loader.ParseFromText(proto_text, serialized_message);
  perfetto::protos::gen::ChromeFieldTracingConfig destination;
  destination.ParseFromString(serialized_message);
  return destination;
}

}  // namespace

class BackgroundTracingManagerBrowserTest : public ContentBrowserTest {
 public:
  BackgroundTracingManagerBrowserTest() {
    feature_list_.InitWithFeatures(
        /* enabled_features = */ {features::kEnablePerfettoSystemTracing},
        /* disabled_features = */ {});
    // 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());
  }

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

  void PreRunTestOnMainThread() override {
    BackgroundTracingManagerImpl::GetInstance()
        .InvalidateTriggersCallbackForTesting();

    ContentBrowserTest::PreRunTestOnMainThread();
  }

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    ContentBrowserTest::SetUpOnMainThread();
  }

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

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

perfetto::protos::gen::ChromeFieldTracingConfig CreateSimpleScenarioConfig() {
  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: { manual_trigger_name: "start_trigger" }
      upload_rules: { manual_trigger_name: "upload_trigger" }
      trace_config: {
        data_sources: {
          config: {
            name: "track_event"
            track_event_config: {
              disabled_categories: [ "*" ],
              enabled_categories: [ "toplevel", "benchmark", "startup" ]
            }
          }
        }
        data_sources: { config: { name: "org.chromium.trace_metadata2" } }
      }
    }
  )pb";
  return ParseFieldTracingConfigFromText(kScenarioConfig);
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       AddPresetScenarios) {
  TestBackgroundTracingHelper background_tracing_helper;
  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: {
        name: "start_trigger"
        manual_trigger_name: "start_trigger"
      }
      upload_rules: {
        name: "upload_trigger"
        manual_trigger_name: "upload_trigger"
      }
      trace_config: {
        data_sources: { config: { name: "org.chromium.trace_metadata2" } }
      }
    }
  )pb";
  auto scenarios = BackgroundTracingManager::GetInstance().AddPresetScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::NO_DATA_FILTERING);
  EXPECT_EQ(std::vector<std::string>({"test_scenario"}), scenarios);
  {
    auto all_scenarios =
        BackgroundTracingManagerImpl::GetInstance().GetAllScenarios();
    std::vector<traces_internals::mojom::ScenarioPtr> expected;
    auto scenario = traces_internals::mojom::Scenario::New();
    scenario->scenario_name = "test_scenario";
    scenario->is_local_scenario = true;
    scenario->is_enabled = false;
    scenario->current_state = TracingScenario::State::kDisabled;
    expected.push_back(std::move(scenario));
    EXPECT_EQ(expected, all_scenarios);
  }

  BackgroundTracingManager::GetInstance().SetEnabledScenarios(scenarios);
  EXPECT_EQ(std::vector<std::string>({"test_scenario"}),
            BackgroundTracingManagerImpl::GetInstance().GetEnabledScenarios());

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("upload_trigger"));
  background_tracing_helper.WaitForScenarioIdle();

  background_tracing_helper.WaitForTraceReceived();
  EXPECT_TRUE(background_tracing_helper.trace_received());
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       EnablePresetScenariosWhileTracing) {
  TestBackgroundTracingHelper background_tracing_helper;
  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: {
        name: "start_trigger"
        manual_trigger_name: "start_trigger"
      }
      trace_config: {
        data_sources: { config: { name: "org.chromium.trace_metadata2" } }
      }
    }
  )pb";
  auto scenarios = BackgroundTracingManager::GetInstance().AddPresetScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::NO_DATA_FILTERING);

  EXPECT_EQ(std::vector<std::string>({"test_scenario"}), scenarios);
  BackgroundTracingManager::GetInstance().SetEnabledScenarios(scenarios);
  EXPECT_EQ(std::vector<std::string>({"test_scenario"}),
            BackgroundTracingManagerImpl::GetInstance().GetEnabledScenarios());

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  BackgroundTracingManager::GetInstance().SetEnabledScenarios({});
  EXPECT_EQ(std::vector<std::string>(),
            BackgroundTracingManagerImpl::GetInstance().GetEnabledScenarios());
  background_tracing_helper.WaitForScenarioIdle();
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       StartUploadScenario) {
  TestBackgroundTracingHelper background_tracing_helper;
  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: {
        name: "start_trigger"
        manual_trigger_name: "start_trigger"
      }
      upload_rules: {
        name: "upload_trigger"
        manual_trigger_name: "upload_trigger"
      }
      trace_config: {
        data_sources: { config: { name: "org.chromium.trace_metadata2" } }
      }
    }
  )pb";
  BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::NO_DATA_FILTERING, false, 0);

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("upload_trigger"));
  background_tracing_helper.WaitForScenarioIdle();

  background_tracing_helper.WaitForTraceReceived();
  EXPECT_TRUE(background_tracing_helper.trace_received());
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       StartInvalidScenario) {
  TestBackgroundTracingHelper background_tracing_helper;
  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: {
        name: "start_trigger"
        manual_trigger_name: "start_trigger"
      }
      trace_config: {
        data_sources: { config: { name: "Invalid" target_buffer: 1 } }
      }
    }
  )pb";
  BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::NO_DATA_FILTERING, false, 0);

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));

  background_tracing_helper.WaitForScenarioIdle();
}

// This tests that non-allowlisted args get stripped if required.
// TODO(https://crbug.com/332743783): Flakey on Linux TSan.
#if BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)
#define MAYBE_NotAllowlistedArgsStripped DISABLED_NotAllowlistedArgsStripped
#else
#define MAYBE_NotAllowlistedArgsStripped NotAllowlistedArgsStripped
#endif
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       MAYBE_NotAllowlistedArgsStripped) {
  TestBackgroundTracingHelper background_tracing_helper;

  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: {
        name: "start_trigger"
        manual_trigger_name: "start_trigger"
      }
      upload_rules: {
        name: "upload_trigger"
        manual_trigger_name: "upload_trigger"
      }
      trace_config: {
        data_sources: {
          config: {
            name: "track_event"
            track_event_config: {
              disabled_categories: [ "*" ],
              enabled_categories: [ "toplevel", "startup" ]
            }
          }
        }
      }
    }
  )pb";
  BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::ANONYMIZE_DATA, false, 0);
  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

  {
    TRACE_EVENT1("toplevel", "ThreadPool_RunTask", "src_file", "abc");
    TRACE_EVENT1("startup", "TestNotAllowlist", "test_not_allowlist", "abc");
  }

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("upload_trigger"));
  background_tracing_helper.WaitForScenarioIdle();

  background_tracing_helper.WaitForTraceReceived();
  EXPECT_TRUE(background_tracing_helper.trace_received());
  EXPECT_TRUE(background_tracing_helper.TraceHasMatchingString("{"));
  EXPECT_TRUE(background_tracing_helper.TraceHasMatchingString("src_file"));
  EXPECT_FALSE(
      background_tracing_helper.TraceHasMatchingString("test_not_allowlist"));
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       StartOtherScenario) {
  TestBackgroundTracingHelper observer;
  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: {
        name: "start_trigger"
        manual_trigger_name: "start_trigger"
      }
      stop_rules: { name: "stop_trigger" manual_trigger_name: "stop_trigger" }
      trace_config: {
        data_sources: { config: { name: "org.chromium.trace_metadata2" } }
      }
    }
    scenarios: {
      scenario_name: "other_scenario"
      start_rules: {
        name: "start_trigger"
        manual_trigger_name: "other_start_trigger"
      }
      trace_config: {
        data_sources: { config: { name: "org.chromium.trace_metadata2" } }
      }
    }
  )pb";
  BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::NO_DATA_FILTERING, false, 0);

  observer.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));

  EXPECT_FALSE(base::trace_event::EmitNamedTrigger("other_scenario"));

  observer.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("stop_trigger"));
  observer.WaitForScenarioIdle();

  observer.ExpectOnScenarioActive("other_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("other_start_trigger"));
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       StartNestedScenario) {
  TestBackgroundTracingHelper observer;
  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: { manual_trigger_name: "start_trigger" }
      stop_rules: { manual_trigger_name: "stop_trigger" }
      trace_config: {
        data_sources: { config: { name: "org.chromium.trace_metadata2" } }
      }
      nested_scenarios: {
        scenario_name: "nested_scenario"
        start_rules: { manual_trigger_name: "nested_start_trigger" }
        upload_rules: { manual_trigger_name: "nested_upload_trigger" }
      }
    }
  )pb";
  BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::NO_DATA_FILTERING, false, 0);

  observer.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));

  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("nested_start_trigger"));
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("nested_upload_trigger"));

  observer.WaitForTraceReceived();
  EXPECT_TRUE(observer.trace_received());

  observer.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("stop_trigger"));
  observer.WaitForScenarioIdle();
}

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

  EXPECT_TRUE(BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      CreateSimpleScenarioConfig(), BackgroundTracingManager::ANONYMIZE_DATA,
      false, 0));

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

  {
    TRACE_EVENT1("toplevel", "ThreadPool_RunTask", "src_file", "abc");
    TRACE_EVENT1("startup", "TestNotAllowlist", "test_not_allowlist", "abc");
  }

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("upload_trigger"));
  background_tracing_helper.WaitForScenarioIdle();

  background_tracing_helper.WaitForTraceReceived();

  EXPECT_TRUE(background_tracing_helper.trace_received());
  EXPECT_TRUE(background_tracing_helper.TraceHasMatchingString("{"));
  EXPECT_TRUE(background_tracing_helper.TraceHasMatchingString("src_file"));
  EXPECT_FALSE(
      background_tracing_helper.TraceHasMatchingString("test_not_allowlist"));
}

// Regression test for https://crbug.com/1405341.
// Tests that RenderFrameHostImpl destruction is finished without crashing when
// tracing is enabled.
// TODO(crbug.com/335334098): Flaky on Linux TSan
#if BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)
#define MAYBE_TracingRenderFrameHostImplDtor \
  DISABLED_TracingRenderFrameHostImplDtor
#else
#define MAYBE_TracingRenderFrameHostImplDtor TracingRenderFrameHostImplDtor
#endif
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       MAYBE_TracingRenderFrameHostImplDtor) {
  ASSERT_TRUE(embedded_test_server()->Start());

  TestBackgroundTracingHelper background_tracing_helper;

  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: { manual_trigger_name: "start_trigger" }
      upload_rules: { manual_trigger_name: "upload_trigger" }
      trace_config: {
        data_sources: {
          config: {
            name: "track_event"
            track_event_config: {
              disabled_categories: [ "*" ],
              enabled_categories: [ "content" ]
            }
          }
        }
      }
    }
  )pb";

  BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::NO_DATA_FILTERING, false, 0);

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  auto* rfhi = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());

  // Audible audio output should cause the media stream count to increment.
  rfhi->OnMediaStreamAdded(
      RenderFrameHostImpl::MediaStreamType::kPlayingAudibleAudioStream);

  RenderFrameDeletedObserver delete_frame(rfhi);

  // The old RenderFrameHost might have entered the BackForwardCache. Disable
  // back-forward cache to ensure that the RenderFrameHost gets deleted.
  DisableBackForwardCacheForTesting(shell()->web_contents(),
                                    BackForwardCache::TEST_REQUIRES_NO_CACHING);

  GURL cross_site_url = embedded_test_server()->GetURL("b.com", "/title2.html");
  EXPECT_TRUE(NavigateToURL(shell(), cross_site_url));
  delete_frame.WaitUntilDeleted();

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("upload_trigger"));
  background_tracing_helper.WaitForScenarioIdle();

  background_tracing_helper.WaitForTraceReceived();

  EXPECT_TRUE(background_tracing_helper.trace_received());
}

// Tests that events emitted by the browser process immediately after the
// SetActiveScenarioWithReceiveCallback call does get included in the trace,
// without waiting for the full WaitForTraceStarted() 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).
// The test is disabled since Perfetto SDK migration because startup tracing is
// now started asynchronously.
// TODO(khokhlov): Re-enable when background tracing is switched to synchronous
// start.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       EarlyTraceEventsInTrace) {
  TestBackgroundTracingHelper background_tracing_helper;

  EXPECT_TRUE(BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      CreateSimpleScenarioConfig(), BackgroundTracingManager::ANONYMIZE_DATA,
      false, 0));

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));

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

  background_tracing_helper.WaitForTraceStarted();

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("upload_trigger"));
  background_tracing_helper.WaitForScenarioIdle();

  background_tracing_helper.WaitForTraceReceived();

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

// This tests that browser metadata gets included in the trace.
// TODO(crbug.com/40891272): Re-enable this test on TSAN builds.
#if BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)
#define MAYBE_TraceMetadataInTrace DISABLED_TraceMetadataInTrace
#else
#define MAYBE_TraceMetadataInTrace TraceMetadataInTrace
#endif
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       MAYBE_TraceMetadataInTrace) {
  TestBackgroundTracingHelper background_tracing_helper;

  EXPECT_TRUE(BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      CreateSimpleScenarioConfig(), BackgroundTracingManager::NO_DATA_FILTERING,
      false, 0));

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("upload_trigger"));
  background_tracing_helper.WaitForScenarioIdle();

  background_tracing_helper.WaitForTraceReceived();

  EXPECT_TRUE(background_tracing_helper.trace_received());
  EXPECT_TRUE(background_tracing_helper.TraceHasMatchingString("os-name"));
}

// This tests that histogram triggers for preemptive mode configs.
// TODO(crbug.com/40900999): Flaky on Linux TSan.
#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(THREAD_SANITIZER)
#define MAYBE_ReceiveTraceSucceedsOnHigherHistogramSample \
  DISABLED_ReceiveTraceSucceedsOnHigherHistogramSample
#else
#define MAYBE_ReceiveTraceSucceedsOnHigherHistogramSample \
  ReceiveTraceSucceedsOnHigherHistogramSample
#endif
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       MAYBE_ReceiveTraceSucceedsOnHigherHistogramSample) {
  TestBackgroundTracingHelper background_tracing_helper;
  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: { manual_trigger_name: "start_trigger" }
      upload_rules: { histogram: { histogram_name: "fake" min_value: 1 } }
      trace_config: {
        data_sources: { config: { name: "org.chromium.trace_metadata2" } }
      }
    }
  )pb";
  BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::NO_DATA_FILTERING, false, 0);

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

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

  background_tracing_helper.WaitForScenarioIdle();
  background_tracing_helper.WaitForTraceReceived();

  EXPECT_TRUE(background_tracing_helper.trace_received());

  std::optional<base::Value> trace_json =
      base::JSONReader::Read(background_tracing_helper.json_file_contents(),
                             base::JSON_PARSE_CHROMIUM_EXTENSIONS);
  ASSERT_TRUE(trace_json);
  ASSERT_TRUE(trace_json->is_dict());
  auto* metadata_json = trace_json->GetDict().FindDict("metadata");
  ASSERT_TRUE(metadata_json);
}

// 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(crbug.com/40680210) 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::IsStackUnwindingSupportedForTesting()) {
    return;
  }

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

  TestBackgroundTracingHelper background_tracing_helper;

  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: { manual_trigger_name: "start_trigger" }
      upload_rules: { manual_trigger_name: "upload_trigger" }
      trace_config: {
        data_sources: {
          config: {
            name: "track_event"
            track_event_config: {
              disabled_categories: [ "*" ],
              enabled_categories: [ "content" ]
            }
          }
        }
      }
    }
  )pb";

  BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::ANONYMIZE_DATA, false, 0);

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

  wait_for_sample.Run();

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("upload_trigger"));
  background_tracing_helper.WaitForScenarioIdle();
  background_tracing_helper.WaitForTraceReceived();

  EXPECT_TRUE(background_tracing_helper.trace_received());

  trace_analyzer::TraceEventVector events;
  std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer(
      trace_analyzer::TraceAnalyzer::Create(
          background_tracing_helper.json_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 =
      base::TransformModuleIDToSymbolServerFormat(this_module->GetId());

  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);
}

IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       SetupStartupTracing) {
  std::unique_ptr<TestStartupPreferenceManagerImpl> preferences_moved(
      new TestStartupPreferenceManagerImpl);
  TestStartupPreferenceManagerImpl* preferences = preferences_moved.get();
  BackgroundTracingManagerImpl::GetInstance().SetPreferenceManagerForTesting(
      std::move(preferences_moved));
  preferences->SetBackgroundStartupTracingEnabled(false);

  perfetto::protos::gen::ChromeFieldTracingConfig config;
  EXPECT_TRUE(BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      config, BackgroundTracingManager::ANONYMIZE_DATA, false, 0));

  EXPECT_FALSE(base::trace_event::EmitNamedTrigger(
      base::trace_event::kStartupTracingTriggerName));
}

// TODO(crbug.com/40267734): Re-enable this test once fixed.
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID) || \
    (BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER))
#define MAYBE_RunStartupTracing DISABLED_RunStartupTracing
#else
#define MAYBE_RunStartupTracing RunStartupTracing
#endif
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                       MAYBE_RunStartupTracing) {
  TestBackgroundTracingHelper background_tracing_helper;

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

  perfetto::protos::gen::ChromeFieldTracingConfig config;
  EXPECT_TRUE(BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      config, BackgroundTracingManager::ANONYMIZE_DATA, false, 0));

  background_tracing_helper.ExpectOnScenarioActive("Startup");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger(
      base::trace_event::kStartupTracingTriggerName));

  background_tracing_helper.WaitForTraceStarted();

  background_tracing_helper.ExpectOnScenarioIdle("Startup");
  background_tracing_helper.WaitForScenarioIdle();

  background_tracing_helper.WaitForTraceReceived();
  EXPECT_TRUE(background_tracing_helper.trace_received());
}

namespace {

class ProtoBackgroundTracingTest : public DevToolsProtocolTest {};

}  // namespace

IN_PROC_BROWSER_TEST_F(ProtoBackgroundTracingTest,
                       DevtoolsInterruptsBackgroundTracing) {
  TestBackgroundTracingHelper background_tracing_helper;
  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: { manual_trigger_name: "start_trigger" }
      trace_config: {
        data_sources: { config: { name: "org.chromium.trace_metadata2" } }
      }
    }
  )pb";

  EXPECT_TRUE(BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::NO_DATA_FILTERING, false, 0));

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

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

  const base::Value::Dict* start_tracing_result =
      SendCommandSync("Tracing.start");
  ASSERT_TRUE(start_tracing_result);
  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  BackgroundTracingManager::GetInstance().AbortScenarioForTesting();
  background_tracing_helper.WaitForScenarioIdle();
}

IN_PROC_BROWSER_TEST_F(ProtoBackgroundTracingTest, ProtoTraceReceived) {
  TestBackgroundTracingHelper background_tracing_helper;

  EXPECT_TRUE(BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      CreateSimpleScenarioConfig(), BackgroundTracingManager::ANONYMIZE_DATA,
      false, 0));

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

  // Add track event with blocked args.
  TRACE_EVENT_INSTANT("log", "LogMessage", [&](perfetto::EventContext ctx) {
    ctx.event()->set_log_message()->set_body_iid(
        base::trace_event::InternedLogMessage::Get(&ctx, std::string("test")));
  });

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

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("upload_trigger"));
  background_tracing_helper.WaitForScenarioIdle();

  background_tracing_helper.WaitForTraceSaved();
  EXPECT_TRUE(BackgroundTracingManager::GetInstance().HasTraceToUpload());

  std::string compressed_trace;
  base::RunLoop run_loop;
  BackgroundTracingManager::GetInstance().GetTraceToUpload(
      base::BindLambdaForTesting([&](std::optional<std::string> trace_content,
                                     std::optional<std::string> system_profile,
                                     base::OnceClosure upload_complete) {
        ASSERT_TRUE(trace_content);
        compressed_trace = std::move(*trace_content);
        std::move(upload_complete).Run();
        run_loop.Quit();
      }));
  run_loop.Run();

  std::string serialized_trace;
  ASSERT_TRUE(compression::GzipUncompress(compressed_trace, &serialized_trace));
  tracing::PrivacyFilteringCheck checker;
  checker.CheckProtoForUnexpectedFields(serialized_trace);
  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);
  EXPECT_FALSE(checker.stats().has_interned_log_messages);
}

// TODO(crbug.com/452421404): Flaky on Linux TSAN bot.
#if BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)
#define MAYBE_ReceiveCallback DISABLED_ReceiveCallback
#else
#define MAYBE_ReceiveCallback ReceiveCallback
#endif  // BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)
IN_PROC_BROWSER_TEST_F(ProtoBackgroundTracingTest, MAYBE_ReceiveCallback) {
  TestBackgroundTracingHelper background_tracing_helper;

  EXPECT_TRUE(BackgroundTracingManager::GetInstance().InitializeFieldScenarios(
      CreateSimpleScenarioConfig(), BackgroundTracingManager::ANONYMIZE_DATA,
      false, 0));

  // If a ReceiveCallback is given, it should be triggered instead of
  // SetTraceToUpload. (In production this is used to implement the
  // kBackgroundTracingOutputFile parameter, not to upload traces.)
  std::string received_trace_data;
  BackgroundTracingManager::GetInstance().SetReceiveCallback(
      base::BindLambdaForTesting(
          [&](const std::string& file_name, std::string proto_content,
              BackgroundTracingManager::FinishedProcessingCallback callback) {
            received_trace_data = std::move(proto_content);
            std::move(callback).Run(true);
          }));

  background_tracing_helper.ExpectOnScenarioActive("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("start_trigger"));
  background_tracing_helper.WaitForTraceStarted();

  // Add track event with blocked args.
  TRACE_EVENT_INSTANT("log", "LogMessage", [&](perfetto::EventContext ctx) {
    ctx.event()->set_log_message()->set_body_iid(
        base::trace_event::InternedLogMessage::Get(&ctx, std::string("test")));
  });

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

  background_tracing_helper.ExpectOnScenarioIdle("test_scenario");
  EXPECT_TRUE(base::trace_event::EmitNamedTrigger("upload_trigger"));
  background_tracing_helper.WaitForScenarioIdle();
  background_tracing_helper.WaitForTraceReceived();
  EXPECT_FALSE(BackgroundTracingManager::GetInstance().HasTraceToUpload());
  ASSERT_TRUE(background_tracing_helper.trace_received());
  std::string trace_data = background_tracing_helper.proto_file_contents();
  EXPECT_EQ(received_trace_data, trace_data);

  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);
  EXPECT_FALSE(checker.stats().has_interned_log_messages);
}

}  // namespace content
