File: webrtc_log_uploader.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (262 lines) | stat: -rw-r--r-- 10,520 bytes parent folder | download | duplicates (10)
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_LOG_UPLOADER_H_
#define CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_LOG_UPLOADER_H_

#include <stdint.h>

#include <list>
#include <map>
#include <memory>
#include <optional>
#include <string>

#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "chrome/browser/media/webrtc/webrtc_log_buffer.h"
#include "url/gurl.h"

namespace network {
class SimpleURLLoader;
}

typedef struct z_stream_s z_stream;

struct WebRtcLogPaths {
  base::FilePath directory;
  base::FilePath incoming_rtp_dump;
  base::FilePath outgoing_rtp_dump;
};

typedef std::map<std::string, std::string> WebRtcLogMetaDataMap;

// Upload failure reasons used for UMA stats. A failure reason can be one of
// those listed here or a response code for the upload HTTP request. The
// values in this list must be less than 100 and cannot be changed.
struct WebRtcLogUploadFailureReason {
  enum {
    kInvalidState = 0,
    kStoredLogNotFound = 1,
    kNetworkError = 2,
  };
};

// Changes the crash product under which text and event logs are uploaded
// to have a "_webrtc" suffix, and removes the "-webrtc" suffix from the
// crash version field.
// eg, when enabled: product: "Chrome_Mac_webrtc", version: "121.0.6151.0"
// when disabled: product: "Chrome_Mac", version: "121.0.6151.0-webrtc"
BASE_DECLARE_FEATURE(kWebRTCLogUploadSuffix);

// Returns the product string to use for crash log uploads.
std::string GetLogUploadProduct();

// Returns the version string to use for crash log uploads.
std::string GetLogUploadVersion();

// WebRtcLogUploader uploads WebRTC logs, keeps count of how many logs have
// been started and denies further logs if a limit is reached. It also adds
// the timestamp and report ID of the uploded log to a text file. There must
// only be one object of this type.
class WebRtcLogUploader {
 public:
  typedef base::OnceCallback<void(bool, const std::string&)>
      GenericDoneCallback;
  typedef base::OnceCallback<void(bool is_upload_successful,
                                  const std::string& report_id,
                                  const std::string& error_message)>
      UploadDoneCallback;

  static constexpr char kLogUploadDisabledMsg[] =
      "WebRtc text log upload is disabled";

  // Used when uploading is done to perform post-upload actions. |paths| is
  // also used pre-upload.
  struct UploadDoneData {
    UploadDoneData();
    UploadDoneData(UploadDoneData&& other);
    ~UploadDoneData();

    WebRtcLogPaths paths;
    UploadDoneCallback callback;
    std::string local_log_id;
    // Used for statistics. See |WebRtcLoggingHandlerHost::web_app_id_|.
    int web_app_id;
  };

  static WebRtcLogUploader* GetInstance();
  WebRtcLogUploader();

  WebRtcLogUploader(const WebRtcLogUploader&) = delete;
  WebRtcLogUploader& operator=(const WebRtcLogUploader&) = delete;

  ~WebRtcLogUploader();

  // Returns true is number of logs limit is not reached yet. Increases log
  // count if true is returned. Must be called before UploadLog().
  bool ApplyForStartLogging();

  // Notifies that logging has stopped and that the log should not be uploaded.
  // Decreases log count. May only be called if permission to log has been
  // granted by calling ApplyForStartLogging() and getting true in return.
  // After this function has been called, a new permission must be granted.
  // Call either this function or LoggingStoppedDoUpload().
  void LoggingStoppedDontUpload();

  // Notifies that that logging has stopped. Stores text logs in gz file.
  // Logs are uploaded if allowed by policy. Decreases log count.
  // May only be called if permission to log has been
  // granted by calling ApplyForStartLogging() and getting true in return. After
  // this function has been called, a new permission must be granted. Call
  // either this function or LoggingStoppedDontUpload().
  // |upload_done_data.local_log_id| is set and used internally and should be
  // left empty.
  void OnLoggingStopped(std::unique_ptr<WebRtcLogBuffer> log_buffer,
                        std::unique_ptr<WebRtcLogMetaDataMap> meta_data,
                        UploadDoneData upload_done_data,
                        bool is_text_log_upload_allowed);

  // Uploads a previously stored log (see LoggingStoppedDoStore()).
  void UploadStoredLog(UploadDoneData upload_data);

  // Similarly to LoggingStoppedDoUpload(), we store the log in compressed
  // format on disk but add the option to specify a unique |log_id| for later
  // identification and potential upload.
  void LoggingStoppedDoStore(const WebRtcLogPaths& log_paths,
                             const std::string& log_id,
                             std::unique_ptr<WebRtcLogBuffer> log_buffer,
                             std::unique_ptr<WebRtcLogMetaDataMap> meta_data,
                             GenericDoneCallback done_callback);

  // Cancels URL fetcher operation by deleting all URL fetchers. This cancels
  // any pending uploads and releases SystemURLRequestContextGetter references.
  // Sets |shutdown_| which prevents new fetchers from being created.
  void Shutdown();

