1 // Copyright 2015 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 CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_
6 #define CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_
7 
8 #include <map>
9 #include <memory>
10 #include <set>
11 #include <string>
12 #include <vector>
13 
14 #include "base/macros.h"
15 #include "content/browser/tracing/background_tracing_config_impl.h"
16 #include "content/public/browser/background_tracing_manager.h"
17 #include "mojo/public/cpp/bindings/remote.h"
18 #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h"
19 #include "services/tracing/public/mojom/background_tracing_agent.mojom.h"
20 
21 namespace base {
22 template <typename T>
23 class NoDestructor;
24 }  // namespace base
25 
26 namespace tracing {
27 namespace mojom {
28 class BackgroundTracingAgent;
29 class BackgroundTracingAgentProvider;
30 }  // namespace mojom
31 }  // namespace tracing
32 
33 namespace content {
34 namespace mojom {
35 class ChildProcess;
36 }  // namespace mojom
37 
38 class BackgroundTracingRule;
39 class BackgroundTracingActiveScenario;
40 class TracingDelegate;
41 
42 class BackgroundTracingManagerImpl : public BackgroundTracingManager {
43  public:
44   // Enabled state observers get a callback when the state of background tracing
45   // changes.
46   class CONTENT_EXPORT EnabledStateObserver {
47    public:
48     // Called when the activation of a background tracing scenario is
49     // successful.
50     virtual void OnScenarioActivated(
51         const BackgroundTracingConfigImpl* config) = 0;
52 
53     // In case the scenario was aborted before or after tracing was enabled.
54     virtual void OnScenarioAborted() = 0;
55 
56     // Called after tracing is enabled on all processes because the rule was
57     // triggered.
58     virtual void OnTracingEnabled(
59         BackgroundTracingConfigImpl::CategoryPreset preset) = 0;
60 
61     virtual ~EnabledStateObserver() = default;
62   };
63 
64   class AgentObserver {
65    public:
66     virtual void OnAgentAdded(
67         tracing::mojom::BackgroundTracingAgent* agent) = 0;
68     virtual void OnAgentRemoved(
69         tracing::mojom::BackgroundTracingAgent* agent) = 0;
70   };
71 
72   // These values are used for a histogram. Do not reorder.
73   enum class Metrics {
74     SCENARIO_ACTIVATION_REQUESTED = 0,
75     SCENARIO_ACTIVATED_SUCCESSFULLY = 1,
76     RECORDING_ENABLED = 2,
77     PREEMPTIVE_TRIGGERED = 3,
78     REACTIVE_TRIGGERED = 4,
79     FINALIZATION_ALLOWED = 5,
80     FINALIZATION_DISALLOWED = 6,
81     FINALIZATION_STARTED = 7,
82     OBSOLETE_FINALIZATION_COMPLETE = 8,
83     SCENARIO_ACTION_FAILED_LOWRES_CLOCK = 9,
84     UPLOAD_FAILED = 10,
85     UPLOAD_SUCCEEDED = 11,
86     STARTUP_SCENARIO_TRIGGERED = 12,
87     LARGE_UPLOAD_WAITING_TO_RETRY = 13,
88     SYSTEM_TRIGGERED = 14,
89     NUMBER_OF_BACKGROUND_TRACING_METRICS,
90   };
91   static void RecordMetric(Metrics metric);
92 
93   CONTENT_EXPORT static BackgroundTracingManagerImpl* GetInstance();
94 
95   // Callable from any thread.
96   static void ActivateForProcess(int child_process_id,
97                                  mojom::ChildProcess* child_process);
98 
99   bool SetActiveScenario(std::unique_ptr<BackgroundTracingConfig>,
100                          ReceiveCallback,
101                          DataFiltering data_filtering) override;
102   void AbortScenario();
103   bool HasActiveScenario() override;
104 
105   // Named triggers
106   void TriggerNamedEvent(TriggerHandle, StartedFinalizingCallback) override;
107   TriggerHandle RegisterTriggerType(const char* trigger_name) override;
108   std::string GetTriggerNameFromHandle(TriggerHandle handle) const;
109 
110   void OnHistogramTrigger(const std::string& histogram_name);
111 
112   void OnRuleTriggered(const BackgroundTracingRule* triggered_rule,
113                        StartedFinalizingCallback callback);
114   bool HasTraceToUpload() override;
115   std::string GetLatestTraceToUpload() override;
116   void SetTraceToUpload(std::unique_ptr<std::string> trace_data);
117 
118   // Add/remove EnabledStateObserver.
119   CONTENT_EXPORT void AddEnabledStateObserver(EnabledStateObserver* observer);
120   CONTENT_EXPORT void RemoveEnabledStateObserver(
121       EnabledStateObserver* observer);
122 
123   // Add/remove Agent{Observer}.
124   void AddAgent(tracing::mojom::BackgroundTracingAgent* agent);
125   void RemoveAgent(tracing::mojom::BackgroundTracingAgent* agent);
126   void AddAgentObserver(AgentObserver* observer);
127   void RemoveAgentObserver(AgentObserver* observer);
128 
129   void AddMetadataGeneratorFunction();
130 
131   bool IsAllowedFinalization() const;
132 
133   // Called by BackgroundTracingActiveScenario
134   void OnStartTracingDone(BackgroundTracingConfigImpl::CategoryPreset preset);
135 
136   // For tests
137   CONTENT_EXPORT BackgroundTracingActiveScenario* GetActiveScenarioForTesting();
138   CONTENT_EXPORT void InvalidateTriggerHandlesForTesting();
139   CONTENT_EXPORT bool IsTracingForTesting();
140   void WhenIdle(IdleCallback idle_callback) override;
141   CONTENT_EXPORT void AbortScenarioForTesting() override;
142   CONTENT_EXPORT void SetTraceToUploadForTesting(
143       std::unique_ptr<std::string> trace_data) override;
144 
145  private:
146   friend class base::NoDestructor<BackgroundTracingManagerImpl>;
147 
148   BackgroundTracingManagerImpl();
149   ~BackgroundTracingManagerImpl() override;
150 
151   void ValidateStartupScenario();
152   bool IsSupportedConfig(BackgroundTracingConfigImpl* config);
153   std::unique_ptr<base::DictionaryValue> GenerateMetadataDict();
154   void GenerateMetadataProto(
155       perfetto::protos::pbzero::ChromeMetadataPacket* metadata,
156       bool privacy_filtering_enabled);
157   bool IsTriggerHandleValid(TriggerHandle handle) const;
158   void OnScenarioAborted();
159   static void AddPendingAgent(
160       int child_process_id,
161       mojo::PendingRemote<tracing::mojom::BackgroundTracingAgentProvider>
162           provider);
163   static void ClearPendingAgent(int child_process_id);
164   void MaybeConstructPendingAgents();
165 
166   std::unique_ptr<BackgroundTracingActiveScenario> active_scenario_;
167 
168   std::unique_ptr<TracingDelegate> delegate_;
169   std::map<TriggerHandle, std::string> trigger_handles_;
170   int trigger_handle_ids_;
171 
172   // Note, these sets are not mutated during iteration so it is okay to not use
173   // base::ObserverList.
174   std::set<EnabledStateObserver*> background_tracing_observers_;
175   std::set<tracing::mojom::BackgroundTracingAgent*> agents_;
176   std::set<AgentObserver*> agent_observers_;
177 
178   std::map<int, mojo::Remote<tracing::mojom::BackgroundTracingAgentProvider>>
179       pending_agents_;
180 
181   IdleCallback idle_callback_;
182   base::RepeatingClosure tracing_enabled_callback_for_testing_;
183 
184   // This field contains serialized trace log proto.
185   std::string trace_to_upload_;
186 
187   DISALLOW_COPY_AND_ASSIGN(BackgroundTracingManagerImpl);
188 };
189 
190 }  // namespace content
191 
192 #endif  // CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_
193