1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196

content / public / browser / background_tracing_manager.h [blame]

// 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.

#ifndef CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_MANAGER_H_
#define CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_MANAGER_H_

#include <memory>
#include <string>

#include "base/time/time.h"
#include "base/token.h"
#include "base/trace_event/trace_event_impl.h"
#include "content/common/content_export.h"
#include "third_party/perfetto/protos/perfetto/config/chrome/scenario_config.gen.h"

namespace content {
class BackgroundTracingConfig;

// BackgroundTracingManager is used on the browser process to trigger the
// collection of trace data and upload the results. Only the browser UI thread
// is allowed to interact with the BackgroundTracingManager. All callbacks are
// called on the UI thread.
class BackgroundTracingManager {
 public:
  // Creates and return a global BackgroundTracingManager instance.
  CONTENT_EXPORT static std::unique_ptr<BackgroundTracingManager>
  CreateInstance();

  // Returns the global instance created with CreateInstance().
  CONTENT_EXPORT static BackgroundTracingManager& GetInstance();

  CONTENT_EXPORT static const char kContentTriggerConfig[];

  // Enabled state observers get a callback when the state of background tracing
  // changes.
  class CONTENT_EXPORT EnabledStateTestObserver {
   public:
    // Called when |scenario_name| becomes active.
    virtual void OnScenarioActive(const std::string& scenario_name) {}
    // Called when |scenario_name| becomes idle again.
    virtual void OnScenarioIdle(const std::string& scenario_name) {}
    // Called when tracing is enabled on all processes because of an active
    // scenario.
    virtual void OnTraceStarted() {}
    // Called when tracing stopped and |proto_content| was received.
    virtual void OnTraceReceived(const std::string& proto_content) {}
    // Called when the trace content is saved.
    virtual void OnTraceSaved() {}

   protected:
    ~EnabledStateTestObserver() = default;
  };

  virtual ~BackgroundTracingManager() = default;

  // If a ReceiveCallback is set it will be called on the UI thread every time
  // the BackgroundTracingManager finalizes a trace. The first parameter of
  // this callback is the trace data. The second is a callback to notify the
  // BackgroundTracingManager that you've finished processing the trace data
  // and whether we were successful or not.
  //
  // Example:
  //
  // void Upload(std::string data,
  //             FinishedProcessingCallback done_callback) {
  //   base::PostTaskAndReply(
  //       FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
  //       base::BindOnce(&DoUploadInBackground, std::move(data)),
  //       std::move(done_callback));
  // }
  //
  using FinishedProcessingCallback = base::OnceCallback<void(bool success)>;
  using ReceiveCallback = base::RepeatingCallback<
      void(const std::string&, std::string, FinishedProcessingCallback)>;

  virtual void SetReceiveCallback(ReceiveCallback receive_callback) = 0;

  enum DataFiltering {
    NO_DATA_FILTERING,
    ANONYMIZE_DATA,
    ANONYMIZE_DATA_AND_FILTER_PACKAGE_NAME,
  };

  // Set the triggering rules for when to start recording.
  //
  // In preemptive mode, recording begins immediately and any calls to
  // TriggerNamedEvent() will potentially trigger the trace to finalize
  // and get uploaded. Once the trace has been uploaded, tracing will be
  // enabled again.
  //
  // In reactive mode, recording begins when TriggerNamedEvent() is
  // called, and continues until either the next call to
  // TriggerNamedEvent, or a timeout occurs. Tracing will not be
  // re-enabled after the trace is finalized and uploaded.
  //
  // This function uploads traces through UMA using GetTraceToUpload.
  //
  // Calls to SetActiveScenario() with a config will fail if tracing is
  // currently on.
  virtual bool SetActiveScenario(
      std::unique_ptr<BackgroundTracingConfig> config,
      DataFiltering data_filtering) = 0;

