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_WEBRTC_LOGGING_CONTROLLER_H_
6 #define CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_LOGGING_CONTROLLER_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <map>
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
16 #include "base/callback.h"
17 #include "base/macros.h"
18 #include "base/memory/ref_counted.h"
19 #include "build/build_config.h"
20 #include "chrome/browser/media/webrtc/rtp_dump_type.h"
21 #include "chrome/browser/media/webrtc/webrtc_log_uploader.h"
22 #include "chrome/browser/media/webrtc/webrtc_text_log_handler.h"
23 #include "chrome/common/media/webrtc_logging.mojom.h"
24 #include "content/public/browser/render_process_host.h"
25 #include "mojo/public/cpp/bindings/remote.h"
26 
27 class WebRtcLogUploader;
28 class WebRtcRtpDumpHandler;
29 
30 namespace content {
31 class BrowserContext;
32 }  // namespace content
33 
34 // WebRtcLoggingController handles operations regarding the WebRTC logging:
35 // - Opens a connection to a WebRtcLoggingAgent that runs in the render process
36 //   and generates log messages.
37 // - Writes basic machine info to the log.
38 // - Informs the handler in the render process when to stop logging.
39 // - Closes the connection to the WebRtcLoggingAgent (and thereby discarding it)
40 //   or triggers uploading of the log.
41 // - Detects when the agent (e.g., because of a tab closure or crash) is going
42 //   away and possibly triggers uploading the log.
43 class WebRtcLoggingController
44     : public base::RefCounted<WebRtcLoggingController>,
45       public chrome::mojom::WebRtcLoggingClient {
46  public:
47   typedef WebRtcLogUploader::GenericDoneCallback GenericDoneCallback;
48   typedef WebRtcLogUploader::UploadDoneCallback UploadDoneCallback;
49   typedef base::OnceCallback<void(const std::string&, const std::string&)>
50       LogsDirectoryCallback;
51   typedef base::OnceCallback<void(const std::string&)>
52       LogsDirectoryErrorCallback;
53 
54   // Argument #1: Indicate success/failure.
55   // Argument #2: If success, the log's ID. Otherwise, empty.
56   // Argument #3: If failure, the error message. Otherwise, empty.
57   typedef base::RepeatingCallback<
58       void(bool, const std::string&, const std::string&)>
59       StartEventLoggingCallback;
60 
61   static void AttachToRenderProcessHost(content::RenderProcessHost* host,
62                                         WebRtcLogUploader* log_uploader);
63   static WebRtcLoggingController* FromRenderProcessHost(
64       content::RenderProcessHost* host);
65 
66   // Sets meta data that will be uploaded along with the log and also written
67   // in the beginning of the log. Must be called on the IO thread before calling
68   // StartLogging.
69   void SetMetaData(std::unique_ptr<WebRtcLogMetaDataMap> meta_data,
70                    GenericDoneCallback callback);
71 
72   // Opens a log and starts logging. Must be called on the IO thread.
73   void StartLogging(GenericDoneCallback callback);
74 
75   // Stops logging. Log will remain open until UploadLog or DiscardLog is
76   // called. Must be called on the IO thread.
77   void StopLogging(GenericDoneCallback callback);
78 
79   // Uploads the text log and the RTP dumps. Discards the local copy. May only
80   // be called after text logging has stopped. Must be called on the IO thread.
81   void UploadLog(UploadDoneCallback callback);
82 
83   // Uploads a log that was previously saved via a call to StoreLog().
84   // Otherwise operates in the same way as UploadLog.
85   void UploadStoredLog(const std::string& log_id, UploadDoneCallback callback);
86 
87   // Discards the log and the RTP dumps. May only be called after logging has
88   // stopped. Must be called on the IO thread.
89   void DiscardLog(GenericDoneCallback callback);
90 
91   // Stores the log locally using a hash of log_id + security origin.
92   void StoreLog(const std::string& log_id, GenericDoneCallback callback);
93 
94   // May be called on any thread. |upload_log_on_render_close_| is used
95   // for decision making and it's OK if it changes before the execution based
96   // on that decision has finished.
set_upload_log_on_render_close(bool should_upload)97   void set_upload_log_on_render_close(bool should_upload) {
98     upload_log_on_render_close_ = should_upload;
99   }
100 
101   // Starts dumping the RTP headers for the specified direction. Must be called
102   // on the UI thread. |type| specifies which direction(s) of RTP packets should
103   // be dumped. |callback| will be called when starting the dump is done.
104   void StartRtpDump(RtpDumpType type, GenericDoneCallback callback);
105 
106   // Stops dumping the RTP headers for the specified direction. Must be called
107   // on the UI thread. |type| specifies which direction(s) of RTP packet dumping
108   // should be stopped. |callback| will be called when stopping the dump is
109   // done.
110   void StopRtpDump(RtpDumpType type, GenericDoneCallback callback);
111 
112   // Called when an RTP packet is sent or received. Must be called on the UI
113   // thread.
114   void OnRtpPacket(std::unique_ptr<uint8_t[]> packet_header,
115                    size_t header_length,
116                    size_t packet_length,
117                    bool incoming);
118 
119   // Start remote-bound event logging for a specific peer connection
120   // (indicated by its session description's ID).
121   // The callback will be posted back, indicating |true| if and only if an
122   // event log was successfully started, in which case the first of the string
123   // arguments will be set to the log-ID. Otherwise, the second of the string
124   // arguments will contain the error message.
125   // This function must be called on the UI thread.
126   void StartEventLogging(const std::string& session_id,
127                          size_t max_log_size_bytes,
128                          int output_period_ms,
129                          size_t web_app_id,
130                          const StartEventLoggingCallback& callback);
131 
132 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
133   // Ensures that the WebRTC Logs directory exists and then grants render
134   // process access to the 'WebRTC Logs' directory, and invokes |callback| with
135   // the ids necessary to create a DirectoryEntry object.
136   void GetLogsDirectory(LogsDirectoryCallback callback,
137                         LogsDirectoryErrorCallback error_callback);
138 #endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
139 
140   // chrome::mojom::WebRtcLoggingClient methods:
141   void OnAddMessages(
142       std::vector<chrome::mojom::WebRtcLoggingMessagePtr> messages) override;
143   void OnStopped() override;
144 
145  private:
146   friend class base::RefCounted<WebRtcLoggingController>;
147 
148   WebRtcLoggingController(int render_process_id,
149                           content::BrowserContext* browser_context,
150                           WebRtcLogUploader* log_uploader);
151   ~WebRtcLoggingController() override;
152 
153   void OnAgentDisconnected();
154 
155   // Called after stopping RTP dumps.
156   void StoreLogContinue(const std::string& log_id,
157                         GenericDoneCallback callback);
158 
159   // Writes a formatted log |message| to the |circular_buffer_|.
160   void LogToCircularBuffer(const std::string& message);
161 
162   void TriggerUpload(UploadDoneCallback callback,
163                      const base::FilePath& log_directory);
164 
165   void StoreLogInDirectory(const std::string& log_id,
166                            std::unique_ptr<WebRtcLogPaths> log_paths,
167                            GenericDoneCallback done_callback,
168                            const base::FilePath& directory);
169 
170   // A helper for TriggerUpload to do the real work.
171   void DoUploadLogAndRtpDumps(const base::FilePath& log_directory,
172                               UploadDoneCallback callback);
173 
174   // Create the RTP dump handler and start dumping. Must be called after making
175   // sure the log directory exists.
176   void CreateRtpDumpHandlerAndStart(RtpDumpType type,
177                                     GenericDoneCallback callback,
178                                     const base::FilePath& dump_dir);
179 
180   // A helper for starting RTP dump assuming the RTP dump handler has been
181   // created.
182   void DoStartRtpDump(RtpDumpType type, GenericDoneCallback callback);
183 
184   bool ReleaseRtpDumps(WebRtcLogPaths* log_paths);
185 
186   void FireGenericDoneCallback(
187       WebRtcLoggingController::GenericDoneCallback callback,
188       bool success,
189       const std::string& error_message);
190 
191 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
192   // Grants the render process access to the 'WebRTC Logs' directory, and
193   // invokes |callback| with the ids necessary to create a DirectoryEntry
194   // object. If the |logs_path| couldn't be created or found, |error_callback|
195   // is run.
196   void GrantLogsDirectoryAccess(LogsDirectoryCallback callback,
197                                 LogsDirectoryErrorCallback error_callback,
198                                 const base::FilePath& logs_path);
199 #endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
200 
201   static base::FilePath GetLogDirectoryAndEnsureExists(
202       const base::FilePath& browser_context_directory_path);
203 
204   SEQUENCE_CHECKER(sequence_checker_);
205 
206   mojo::Receiver<chrome::mojom::WebRtcLoggingClient> receiver_;
207   mojo::Remote<chrome::mojom::WebRtcLoggingAgent> logging_agent_;
208 
209   // The render process ID this object belongs to.
210   const int render_process_id_;
211 
212   // A callback that needs to be run from a blocking worker pool and returns
213   // the browser context directory path associated with our renderer process.
214   base::RepeatingCallback<base::FilePath(void)> log_directory_getter_;
215 
216   // True if we should upload whatever log we have when the renderer closes.
217   bool upload_log_on_render_close_;
218 
219   // The text log handler owns the WebRtcLogBuffer object and keeps track of
220   // the logging state.
221   std::unique_ptr<WebRtcTextLogHandler> text_log_handler_;
222 
223   // The RTP dump handler responsible for creating the RTP header dump files.
224   std::unique_ptr<WebRtcRtpDumpHandler> rtp_dump_handler_;
225 
226   // The callback to call when StopRtpDump is called.
227   content::RenderProcessHost::WebRtcStopRtpDumpCallback stop_rtp_dump_callback_;
228 
229   // A pointer to the log uploader that's shared for all browser contexts.
230   // Ownership lies with the browser process.
231   WebRtcLogUploader* const log_uploader_;
232 
233   // Web app id used for statistics. Created as the hash of the value of a
234   // "client" meta data key, if exists. 0 means undefined, and is the hash of
235   // the empty string.
236   int web_app_id_ = 0;
237 
238   DISALLOW_COPY_AND_ASSIGN(WebRtcLoggingController);
239 };
240 
241 #endif  // CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_LOGGING_CONTROLLER_H_
242