1// Copyright 2013 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 CHROME_BROWSER_MEDIA_WEBRTC_LOG_UPLOADER_H_
6#define CHROME_BROWSER_MEDIA_WEBRTC_LOG_UPLOADER_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/gtest_prod_util.h"
14#include "base/threading/thread_checker.h"
15#include "chrome/browser/media/webrtc_logging_handler_host.h"
16#include "net/url_request/url_fetcher_delegate.h"
17
18class Profile;
19
20namespace base {
21class SharedMemory;
22}
23
24namespace net {
25class URLFetcher;
26}
27
28typedef struct z_stream_s z_stream;
29
30// Used when uploading is done to perform post-upload actions. |log_path| is
31// also used pre-upload.
32struct WebRtcLogUploadDoneData {
33  WebRtcLogUploadDoneData();
34  ~WebRtcLogUploadDoneData();
35
36  base::FilePath log_path;
37  base::FilePath incoming_rtp_dump;
38  base::FilePath outgoing_rtp_dump;
39  WebRtcLoggingHandlerHost::UploadDoneCallback callback;
40  scoped_refptr<WebRtcLoggingHandlerHost> host;
41  std::string local_log_id;
42};
43
44// WebRtcLogUploader uploads WebRTC logs, keeps count of how many logs have
45// been started and denies further logs if a limit is reached. It also adds
46// the timestamp and report ID of the uploded log to a text file. There must
47// only be one object of this type.
48class WebRtcLogUploader : public net::URLFetcherDelegate {
49 public:
50  WebRtcLogUploader();
51  virtual ~WebRtcLogUploader();
52
53  // net::URLFetcherDelegate implementation.
54  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
55  virtual void OnURLFetchUploadProgress(const net::URLFetcher* source,
56                                        int64 current, int64 total) OVERRIDE;
57
58  // Returns true is number of logs limit is not reached yet. Increases log
59  // count if true is returned. Must be called before UploadLog().
60  bool ApplyForStartLogging();
61
62  // Notifies that logging has stopped and that the log should not be uploaded.
63  // Decreases log count. May only be called if permission to log has been
64  // granted by calling ApplyForStartLogging() and getting true in return.
65  // After this function has been called, a new permission must be granted.
66  // Call either this function or LoggingStoppedDoUpload().
67  void LoggingStoppedDontUpload();
68
69  // Notifies that that logging has stopped and that the log should be uploaded.
70  // Decreases log count. May only be called if permission to log has been
71  // granted by calling ApplyForStartLogging() and getting true in return. After
72  // this function has been called, a new permission must be granted. Call
73  // either this function or LoggingStoppedDontUpload().
74  // |upload_done_data.local_log_id| is set and used internally and should be
75  // left empty.
76  void LoggingStoppedDoUpload(
77      scoped_ptr<unsigned char[]> log_buffer,
78      uint32 length,
79      const std::map<std::string, std::string>& meta_data,
80      const WebRtcLogUploadDoneData& upload_done_data);
81
82  // Cancels URL fetcher operation by deleting all URL fetchers. This cancels
83  // any pending uploads and releases SystemURLRequestContextGetter references.
84  // Sets |shutting_down_| which prevent new fetchers to be created.
85  void StartShutdown();
86
87  // For testing purposes. If called, the multipart will not be uploaded, but
88  // written to |post_data_| instead.
89  void OverrideUploadWithBufferForTesting(std::string* post_data) {
90    DCHECK((post_data && !post_data_) || (!post_data && post_data_));
91    post_data_ = post_data;
92  }
93
94 private:
95  FRIEND_TEST_ALL_PREFIXES(WebRtcLogUploaderTest,
96                           AddLocallyStoredLogInfoToUploadListFile);
97  FRIEND_TEST_ALL_PREFIXES(WebRtcLogUploaderTest,
98                           AddUploadedLogInfoToUploadListFile);
99
100  // Sets up a multipart body to be uploaded. The body is produced according
101  // to RFC 2046.
102  void SetupMultipart(std::string* post_data,
103                      const std::vector<uint8>& compressed_log,
104                      const base::FilePath& incoming_rtp_dump,
105                      const base::FilePath& outgoing_rtp_dump,
106                      const std::map<std::string, std::string>& meta_data);
107
108  void CompressLog(std::vector<uint8>* compressed_log,
109                   uint8* input,
110                   uint32 input_size);
111
112  void ResizeForNextOutput(std::vector<uint8>* compressed_log,
113                           z_stream* stream);
114
115  void CreateAndStartURLFetcher(
116      const WebRtcLogUploadDoneData& upload_done_data,
117      scoped_ptr<std::string> post_data);
118
119  void DecreaseLogCount();
120
121  // Must be called on the FILE thread.
122  void WriteCompressedLogToFile(const std::vector<uint8>& compressed_log,
123                                const base::FilePath& log_file_path);
124
125  // Append information (upload time, report ID and local ID) about a log to a
126  // log list file, limited to |kLogListLimitLines| entries. This list is used
127  // for viewing the logs under chrome://webrtc-logs, see WebRtcLogUploadList.
128  // The list has the format
129  // upload_time,report_id,local_id
130  // upload_time,report_id,local_id
131  // etc.
132  // where each line represents a log. "upload_time" is the time when the log
133  // was uploaded in Unix time. "report_id" is the ID reported back by the
134  // server. "local_id" is the ID for the locally stored log. It's the time
135  // stored in Unix time and it's also used as file name.
136  // AddLocallyStoredLogInfoToUploadListFile() will first be called,
137  // "upload_time" and "report_id" is the left empty in the entry written to the
138  // list file. If uploading is successful, AddUploadedLogInfoToUploadListFile()
139  // is called and those empty items are filled out.
140  // Must be called on the FILE thread.
141  void AddLocallyStoredLogInfoToUploadListFile(
142      const base::FilePath& upload_list_path,
143      const std::string& local_log_id);
144  void AddUploadedLogInfoToUploadListFile(
145      const base::FilePath& upload_list_path,
146      const std::string& local_log_id,
147      const std::string& report_id);
148
149  void NotifyUploadDone(int response_code,
150                        const std::string& report_id,
151                        const WebRtcLogUploadDoneData& upload_done_data);
152
153  // This is the UI thread for Chromium. Some other thread for tests.
154  base::ThreadChecker create_thread_checker_;
155
156  // This is the FILE thread for Chromium. Some other thread for tests.
157  base::ThreadChecker file_thread_checker_;
158
159  // Keeps track of number of currently open logs. Must be accessed on the UI
160  // thread.
161  int log_count_;
162
163  // For testing purposes, see OverrideUploadWithBufferForTesting. Only accessed
164  // on the FILE thread.
165  std::string* post_data_;
166
167  typedef std::map<const net::URLFetcher*, WebRtcLogUploadDoneData>
168      UploadDoneDataMap;
169  // Only accessed on the UI thread.
170  UploadDoneDataMap upload_done_data_;
171
172  // When shutting down, don't create new URLFetchers.
173  bool shutting_down_;
174
175  DISALLOW_COPY_AND_ASSIGN(WebRtcLogUploader);
176};
177
178#endif  // CHROME_BROWSER_MEDIA_WEBRTC_LOG_UPLOADER_H_
179