Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(409)

Side by Side Diff: chrome/browser/media/webrtc_internal_log_handler_host.cc

Issue 1650133002: Start and stop RTC event logs from private extension API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Drop MessageFilter, add keys for use in GetUserData() Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "chrome/browser/media/webrtc_internal_log_handler_host.h"
6
7 #include <string>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/cpu.h"
13 #include "base/files/file_util.h"
14 #include "base/logging.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/sys_info.h"
18 #include "base/time/time.h"
19 #include "build/build_config.h"
20 #include "chrome/browser/bad_message.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chromeos/settings/cros_settings.h"
23 #include "chrome/browser/media/webrtc_log_list.h"
24 #include "chrome/browser/media/webrtc_log_uploader.h"
25 #include "chrome/browser/media/webrtc_rtp_dump_handler.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/common/channel_info.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/media/webrtc_logging_messages.h"
30 #include "chromeos/settings/cros_settings_names.h"
31 #include "components/version_info/version_info.h"
32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/content_browser_client.h"
34 #include "content/public/browser/gpu_data_manager.h"
35 #include "content/public/browser/render_process_host.h"
36 #include "gpu/config/gpu_info.h"
37 #include "net/base/address_family.h"
38 #include "net/base/ip_address_number.h"
39 #include "net/base/net_util.h"
40 #include "net/url_request/url_request_context_getter.h"
41
42 #if defined(OS_LINUX)
43 #include "base/linux_util.h"
44 #endif
45
46 #if defined(OS_MACOSX)
47 #include "base/mac/mac_util.h"
48 #endif
49
50 #if defined(OS_CHROMEOS)
51 #include "chromeos/system/statistics_provider.h"
52 #endif
53
54 using content::BrowserThread;
55
56 // Keys used to attach handler to the RenderProcessHost
57 const char WebRtcInternalLogHandlerHost::kWebRtcInternalLogHandlerHostKey[] =
58 "kWebRtcInternalLogHandlerHostKey";
59
60 namespace {
61
62 // Returns a path name to be used as prefix for audio debug recordings files.
63 base::FilePath GetAudioDebugRecordingsPrefixPath(
64 const base::FilePath& directory,
65 uint64_t audio_debug_recordings_id) {
66 static const char kAudioDebugRecordingsFilePrefix[] = "AudioDebugRecordings.";
67 return directory.AppendASCII(kAudioDebugRecordingsFilePrefix +
68 base::Int64ToString(audio_debug_recordings_id));
69 }
70
71 // Returns a path name to be used as prefix for RTC event log files.
72 base::FilePath GetRtcEventLogPrefixPath(const base::FilePath& directory,
73 uint64_t rtc_event_log_id) {
74 static const char kRtcEventLogFilePrefix[] = "RtcEventLog.";
75 return directory.AppendASCII(kRtcEventLogFilePrefix +
76 base::Int64ToString(rtc_event_log_id));
77 }
78
79 } // namespace
80
81 WebRtcInternalLogHandlerHost::WebRtcInternalLogHandlerHost(Profile* profile)
82 : profile_(profile),
83 is_audio_debug_recordings_in_progress_(false),
84 current_audio_debug_recordings_id_(0),
85 is_rtc_event_logging_in_progress_(false),
86 current_rtc_event_log_id_(0) {
87 DCHECK(profile_);
88 }
89
90 WebRtcInternalLogHandlerHost::~WebRtcInternalLogHandlerHost() {
91 // TODO: Can we check that we dont hold any references to any Javascript
92 // callbacks?
93 }
94
95 void WebRtcInternalLogHandlerHost::StartAudioDebugRecordings(
96 content::RenderProcessHost* host,
97 base::TimeDelta delay,
98 const TimeLimitedRecordingCallback& callback,
99 const TimeLimitedRecordingErrorCallback& error_callback) {
100 DCHECK_CURRENTLY_ON(BrowserThread::UI);
101
102 BrowserThread::PostTaskAndReplyWithResult(
103 BrowserThread::FILE, FROM_HERE,
104 base::Bind(&WebRtcInternalLogHandlerHost::GetLogDirectoryAndEnsureExists,
105 this),
106 base::Bind(&WebRtcInternalLogHandlerHost::DoStartAudioDebugRecordings,
107 this, host, delay, callback, error_callback));
108 }
109
110 void WebRtcInternalLogHandlerHost::StopAudioDebugRecordings(
111 content::RenderProcessHost* host,
112 const TimeLimitedRecordingCallback& callback,
113 const TimeLimitedRecordingErrorCallback& error_callback) {
114 DCHECK_CURRENTLY_ON(BrowserThread::UI);
115 BrowserThread::PostTaskAndReplyWithResult(
116 BrowserThread::FILE, FROM_HERE,
117 base::Bind(&WebRtcInternalLogHandlerHost::GetLogDirectoryAndEnsureExists,
118 this),
119 base::Bind(&WebRtcInternalLogHandlerHost::DoStopAudioDebugRecordings,
120 this, host, true /* manual stop */,
121 current_audio_debug_recordings_id_, callback, error_callback));
122 }
123
124 void WebRtcInternalLogHandlerHost::StartRtcEventLogging(
125 content::RenderProcessHost* host,
126 base::TimeDelta delay,
127 const TimeLimitedRecordingCallback& callback,
128 const TimeLimitedRecordingErrorCallback& error_callback) {
129 DCHECK_CURRENTLY_ON(BrowserThread::UI);
130
131 BrowserThread::PostTaskAndReplyWithResult(
132 BrowserThread::FILE, FROM_HERE,
133 base::Bind(&WebRtcInternalLogHandlerHost::GetLogDirectoryAndEnsureExists,
134 this),
135 base::Bind(&WebRtcInternalLogHandlerHost::DoStartRtcEventLogging, this,
136 host, delay, callback, error_callback));
137 }
138
139 void WebRtcInternalLogHandlerHost::StopRtcEventLogging(
140 content::RenderProcessHost* host,
141 const TimeLimitedRecordingCallback& callback,
142 const TimeLimitedRecordingErrorCallback& error_callback) {
143 DCHECK_CURRENTLY_ON(BrowserThread::UI);
144 BrowserThread::PostTaskAndReplyWithResult(
145 BrowserThread::FILE, FROM_HERE,
146 base::Bind(&WebRtcInternalLogHandlerHost::GetLogDirectoryAndEnsureExists,
147 this),
148 base::Bind(&WebRtcInternalLogHandlerHost::DoStopRtcEventLogging, this,
149 host, true /* manual stop */,
150 current_audio_debug_recordings_id_, callback, error_callback));
151 }
152
153 base::FilePath WebRtcInternalLogHandlerHost::GetLogDirectoryAndEnsureExists() {
154 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
155 base::FilePath log_dir_path =
156 WebRtcLogList::GetWebRtcLogDirectoryForProfile(profile_->GetPath());
157 base::File::Error error;
158 if (!base::CreateDirectoryAndGetError(log_dir_path, &error)) {
159 DLOG(ERROR) << "Could not create WebRTC log directory, error: " << error;
160 return base::FilePath();
161 }
162 return log_dir_path;
163 }
164
165 void WebRtcInternalLogHandlerHost::DoStartAudioDebugRecordings(
166 content::RenderProcessHost* host,
167 base::TimeDelta delay,
168 const TimeLimitedRecordingCallback& callback,
169 const TimeLimitedRecordingErrorCallback& error_callback,
170 const base::FilePath& log_directory) {
171 DCHECK_CURRENTLY_ON(BrowserThread::UI);
172
173 if (is_audio_debug_recordings_in_progress_) {
174 error_callback.Run("Audio debug recordings already in progress");
175 return;
176 }
177
178 is_audio_debug_recordings_in_progress_ = true;
179 base::FilePath prefix_path = GetAudioDebugRecordingsPrefixPath(
180 log_directory, ++current_audio_debug_recordings_id_);
181 host->EnableAudioDebugRecordings(prefix_path);
182
183 if (delay.is_zero()) {
184 callback.Run(prefix_path.AsUTF8Unsafe(), false /* not stopped */,
185 false /* not manually stopped */);
186 return;
187 }
188
189 BrowserThread::PostDelayedTask(
190 BrowserThread::UI, FROM_HERE,
191 base::Bind(&WebRtcInternalLogHandlerHost::DoStopAudioDebugRecordings,
192 this, host, false /* no manual stop */,
193 current_audio_debug_recordings_id_, callback, error_callback,
194 prefix_path),
195 delay);
196 }
197
198 void WebRtcInternalLogHandlerHost::DoStopAudioDebugRecordings(
199 content::RenderProcessHost* host,
200 bool is_manual_stop,
201 uint64_t audio_debug_recordings_id,
202 const TimeLimitedRecordingCallback& callback,
203 const TimeLimitedRecordingErrorCallback& error_callback,
204 const base::FilePath& log_directory) {
205 DCHECK_CURRENTLY_ON(BrowserThread::UI);
206 DCHECK_LE(audio_debug_recordings_id, current_audio_debug_recordings_id_);
207
208 base::FilePath prefix_path = GetAudioDebugRecordingsPrefixPath(
209 log_directory, audio_debug_recordings_id);
210 // Prevent an old posted StopAudioDebugRecordings() call to stop a newer dump.
211 // This could happen in a sequence like:
212 // Start(10); //Start dump 1. Post Stop() to run after 10 seconds.
213 // Stop(); // Manually stop dump 1 before 10 seconds;
214 // Start(20); // Start dump 2. Posted Stop() for 1 should not stop dump 2.
215 if (audio_debug_recordings_id < current_audio_debug_recordings_id_) {
216 callback.Run(prefix_path.AsUTF8Unsafe(), false /* not stopped */,
217 is_manual_stop);
218 return;
219 }
220
221 if (!is_audio_debug_recordings_in_progress_) {
222 error_callback.Run("No audio debug recording in progress");
223 return;
224 }
225
226 host->DisableAudioDebugRecordings();
227 is_audio_debug_recordings_in_progress_ = false;
228 callback.Run(prefix_path.AsUTF8Unsafe(), true /* stopped */, is_manual_stop);
229 }
230
231 void WebRtcInternalLogHandlerHost::DoStartRtcEventLogging(
232 content::RenderProcessHost* host,
233 base::TimeDelta delay,
234 const TimeLimitedRecordingCallback& callback,
235 const TimeLimitedRecordingErrorCallback& error_callback,
236 const base::FilePath& log_directory) {
237 DCHECK_CURRENTLY_ON(BrowserThread::UI);
238
239 if (is_rtc_event_logging_in_progress_) {
240 error_callback.Run("RTC event logging already in progress");
241 return;
242 }
243
244 is_rtc_event_logging_in_progress_ = true;
245 base::FilePath prefix_path =
246 GetRtcEventLogPrefixPath(log_directory, ++current_rtc_event_log_id_);
247 host->EnableEventLogRecordings(prefix_path);
248
249 if (delay.is_zero()) {
250 callback.Run(prefix_path.AsUTF8Unsafe(), false /* not stopped */,
251 false /* not manually stopped */);
252 return;
253 }
254
255 BrowserThread::PostDelayedTask(
256 BrowserThread::UI, FROM_HERE,
257 base::Bind(&WebRtcInternalLogHandlerHost::DoStopRtcEventLogging, this,
258 host, false /* no manual stop */, current_rtc_event_log_id_,
259 callback, error_callback, prefix_path),
260 delay);
261 }
262
263 void WebRtcInternalLogHandlerHost::DoStopRtcEventLogging(
264 content::RenderProcessHost* host,
265 bool is_manual_stop,
266 uint64_t rtc_event_log_id,
267 const TimeLimitedRecordingCallback& callback,
268 const TimeLimitedRecordingErrorCallback& error_callback,
269 const base::FilePath& log_directory) {
270 DCHECK_CURRENTLY_ON(BrowserThread::UI);
271 DCHECK_LE(rtc_event_log_id, current_rtc_event_log_id_);
272
273 base::FilePath prefix_path =
274 GetRtcEventLogPrefixPath(log_directory, rtc_event_log_id);
275 // Prevent an old posted DoStopRtcEventLogging() call to stop a newer dump.
276 // This could happen in a sequence like:
277 // Start(10); //Start dump 1. Post Stop() to run after 10 seconds.
278 // Stop(); // Manually stop dump 1 before 10 seconds;
279 // Start(20); // Start dump 2. Posted Stop() for 1 should not stop dump 2.
280 if (rtc_event_log_id < current_rtc_event_log_id_) {
281 callback.Run(prefix_path.AsUTF8Unsafe(), false /* not stopped */,
282 is_manual_stop);
283 return;
284 }
285
286 if (!is_rtc_event_logging_in_progress_) {
287 error_callback.Run("No RTC event logging in progress");
288 return;
289 }
290
291 host->DisableEventLogRecordings();
292 is_rtc_event_logging_in_progress_ = false;
293 callback.Run(prefix_path.AsUTF8Unsafe(), true /* stopped */, is_manual_stop);
294 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698