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     REACHED_CODE_SCENARIO_TRIGGERED = 15,
90     NUMBER_OF_BACKGROUND_TRACING_METRICS,
91   };
92   static void RecordMetric(Metrics metric);
93 
94   CONTENT_EXPORT static BackgroundTracingManagerImpl* GetInstance();
95 
96   // Callable from any thread.
97   static void ActivateForProcess(int child_process_id,
98                                  mojom::ChildProcess* child_process);
99 
100   bool SetActiveScenario(std::unique_ptr<BackgroundTracingConfig>,
101                          ReceiveCallback,
102                          DataFiltering data_filtering) override;
103   void AbortScenario();
104   bool HasActiveScenario() override;
105 
106   // Named triggers
107   void TriggerNamedEvent(TriggerHandle, StartedFinalizingCallback) override;
108   TriggerHandle RegisterTriggerType(const char* trigger_name) override;
109   std::string GetTriggerNameFromHandle(TriggerHandle handle) const;
110 
111   void OnHistogramTrigger(const std::string& histogram_name);
112 
113   void OnRuleTriggered(const BackgroundTracingRule* triggered_rule,
114                        StartedFinalizingCallback callback);
115   bool HasTraceToUpload() override;
116   std::string GetLatestTraceToUpload() override;
117   void SetTraceToUpload(std::unique_ptr<std::string> trace_data);
118   std::string GetBackgroundTracingUploadUrl(
119       const std::string& trial_name) override;
120   std::unique_ptr<BackgroundTracingConfig> GetBackgroundTracingConfig(
121       const std::string& trial_name) override;
122 
123   // Add/remove EnabledStateObserver.
124   CONTENT_EXPORT void AddEnabledStateObserver(EnabledStateObserver* observer);
125   CONTENT_EXPORT void RemoveEnabledStateObserver(
126       EnabledStateObserver* observer);
127 
128   // Add/remove Agent{Observer}.
129   void AddAgent(tracing::mojom::BackgroundTracingAgent* agent);
130   void RemoveAgent(tracing::mojom::BackgroundTracingAgent* agent);
131   void AddAgentObserver(AgentObserver* observer);
132   void RemoveAgentObserver(AgentObserver* observer);
133 
134   void AddMetadataGeneratorFunction();
135 
136   bool IsAllowedFinalization() const;
137 
138   // Called by BackgroundTracingActiveScenario
139   void OnStartTracingDone(BackgroundTracingConfigImpl::CategoryPreset preset);
140 
141   // For tests
142   CONTENT_EXPORT BackgroundTracingActiveScenario* GetActiveScenarioForTesting();
143   CONTENT_EXPORT void InvalidateTriggerHandlesForTesting();
144   CONTENT_EXPORT bool IsTracingForTesting();
145   void WhenIdle(IdleCallback idle_callback) override;
146   CONTENT_EXPORT void AbortScenarioForTesting() override;
147   CONTENT_EXPORT void SetTraceToUploadForTesting(
148       std::unique_ptr<std::string> trace_data) override;
149   void SetConfigTextFilterForTesting(
150       ConfigTextFilterForTesting predicate) override;
151 
152  private:
153   friend class base::NoDestructor<BackgroundTracingManagerImpl>;
154 
155   BackgroundTracingManagerImpl();
156   ~BackgroundTracingManagerImpl() override;
157 
158   void ValidateStartupScenario();
159   bool IsSupportedConfig(BackgroundTracingConfigImpl* config);
160   std::unique_ptr<base::DictionaryValue> GenerateMetadataDict();
161   void GenerateMetadataProto(
162       perfetto::protos::pbzero::ChromeMetadataPacket* metadata,
163       bool privacy_filtering_enabled);
164   bool IsTriggerHandleValid(TriggerHandle handle) const;
165   void OnScenarioAborted();
166   static void AddPendingAgent(
167       int child_process_id,
168       mojo::PendingRemote<tracing::mojom::BackgroundTracingAgentProvider>
169           provider);
170   static void ClearPendingAgent(int child_process_id);
171   void MaybeConstructPendingAgents();
172 
173   std::unique_ptr<BackgroundTracingActiveScenario> active_scenario_;
174 
175   std::unique_ptr<TracingDelegate> delegate_;
176   std::map<TriggerHandle, std::string> trigger_handles_;
177   int trigger_handle_ids_;
178 
179   // Note, these sets are not mutated during iteration so it is okay to not use
180   // base::ObserverList.
181   std::set<EnabledStateObserver*> background_tracing_observers_;
182   std::set<tracing::mojom::BackgroundTracingAgent*> agents_;
183   std::set<AgentObserver*> agent_observers_;
184 
185   std::map<int, mojo::Remote<tracing::mojom::BackgroundTracingAgentProvider>>
186       pending_agents_;
187 
188   IdleCallback idle_callback_;
189   base::RepeatingClosure tracing_enabled_callback_for_testing_;
190 
191   // This field contains serialized trace log proto.
192   std::string trace_to_upload_;
193 
194   // Callback to override the background tracing config for testing.
195   ConfigTextFilterForTesting config_text_filter_for_testing_;
196 
197   DISALLOW_COPY_AND_ASSIGN(BackgroundTracingManagerImpl);
198 };
199 
200 }  // namespace content
201 
202 #endif  // CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_
203