#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "content/browser/devtools/protocol/tracing_handler.h"
#include <algorithm>
#include <cmath>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/json/json_writer.h"
#include "base/memory/ref_counted_memory.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/strcat.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event_impl.h"
#include "base/trace_event/traced_value.h"
#include "base/trace_event/tracing_agent.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/devtools_io_context.h"
#include "content/browser/devtools/devtools_stream_file.h"
#include "content/browser/devtools/devtools_traceable_screenshot.h"
#include "content/browser/devtools/devtools_video_consumer.h"
#include "content/browser/devtools/tracing_process_set_monitor.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/tracing/tracing_controller_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/tracing_service.h"
#include "content/public/browser/web_contents.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
#include "services/tracing/public/cpp/perfetto/perfetto_config.h"
#include "services/tracing/public/cpp/perfetto/perfetto_session.h"
#include "services/tracing/public/cpp/perfetto/trace_packet_tokenizer.h"
#include "services/tracing/public/cpp/trace_startup_config.h"
#include "services/tracing/public/cpp/tracing_features.h"
#include "services/tracing/public/mojom/constants.mojom-forward.h"
#include "third_party/abseil-cpp/absl/strings/ascii.h"
#include "third_party/inspector_protocol/crdtp/json.h"
#if BUILDFLAG(IS_ANDROID)
#include "content/browser/renderer_host/compositor_impl_android.h"
#endif
namespace content::protocol {
namespace {
const double kMinimumReportingInterval = …;
const char kRecordModeParam[] = …;
const char kTraceBufferSizeInKb[] = …;
const char kTrackEventDataSourceName[] = …;
constexpr gfx::Size kMinFrameSize = …;
constexpr gfx::Size kMaxFrameSize = …;
std::string ConvertFromCamelCase(const std::string& in_str, char separator) { … }
base::Value ConvertDictKeyStyle(const base::Value& value) { … }
class DevToolsTraceEndpointProxy : public TracingController::TraceDataEndpoint { … };
class DevToolsStreamEndpoint : public TracingController::TraceDataEndpoint { … };
std::string GetProcessHostHex(RenderProcessHost* host) { … }
void SendProcessReadyInBrowserEvent(const base::UnguessableToken& frame_token,
RenderProcessHost* host) { … }
void FillFrameData(base::trace_event::TracedValue* data,
RenderFrameHostImpl* frame_host,
const GURL& url) { … }
std::optional<base::trace_event::MemoryDumpLevelOfDetail>
StringToMemoryDumpLevelOfDetail(const std::string& str) { … }
void AddPidsToProcessFilter(
const std::unordered_set<base::ProcessId>& included_process_ids,
perfetto::TraceConfig& trace_config) { … }
bool IsChromeDataSource(const std::string& data_source_name) { … }
std::optional<perfetto::BackendType> GetBackendTypeFromParameters(
const std::string& tracing_backend,
perfetto::TraceConfig& perfetto_config) { … }
void ConvertToTrackEventConfigIfNeeded(perfetto::TraceConfig& trace_config) { … }
static bool g_any_agent_tracing = …;
}
class TracingHandler::PerfettoTracingSession { … };
TracingHandler::TracingHandler(DevToolsAgentHostImpl* host,
DevToolsIOContext* io_context,
DevToolsSession* root_session)
: … { … }
TracingHandler::~TracingHandler() = default;
std::vector<TracingHandler*> TracingHandler::ForAgentHost(
DevToolsAgentHostImpl* host) { … }
void TracingHandler::Wire(UberDispatcher* dispatcher) { … }
Response TracingHandler::Disable() { … }
namespace {
class TracingNotification : public crdtp::Serializable { … };
}
void TracingHandler::OnTraceDataCollected(
std::unique_ptr<std::string> trace_fragment) { … }
void TracingHandler::OnTraceComplete() { … }
std::string TracingHandler::UpdateTraceDataBuffer(
const std::string& trace_fragment) { … }
void TracingHandler::OnTraceToStreamComplete(const std::string& stream_handle) { … }
void TracingHandler::Start(Maybe<std::string> categories,
Maybe<std::string> options,
Maybe<double> buffer_usage_reporting_interval,
Maybe<std::string> transfer_mode,
Maybe<std::string> transfer_format,
Maybe<std::string> transfer_compression,
Maybe<Tracing::TraceConfig> config,
Maybe<Binary> perfetto_config,
Maybe<std::string> tracing_backend,
std::unique_ptr<StartCallback> callback) { … }
perfetto::TraceConfig TracingHandler::CreatePerfettoConfiguration(
const base::trace_event::TraceConfig& browser_config,
bool return_as_stream,
bool proto_format) { … }
void TracingHandler::AddProcessToFilter(base::ProcessId pid) { … }
void TracingHandler::AttemptAdoptStartupSession(
bool return_as_stream,
bool gzip_compression,
bool proto_format,
perfetto::BackendType tracing_backend) { … }
Response TracingHandler::End() { … }
void TracingHandler::GetCategories(
std::unique_ptr<GetCategoriesCallback> callback) { … }
void TracingHandler::OnRecordingEnabled(std::unique_ptr<StartCallback> callback,
const std::string& error_msg) { … }
void TracingHandler::OnBufferUsage(bool success,
float percent_full,
size_t approximate_event_count) { … }
void TracingHandler::OnCategoriesReceived(
std::unique_ptr<GetCategoriesCallback> callback,
const std::set<std::string>& category_set) { … }
void TracingHandler::RequestMemoryDump(
Maybe<bool> deterministic,
Maybe<std::string> level_of_detail,
std::unique_ptr<RequestMemoryDumpCallback> callback) { … }
void TracingHandler::OnMemoryDumpFinished(
std::unique_ptr<RequestMemoryDumpCallback> callback,
bool success,
uint64_t dump_id) { … }
void TracingHandler::OnFrameFromVideoConsumer(
scoped_refptr<media::VideoFrame> frame) { … }
Response TracingHandler::RecordClockSyncMarker(const std::string& sync_id) { … }
void TracingHandler::SetupTimer(double usage_reporting_interval) { … }
void TracingHandler::UpdateBufferUsage() { … }
void TracingHandler::StopTracing(
const scoped_refptr<TracingController::TraceDataEndpoint>& endpoint) { … }
bool TracingHandler::IsTracing() const { … }
void TracingHandler::EmitFrameTree() { … }
void TracingHandler::WillInitiatePrerender(FrameTreeNode* frame_tree_node) { … }
void TracingHandler::ReadyToCommitNavigation(
NavigationRequest* navigation_request) { … }
void TracingHandler::FrameDeleted(int frame_tree_node_id) { … }
bool TracingHandler::IsStartupTracingActive() { … }
base::trace_event::TraceConfig TracingHandler::GetTraceConfigFromDevToolsConfig(
const base::Value& devtools_config) { … }
}