  // Initializes a list of triggers from `config` to be forwarded to
  // perfetto. This is useful when system tracing is running. This will
  // fail and return false if any scenario was previously enabled,
  // either with InitializeFieldScenarios() or SetEnabledScenarios().
  // This shouldn't be called if SetActiveScenario() was previously
  // called.
  virtual bool InitializePerfettoTriggerRules(
      const perfetto::protos::gen::TracingTriggerRulesConfig& config) = 0;

  // Tracing Scenarios are enrolled by clients based on a set of start and
  // stop rules that delimitate a meaningful tracing interval, usually covering
  // a user journey or a guardian metric (e.g. FirstContentfulPaint). This can
  // only be called once.
  // Field scenarios are enabled automatically for a subset of the population.
  // Preset scenarios are predefined and enabled locally by manual action from
  // a user. When enabled, they take precedence over field scenarios if any.

  // Saves and enables a set of field scenarios, each associated with specific
  // tracing configs. Returns true if all scenarios were successfully
  // initialized. This will fail and return false if any scenario was previously
  // enabled, either with InitializeFieldScenarios() or SetEnabledScenarios().
  // `force_uploads` allows scenario to ignore upload quotas, and
  // `upload_limit_kb` overrides default upload size limits if not 0. This
  // shouldn't be called if SetActiveScenario() was previously called.
  virtual bool InitializeFieldScenarios(
      const perfetto::protos::gen::ChromeFieldTracingConfig& config,
      DataFiltering data_filtering,
      bool force_uploads,
      size_t upload_limit_kb) = 0;

  // Saves a set of preset scenarios, each associated with specific tracing
  // configs, without enabling them. These scenarios can be enabled with
  // SetEnabledScenarios(). Returns the list of scenario hashes that were
  // successfully added. This can be called multiple times.
  virtual std::vector<std::string> AddPresetScenarios(
      const perfetto::protos::gen::ChromeFieldTracingConfig& config,
      DataFiltering data_filtering) = 0;

  // Enables a list of preset scenarios identified by their hashes. This
  // disables all previously enabled scenarios and aborts the current background
  // tracing session if any. Since InitializeFieldScenarios() above fails if
  // scenarios are enabled, field scenarios can't be re-enabled after calling
  // this.
  virtual bool SetEnabledScenarios(
      std::vector<std::string> enabled_preset_scenario_hashes) = 0;

  virtual bool HasActiveScenario() = 0;

  // Returns true whether a trace is ready to be uploaded.
  virtual bool HasTraceToUpload() = 0;

  // TODO(b/295312118): Move this method to trace_report_list.h when it has
  // landed.
  virtual void DeleteTracesInDateRange(base::Time start, base::Time end) = 0;

  // Loads the content of the next trace saved for uploading and returns
  // it through |callback| in a gzip of a serialized proto of message
  // type perfetto::Trace. |callback| may be invoked either synchronously or
  // on a thread pool task runner.
  virtual void GetTraceToUpload(
      base::OnceCallback<void(std::optional<std::string> /*trace_content*/,
                              std::optional<std::string> /*system_profile*/)>
          callback) = 0;

  // Returns background tracing configuration for the experiment |trial_name|.
  virtual std::unique_ptr<BackgroundTracingConfig> GetBackgroundTracingConfig(
      const std::string& trial_name) = 0;

  // Sets a callback that records `SystemProfileProto` when a trace is
  // collected.
  virtual void SetSystemProfileRecorder(
      base::RepeatingCallback<std::string()> recorder) = 0;

  // For tests
  virtual void AbortScenarioForTesting() = 0;
  virtual void SaveTraceForTesting(std::string&& trace_data,
                                   const std::string& scenario_name,
                                   const std::string& rule_name,
                                   const base::Token& uuid) = 0;

  using ConfigTextFilterForTesting =
      base::RepeatingCallback<std::string(const std::string&)>;

 protected:
  // Sets the instance returns by GetInstance() globally to |tracing_manager|.
  CONTENT_EXPORT static void SetInstance(
      BackgroundTracingManager* tracing_manager);
};

}  // namespace content

#endif  // CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_MANAGER_H_