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

Side by Side Diff: content/browser/renderer_host/media/audio_input_renderer_host.cc

Issue 495983002: Improve logging related to start/stop and failure of audio input streams in Chrome (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: xians@ Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | content/browser/renderer_host/media/audio_input_sync_writer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/media/audio_input_renderer_host.h" 5 #include "content/browser/renderer_host/media/audio_input_renderer_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/shared_memory.h" 8 #include "base/memory/shared_memory.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/numerics/safe_math.h" 10 #include "base/numerics/safe_math.h"
11 #include "base/process/process.h" 11 #include "base/process/process.h"
12 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
13 #include "content/browser/media/capture/web_contents_audio_input_stream.h" 13 #include "content/browser/media/capture/web_contents_audio_input_stream.h"
14 #include "content/browser/media/capture/web_contents_capture_util.h" 14 #include "content/browser/media/capture/web_contents_capture_util.h"
15 #include "content/browser/media/media_internals.h" 15 #include "content/browser/media/media_internals.h"
16 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 16 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
17 #include "content/browser/renderer_host/media/audio_input_sync_writer.h" 17 #include "content/browser/renderer_host/media/audio_input_sync_writer.h"
18 #include "content/browser/renderer_host/media/media_stream_manager.h" 18 #include "content/browser/renderer_host/media/media_stream_manager.h"
19 #include "media/audio/audio_manager_base.h" 19 #include "media/audio/audio_manager_base.h"
20 #include "media/base/audio_bus.h" 20 #include "media/base/audio_bus.h"
21 21
22 namespace {
23
24 void LogMessage(int stream_id, const std::string& msg, bool add_prefix) {
25 std::ostringstream oss;
26 oss << "[stream_id=" << stream_id << "] ";
27 if (add_prefix)
28 oss << "AIRH::";
29 oss << msg;
Henrik Grunell 2014/08/29 13:32:21 I'm not sure how this is supposed to be formatted.
henrika (OOO until Aug 14) 2014/08/29 14:05:14 Good comment. Almost all messages starts with func
30 content::MediaStreamManager::SendMessageToNativeLog(oss.str());
31 DVLOG(1) << oss.str();
32 }
33
34 }
35
22 namespace content { 36 namespace content {
23 37
24 struct AudioInputRendererHost::AudioEntry { 38 struct AudioInputRendererHost::AudioEntry {
25 AudioEntry(); 39 AudioEntry();
26 ~AudioEntry(); 40 ~AudioEntry();
27 41
28 // The AudioInputController that manages the audio input stream. 42 // The AudioInputController that manages the audio input stream.
29 scoped_refptr<media::AudioInputController> controller; 43 scoped_refptr<media::AudioInputController> controller;
30 44
31 // The audio input stream ID in the render view. 45 // The audio input stream ID in the render view.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 this, 140 this,
127 make_scoped_refptr(controller), 141 make_scoped_refptr(controller),
128 message)); 142 message));
129 } 143 }
130 144
131 void AudioInputRendererHost::DoCompleteCreation( 145 void AudioInputRendererHost::DoCompleteCreation(
132 media::AudioInputController* controller) { 146 media::AudioInputController* controller) {
133 DCHECK_CURRENTLY_ON(BrowserThread::IO); 147 DCHECK_CURRENTLY_ON(BrowserThread::IO);
134 148
135 AudioEntry* entry = LookupByController(controller); 149 AudioEntry* entry = LookupByController(controller);
136 if (!entry) 150 if (!entry) {
151 NOTREACHED() << "AudioInputController is invalid.";
137 return; 152 return;
153 }
138 154
139 if (!PeerHandle()) { 155 if (!PeerHandle()) {
140 NOTREACHED() << "Renderer process handle is invalid."; 156 NOTREACHED() << "Renderer process handle is invalid.";
141 DeleteEntryOnError(entry, INVALID_PEER_HANDLE); 157 DeleteEntryOnError(entry, INVALID_PEER_HANDLE);
142 return; 158 return;
143 } 159 }
144 160
145 if (!entry->controller->SharedMemoryAndSyncSocketMode()) { 161 if (!entry->controller->SharedMemoryAndSyncSocketMode()) {
146 NOTREACHED() << "Only shared-memory/sync-socket mode is supported."; 162 NOTREACHED() << "Only shared-memory/sync-socket mode is supported.";
147 DeleteEntryOnError(entry, INVALID_LATENCY_MODE); 163 DeleteEntryOnError(entry, INVALID_LATENCY_MODE);
(...skipping 21 matching lines...) Expand all
169 #endif 185 #endif
170 186
171 // If we failed to prepare the sync socket for the renderer then we fail 187 // If we failed to prepare the sync socket for the renderer then we fail
172 // the construction of audio input stream. 188 // the construction of audio input stream.
173 if (!writer->PrepareForeignSocketHandle(PeerHandle(), 189 if (!writer->PrepareForeignSocketHandle(PeerHandle(),
174 &foreign_socket_handle)) { 190 &foreign_socket_handle)) {
175 DeleteEntryOnError(entry, SYNC_SOCKET_ERROR); 191 DeleteEntryOnError(entry, SYNC_SOCKET_ERROR);
176 return; 192 return;
177 } 193 }
178 194
195 LogMessage(entry->stream_id,
196 "DoCompleteCreation => IPC channel and stream are now open",
197 true);
198
179 Send(new AudioInputMsg_NotifyStreamCreated(entry->stream_id, 199 Send(new AudioInputMsg_NotifyStreamCreated(entry->stream_id,
180 foreign_memory_handle, foreign_socket_handle, 200 foreign_memory_handle, foreign_socket_handle,
181 entry->shared_memory.requested_size(), 201 entry->shared_memory.requested_size(),
182 entry->shared_memory_segment_count)); 202 entry->shared_memory_segment_count));
183 } 203 }
184 204
185 void AudioInputRendererHost::DoSendRecordingMessage( 205 void AudioInputRendererHost::DoSendRecordingMessage(
186 media::AudioInputController* controller) { 206 media::AudioInputController* controller) {
187 DCHECK_CURRENTLY_ON(BrowserThread::IO); 207 DCHECK_CURRENTLY_ON(BrowserThread::IO);
188 // TODO(henrika): See crbug.com/115262 for details on why this method 208 // TODO(henrika): See crbug.com/115262 for details on why this method
189 // should be implemented. 209 // should be implemented.
210 AudioEntry* entry = LookupByController(controller);
211 if (!entry) {
212 NOTREACHED() << "AudioInputController is invalid.";
213 return;
214 }
215 LogMessage(entry->stream_id,
216 "DoSendRecordingMessage => stream is now started",
217 true);
190 } 218 }
191 219
192 void AudioInputRendererHost::DoHandleError( 220 void AudioInputRendererHost::DoHandleError(
193 media::AudioInputController* controller, 221 media::AudioInputController* controller,
194 media::AudioInputController::ErrorCode error_code) { 222 media::AudioInputController::ErrorCode error_code) {
195 DCHECK_CURRENTLY_ON(BrowserThread::IO); 223 DCHECK_CURRENTLY_ON(BrowserThread::IO);
196 // Log all errors even it is ignored later. 224 AudioEntry* entry = LookupByController(controller);
197 MediaStreamManager::SendMessageToNativeLog( 225 if (!entry) {
198 base::StringPrintf("AudioInputController error: %d", error_code)); 226 NOTREACHED() << "AudioInputController is invalid.";
227 return;
228 }
199 229
200 // This is a fix for crbug.com/357501. The error can be triggered when closing 230 // This is a fix for crbug.com/357501. The error can be triggered when closing
201 // the lid on Macs, which causes more problems than it fixes. 231 // the lid on Macs, which causes more problems than it fixes.
202 // Also, in crbug.com/357569, the goal is to remove usage of the error since 232 // Also, in crbug.com/357569, the goal is to remove usage of the error since
203 // it was added to solve a crash on Windows that no longer can be reproduced. 233 // it was added to solve a crash on Windows that no longer can be reproduced.
204 if (error_code == media::AudioInputController::NO_DATA_ERROR) { 234 if (error_code == media::AudioInputController::NO_DATA_ERROR) {
205 DVLOG(1) << "AudioInputRendererHost@" << this << "::DoHandleError: " 235 // TODO(henrika): it might be possible to do something other than just
206 << "NO_DATA_ERROR ignored."; 236 // logging when we detect many NO_DATA_ERROR calls for a stream.
237 LogMessage(entry->stream_id, "AIC => NO_DATA_ERROR", false);
207 return; 238 return;
208 } 239 }
209 240
210 AudioEntry* entry = LookupByController(controller); 241 std::ostringstream oss;
211 if (!entry) 242 oss << "AIC reports error_code=" << error_code;
212 return; 243 LogMessage(entry->stream_id, oss.str(), false);
213 244
214 audio_log_->OnError(entry->stream_id); 245 audio_log_->OnError(entry->stream_id);
215 DeleteEntryOnError(entry, AUDIO_INPUT_CONTROLLER_ERROR); 246 DeleteEntryOnError(entry, AUDIO_INPUT_CONTROLLER_ERROR);
216 } 247 }
217 248
218 void AudioInputRendererHost::DoLog(media::AudioInputController* controller, 249 void AudioInputRendererHost::DoLog(media::AudioInputController* controller,
219 const std::string& message) { 250 const std::string& message) {
220 DCHECK_CURRENTLY_ON(BrowserThread::IO); 251 DCHECK_CURRENTLY_ON(BrowserThread::IO);
221 AudioEntry* entry = LookupByController(controller); 252 AudioEntry* entry = LookupByController(controller);
222 if (!entry) 253 if (!entry) {
254 NOTREACHED() << "AudioInputController is invalid.";
223 return; 255 return;
256 }
224 257
225 // Add stream ID and current audio level reported by AIC to native log. 258 // Add stream ID and current audio level reported by AIC to native log.
226 std::string log_string = 259 LogMessage(entry->stream_id, message, false);
227 base::StringPrintf("[stream_id=%d] ", entry->stream_id);
228 log_string += message;
229 MediaStreamManager::SendMessageToNativeLog(log_string);
230 DVLOG(1) << log_string;
231 } 260 }
232 261
233 bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message) { 262 bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message) {
234 bool handled = true; 263 bool handled = true;
235 IPC_BEGIN_MESSAGE_MAP(AudioInputRendererHost, message) 264 IPC_BEGIN_MESSAGE_MAP(AudioInputRendererHost, message)
236 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CreateStream, OnCreateStream) 265 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CreateStream, OnCreateStream)
237 IPC_MESSAGE_HANDLER(AudioInputHostMsg_RecordStream, OnRecordStream) 266 IPC_MESSAGE_HANDLER(AudioInputHostMsg_RecordStream, OnRecordStream)
238 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CloseStream, OnCloseStream) 267 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CloseStream, OnCloseStream)
239 IPC_MESSAGE_HANDLER(AudioInputHostMsg_SetVolume, OnSetVolume) 268 IPC_MESSAGE_HANDLER(AudioInputHostMsg_SetVolume, OnSetVolume)
240 IPC_MESSAGE_UNHANDLED(handled = false) 269 IPC_MESSAGE_UNHANDLED(handled = false)
241 IPC_END_MESSAGE_MAP() 270 IPC_END_MESSAGE_MAP()
242 271
243 return handled; 272 return handled;
244 } 273 }
245 274
246 void AudioInputRendererHost::OnCreateStream( 275 void AudioInputRendererHost::OnCreateStream(
247 int stream_id, 276 int stream_id,
248 int render_view_id, 277 int render_view_id,
249 int session_id, 278 int session_id,
250 const AudioInputHostMsg_CreateStream_Config& config) { 279 const AudioInputHostMsg_CreateStream_Config& config) {
251 DCHECK_CURRENTLY_ON(BrowserThread::IO); 280 DCHECK_CURRENTLY_ON(BrowserThread::IO);
252 281
253 DVLOG(1) << "AudioInputRendererHost@" << this 282 std::ostringstream oss;
254 << "::OnCreateStream(stream_id=" << stream_id 283 oss << "[stream_id=" << stream_id << "] "
255 << ", render_view_id=" << render_view_id 284 << "AIRH::OnCreateStream(render_view_id=" << render_view_id
256 << ", session_id=" << session_id << ")"; 285 << ", session_id=" << session_id << ")";
257 DCHECK_GT(render_view_id, 0); 286 DCHECK_GT(render_view_id, 0);
258 287
259 // media::AudioParameters is validated in the deserializer. 288 // media::AudioParameters is validated in the deserializer.
260 if (LookupById(stream_id) != NULL) { 289 if (LookupById(stream_id) != NULL) {
261 SendErrorMessage(stream_id, STREAM_ALREADY_EXISTS); 290 SendErrorMessage(stream_id, STREAM_ALREADY_EXISTS);
262 return; 291 return;
263 } 292 }
264 293
265 media::AudioParameters audio_params(config.params); 294 media::AudioParameters audio_params(config.params);
266 if (media_stream_manager_->audio_input_device_manager()-> 295 if (media_stream_manager_->audio_input_device_manager()->
(...skipping 13 matching lines...) Expand all
280 audio_input_device_manager()->GetOpenedDeviceInfoById(session_id); 309 audio_input_device_manager()->GetOpenedDeviceInfoById(session_id);
281 if (!info) { 310 if (!info) {
282 SendErrorMessage(stream_id, PERMISSION_DENIED); 311 SendErrorMessage(stream_id, PERMISSION_DENIED);
283 DLOG(WARNING) << "No permission has been granted to input stream with " 312 DLOG(WARNING) << "No permission has been granted to input stream with "
284 << "session_id=" << session_id; 313 << "session_id=" << session_id;
285 return; 314 return;
286 } 315 }
287 316
288 device_id = info->device.id; 317 device_id = info->device.id;
289 device_name = info->device.name; 318 device_name = info->device.name;
319 oss << ": device_name=" << device_name;
290 } 320 }
291 321
292 // Create a new AudioEntry structure. 322 // Create a new AudioEntry structure.
293 scoped_ptr<AudioEntry> entry(new AudioEntry()); 323 scoped_ptr<AudioEntry> entry(new AudioEntry());
294 324
295 const uint32 segment_size = 325 const uint32 segment_size =
296 (sizeof(media::AudioInputBufferParameters) + 326 (sizeof(media::AudioInputBufferParameters) +
297 media::AudioBus::CalculateMemorySize(audio_params)); 327 media::AudioBus::CalculateMemorySize(audio_params));
298 entry->shared_memory_segment_count = config.shared_memory_count; 328 entry->shared_memory_segment_count = config.shared_memory_count;
299 329
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 user_input_monitor_); 373 user_input_monitor_);
344 } 374 }
345 375
346 if (!entry->controller.get()) { 376 if (!entry->controller.get()) {
347 SendErrorMessage(stream_id, STREAM_CREATE_ERROR); 377 SendErrorMessage(stream_id, STREAM_CREATE_ERROR);
348 return; 378 return;
349 } 379 }
350 380
351 // Set the initial AGC state for the audio input stream. Note that, the AGC 381 // Set the initial AGC state for the audio input stream. Note that, the AGC
352 // is only supported in AUDIO_PCM_LOW_LATENCY mode. 382 // is only supported in AUDIO_PCM_LOW_LATENCY mode.
353 if (config.params.format() == media::AudioParameters::AUDIO_PCM_LOW_LATENCY) 383 if (config.params.format() == media::AudioParameters::AUDIO_PCM_LOW_LATENCY) {
354 entry->controller->SetAutomaticGainControl(config.automatic_gain_control); 384 entry->controller->SetAutomaticGainControl(config.automatic_gain_control);
385 oss << ", AGC=" << config.automatic_gain_control;
386 }
387
388 MediaStreamManager::SendMessageToNativeLog(oss.str());
389 DVLOG(1) << oss.str();
355 390
356 // Since the controller was created successfully, create an entry and add it 391 // Since the controller was created successfully, create an entry and add it
357 // to the map. 392 // to the map.
358 entry->stream_id = stream_id; 393 entry->stream_id = stream_id;
359 audio_entries_.insert(std::make_pair(stream_id, entry.release())); 394 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
360
361 MediaStreamManager::SendMessageToNativeLog(
362 "Audio input stream created successfully. Device name: " + device_name);
363 audio_log_->OnCreated(stream_id, audio_params, device_id); 395 audio_log_->OnCreated(stream_id, audio_params, device_id);
364 } 396 }
365 397
366 void AudioInputRendererHost::OnRecordStream(int stream_id) { 398 void AudioInputRendererHost::OnRecordStream(int stream_id) {
367 DCHECK_CURRENTLY_ON(BrowserThread::IO); 399 DCHECK_CURRENTLY_ON(BrowserThread::IO);
400 LogMessage(stream_id, "OnRecordStream", true);
368 401
369 AudioEntry* entry = LookupById(stream_id); 402 AudioEntry* entry = LookupById(stream_id);
370 if (!entry) { 403 if (!entry) {
371 SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY); 404 SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY);
372 return; 405 return;
373 } 406 }
374 407
375 entry->controller->Record(); 408 entry->controller->Record();
376 audio_log_->OnStarted(stream_id); 409 audio_log_->OnStarted(stream_id);
377 } 410 }
378 411
379 void AudioInputRendererHost::OnCloseStream(int stream_id) { 412 void AudioInputRendererHost::OnCloseStream(int stream_id) {
380 DCHECK_CURRENTLY_ON(BrowserThread::IO); 413 DCHECK_CURRENTLY_ON(BrowserThread::IO);
414 LogMessage(stream_id, "OnCloseStream", true);
381 415
382 AudioEntry* entry = LookupById(stream_id); 416 AudioEntry* entry = LookupById(stream_id);
383 417
384 if (entry) 418 if (entry)
385 CloseAndDeleteStream(entry); 419 CloseAndDeleteStream(entry);
386 } 420 }
387 421
388 void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) { 422 void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) {
389 DCHECK_CURRENTLY_ON(BrowserThread::IO); 423 DCHECK_CURRENTLY_ON(BrowserThread::IO);
390 424
391 AudioEntry* entry = LookupById(stream_id); 425 AudioEntry* entry = LookupById(stream_id);
392 if (!entry) { 426 if (!entry) {
393 SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY); 427 SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY);
394 return; 428 return;
395 } 429 }
396 430
397 entry->controller->SetVolume(volume); 431 entry->controller->SetVolume(volume);
398 audio_log_->OnSetVolume(stream_id, volume); 432 audio_log_->OnSetVolume(stream_id, volume);
399 } 433 }
400 434
401 void AudioInputRendererHost::SendErrorMessage( 435 void AudioInputRendererHost::SendErrorMessage(
402 int stream_id, ErrorCode error_code) { 436 int stream_id, ErrorCode error_code) {
403 MediaStreamManager::SendMessageToNativeLog( 437 std::string err_msg =
404 base::StringPrintf("AudioInputRendererHost error: %d", error_code)); 438 base::StringPrintf("SendErrorMessage(error_code=%d)", error_code);
439 LogMessage(stream_id, err_msg, true);
440
405 Send(new AudioInputMsg_NotifyStreamStateChanged( 441 Send(new AudioInputMsg_NotifyStreamStateChanged(
406 stream_id, media::AudioInputIPCDelegate::kError)); 442 stream_id, media::AudioInputIPCDelegate::kError));
407 } 443 }
408 444
409 void AudioInputRendererHost::DeleteEntries() { 445 void AudioInputRendererHost::DeleteEntries() {
410 DCHECK_CURRENTLY_ON(BrowserThread::IO); 446 DCHECK_CURRENTLY_ON(BrowserThread::IO);
411 447
412 for (AudioEntryMap::iterator i = audio_entries_.begin(); 448 for (AudioEntryMap::iterator i = audio_entries_.begin();
413 i != audio_entries_.end(); ++i) { 449 i != audio_entries_.end(); ++i) {
414 CloseAndDeleteStream(i->second); 450 CloseAndDeleteStream(i->second);
415 } 451 }
416 } 452 }
417 453
418 void AudioInputRendererHost::CloseAndDeleteStream(AudioEntry* entry) { 454 void AudioInputRendererHost::CloseAndDeleteStream(AudioEntry* entry) {
419 DCHECK_CURRENTLY_ON(BrowserThread::IO); 455 DCHECK_CURRENTLY_ON(BrowserThread::IO);
420 456
421 if (!entry->pending_close) { 457 if (!entry->pending_close) {
458 LogMessage(entry->stream_id, "CloseAndDeleteStream", true);
422 entry->controller->Close(base::Bind(&AudioInputRendererHost::DeleteEntry, 459 entry->controller->Close(base::Bind(&AudioInputRendererHost::DeleteEntry,
423 this, entry)); 460 this, entry));
424 entry->pending_close = true; 461 entry->pending_close = true;
425 audio_log_->OnClosed(entry->stream_id); 462 audio_log_->OnClosed(entry->stream_id);
426 } 463 }
427 } 464 }
428 465
429 void AudioInputRendererHost::DeleteEntry(AudioEntry* entry) { 466 void AudioInputRendererHost::DeleteEntry(AudioEntry* entry) {
430 DCHECK_CURRENTLY_ON(BrowserThread::IO); 467 DCHECK_CURRENTLY_ON(BrowserThread::IO);
468 LogMessage(entry->stream_id, "DeleteEntry => stream is now closed", true);
431 469
432 // Delete the entry when this method goes out of scope. 470 // Delete the entry when this method goes out of scope.
433 scoped_ptr<AudioEntry> entry_deleter(entry); 471 scoped_ptr<AudioEntry> entry_deleter(entry);
434 472
435 // Erase the entry from the map. 473 // Erase the entry from the map.
436 audio_entries_.erase(entry->stream_id); 474 audio_entries_.erase(entry->stream_id);
437 } 475 }
438 476
439 void AudioInputRendererHost::DeleteEntryOnError(AudioEntry* entry, 477 void AudioInputRendererHost::DeleteEntryOnError(AudioEntry* entry,
440 ErrorCode error_code) { 478 ErrorCode error_code) {
(...skipping 23 matching lines...) Expand all
464 // TODO(hclam): Implement a faster look up method. 502 // TODO(hclam): Implement a faster look up method.
465 for (AudioEntryMap::iterator i = audio_entries_.begin(); 503 for (AudioEntryMap::iterator i = audio_entries_.begin();
466 i != audio_entries_.end(); ++i) { 504 i != audio_entries_.end(); ++i) {
467 if (controller == i->second->controller.get()) 505 if (controller == i->second->controller.get())
468 return i->second; 506 return i->second;
469 } 507 }
470 return NULL; 508 return NULL;
471 } 509 }
472 510
473 } // namespace content 511 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/renderer_host/media/audio_input_sync_writer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698