Andrew Lee | 197daae6 | 2019-08-22 21:51:43 | [diff] [blame] | 1 | // Copyright 2019 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef COMPONENTS_UI_DEVTOOLS_TRACING_AGENT_H_ |
| 6 | #define COMPONENTS_UI_DEVTOOLS_TRACING_AGENT_H_ |
| 7 | |
| 8 | #include <memory> |
| 9 | #include <string> |
| 10 | #include <utility> |
| 11 | |
| 12 | #include "base/callback.h" |
| 13 | #include "base/memory/weak_ptr.h" |
| 14 | #include "base/trace_event/trace_config.h" |
| 15 | #include "components/ui_devtools/Tracing.h" |
| 16 | #include "components/ui_devtools/devtools_base_agent.h" |
| 17 | |
| 18 | namespace base { |
| 19 | class RepeatingTimer; |
| 20 | } |
| 21 | |
| 22 | namespace ui_devtools { |
| 23 | |
| 24 | class ConnectorDelegate; |
| 25 | |
| 26 | // This class is used for tracing in the ui_devtools performance panel. |
| 27 | // A lot of the code is based on TracingHandler from |
| 28 | // content/browser/devtools/protocol/tracing_handler.h. |
| 29 | class UI_DEVTOOLS_EXPORT TracingAgent |
| 30 | : public UiDevToolsBaseAgent<protocol::Tracing::Metainfo> { |
| 31 | public: |
| 32 | explicit TracingAgent(std::unique_ptr<ConnectorDelegate> connector); |
| 33 | ~TracingAgent() override; |
| 34 | |
Mitsuru Oshima | 4de59ac | 2019-09-03 20:49:09 | [diff] [blame] | 35 | void set_gpu_pid(base::ProcessId pid) { gpu_pid_ = pid; } |
| 36 | |
Andrew Lee | 197daae6 | 2019-08-22 21:51:43 | [diff] [blame] | 37 | // Sends the Tracing JSON data in the form of CBOR to the frontend. |
| 38 | void OnTraceDataCollected(std::unique_ptr<std::string> trace_fragment); |
| 39 | |
| 40 | // Signals that tracing is complete and notifies any data loss to the |
| 41 | // frontend. |
| 42 | void OnTraceComplete(); |
| 43 | |
| 44 | // Tracing::Backend: |
| 45 | void start(protocol::Maybe<std::string> categories, |
| 46 | protocol::Maybe<std::string> options, |
| 47 | protocol::Maybe<double> buffer_usage_reporting_interval, |
| 48 | std::unique_ptr<StartCallback> callback) override; |
| 49 | protocol::Response end() override; |
| 50 | |
| 51 | private: |
| 52 | class DevToolsTraceEndpointProxy; |
| 53 | class PerfettoTracingSession; |
| 54 | |
| 55 | struct TraceDataBufferState { |
| 56 | public: |
| 57 | std::string data; |
| 58 | size_t pos = 0; |
| 59 | int open_braces = 0; |
| 60 | bool in_string = false; |
| 61 | bool slashed = false; |
| 62 | size_t offset = 0; |
| 63 | }; |
| 64 | |
| 65 | // Returns the longest prefix of |trace_fragment| that is a valid list and |
| 66 | // stores the rest (tail) to be used in subsequent calls. This returns the |
| 67 | // longest prefix of the tail prepended to |trace_fragment| next time. Assumes |
| 68 | // that the input is a potentially incomplete string representation of a comma |
| 69 | // separated list of JSON objects. |
| 70 | std::string UpdateTraceDataBuffer(const std::string& trace_fragment); |
| 71 | |
| 72 | // Sets TraceConfig to only collect trace events for the specified processes |
| 73 | // in this method. Currently, only the browser process is specified. Starts |
| 74 | // tracing by attempting to enable tracing via perfetto. |
| 75 | void StartTracing(std::unique_ptr<StartCallback>); |
| 76 | |
| 77 | // Called when we have successfully started tracing with Perfetto session. |
| 78 | void OnRecordingEnabled(std::unique_ptr<StartCallback> callback); |
| 79 | |
Andrew Lee | 7459ca47 | 2019-08-23 16:16:18 | [diff] [blame] | 80 | // Edits tracing data to use the normal devtools frontend logic to display |
| 81 | // the performance metrics. Without this, it will use the devtools generic |
| 82 | // trace logic to display the performance metrics. |
| 83 | void EditTraceDataForFrontend(); |
| 84 | |
Andrew Lee | 197daae6 | 2019-08-22 21:51:43 | [diff] [blame] | 85 | // Sets up repeating timer to request the trace buffer status from the |
| 86 | // perfetto tracing session. If usage_reporting_interval is too small, it will |
| 87 | // be clipped to a minimum value. |
| 88 | void SetupTimer(double usage_reporting_interval); |
| 89 | |
| 90 | // Sends frontend information on buffer usage such as how much of the buffer |
| 91 | // is used and the approximate number of events in the trace log. |
| 92 | void OnBufferUsage(float percent_full, size_t approximate_event_count); |
| 93 | |
| 94 | // Gets updated buffer usage from the perfetto tracing session. |
| 95 | void UpdateBufferUsage(); |
| 96 | |
| 97 | // Resets buffer usage and passes the trace data to the trace data endpoint |
| 98 | // consumer. |
| 99 | void StopTracing(const scoped_refptr<DevToolsTraceEndpointProxy>& endpoint, |
| 100 | const std::string& agent_label); |
| 101 | |
| 102 | std::unique_ptr<base::RepeatingTimer> buffer_usage_poll_timer_; |
| 103 | std::unique_ptr<ConnectorDelegate> connector_; |
| 104 | base::ProcessId gpu_pid_ = base::kNullProcessId; |
| 105 | bool did_initiate_recording_ = false; |
| 106 | double buffer_usage_reporting_interval_ = 0; |
| 107 | base::trace_event::TraceConfig trace_config_; |
| 108 | std::unique_ptr<PerfettoTracingSession> perfetto_session_; |
| 109 | TraceDataBufferState trace_data_buffer_state_; |
| 110 | base::WeakPtrFactory<TracingAgent> weak_factory_{this}; |
| 111 | DISALLOW_COPY_AND_ASSIGN(TracingAgent); |
| 112 | }; |
| 113 | |
| 114 | } // namespace ui_devtools |
| 115 | |
| 116 | #endif // COMPONENTS_UI_DEVTOOLS_TRACING_AGENT_H_ |