  // For testing purposes. If called, the multipart will not be uploaded, but
  // written to |post_data_| instead.
  void OverrideUploadWithBufferForTesting(std::string* post_data) {
    DCHECK((post_data && !post_data_) || (!post_data && post_data_));
    post_data_ = post_data;
  }

  // For testing purposes.
  void SetUploadUrlForTesting(const GURL& url) {
    DCHECK((!url.is_empty() && upload_url_for_testing_.is_empty()) ||
           (url.is_empty() && !upload_url_for_testing_.is_empty()));
    upload_url_for_testing_ = url;
  }

  const scoped_refptr<base::SequencedTaskRunner>& background_task_runner()
      const {
    return background_task_runner_;
  }

  void NotifyUploadDisabled(UploadDoneData upload_done_data);

 private:
  // Allow the test class to call AddLocallyStoredLogInfoToUploadListFile.
  friend class WebRtcLogUploaderTest;
  FRIEND_TEST_ALL_PREFIXES(WebRtcLogUploaderTest,
                           AddLocallyStoredLogInfoToUploadListFile);
  FRIEND_TEST_ALL_PREFIXES(WebRtcLogUploaderTest,
                           AddUploadedLogInfoToUploadListFile);

  // Sets up a multipart body to be uploaded. The body is produced according
  // to RFC 2046.
  void SetupMultipart(std::string* post_data,
                      const std::string& compressed_log,
                      const base::FilePath& incoming_rtp_dump,
                      const base::FilePath& outgoing_rtp_dump,
                      const std::map<std::string, std::string>& meta_data);

  std::string CompressLog(WebRtcLogBuffer* buffer);

  void UploadCompressedLog(UploadDoneData upload_done_data,
                           std::unique_ptr<std::string> post_data);

  void DecreaseLogCount();

  // Must be called on the FILE thread.
  void WriteCompressedLogToFile(const std::string& compressed_log,
                                const base::FilePath& log_file_path);

  void PrepareMultipartPostData(const std::string& compressed_log,
                                std::unique_ptr<WebRtcLogMetaDataMap> meta_data,
                                UploadDoneData upload_done_data);

  // Append information (upload time, report ID and local ID) about a log to a
  // log list file, limited to |kLogListLimitLines| entries. This list is used
  // for viewing the logs under chrome://webrtc-logs, see WebRtcLogUploadList.
  // The list has the format:
  //   [upload_time],[report_id],[local_id],[capture_time]
  // Each line represents a log.
  // * |upload_time| is the time when the log was uploaded in Unix time.
  // * |report_id| is the ID reported back by the server.
  // * |local_id| is the ID for the locally stored log. It's the time stored
  //   in Unix time and it's also used as file name.
  // * |capture_time| is the Unix time when the log was captured.
  // AddLocallyStoredLogInfoToUploadListFile() will first be called.
  // |upload_time| and |report_id| will be left empty in the entry written to
  // the list file. If uploading is successful,
  // AddUploadedLogInfoToUploadListFile() will be called and those empty fields
  // will be filled out.
  // Must be called on the FILE thread.
  void AddLocallyStoredLogInfoToUploadListFile(
      const base::FilePath& upload_list_path,
      const std::string& local_log_id);
  static void AddUploadedLogInfoToUploadListFile(
      const base::FilePath& upload_list_path,
      const std::string& local_log_id,
      const std::string& report_id);

  // Notifies users that upload has completed and logs UMA stats.
  // |response_code| not having a value means that no response code could be
  // retrieved, in which case |network_error_code| should be something other
  // than net::OK.
  void NotifyUploadDoneAndLogStats(std::optional<int> response_code,
                                   int network_error_code,
                                   const std::string& report_id,
                                   UploadDoneData upload_done_data);

  using SimpleURLLoaderList =
      std::list<std::unique_ptr<network::SimpleURLLoader>>;

  void OnSimpleLoaderComplete(SimpleURLLoaderList::iterator it,
                              UploadDoneData upload_done_data,
                              std::unique_ptr<std::string> response_body);

  SEQUENCE_CHECKER(main_sequence_checker_);

  // Main sequence where this class was constructed.
  scoped_refptr<base::SequencedTaskRunner> main_task_runner_;

  // Background sequence where we run background, potentially blocking,
  // operations.
  scoped_refptr<base::SequencedTaskRunner> background_task_runner_;

  // Keeps track of number of currently open logs. Must only be accessed from
  // the main sequence.
  int log_count_ = 0;

  // For testing purposes, see OverrideUploadWithBufferForTesting. Only accessed
  // on the background sequence
  raw_ptr<std::string> post_data_ = nullptr;

  // For testing purposes.
  GURL upload_url_for_testing_;

  // Only accessed on the main sequence.
  SimpleURLLoaderList pending_uploads_;

  // When true, don't create new URL loaders.
  bool shutdown_ = false;
};

#endif  // CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_LOG_UPLOADER_H_