#include "base/bind.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/histogram.h"
+#include "base/numerics/safe_math.h"
#include "base/process/process.h"
+#include "base/strings/stringprintf.h"
+#include "content/browser/media/capture/web_contents_audio_input_stream.h"
+#include "content/browser/media/capture/web_contents_capture_util.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/audio_input_sync_writer.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
-#include "content/browser/renderer_host/media/web_contents_audio_input_stream.h"
-#include "content/browser/renderer_host/media/web_contents_capture_util.h"
#include "media/audio/audio_manager_base.h"
namespace content {
MediaStreamManager* media_stream_manager,
AudioMirroringManager* audio_mirroring_manager,
media::UserInputMonitor* user_input_monitor)
- : audio_manager_(audio_manager),
+ : BrowserMessageFilter(AudioMsgStart),
+ audio_manager_(audio_manager),
media_stream_manager_(media_stream_manager),
audio_mirroring_manager_(audio_mirroring_manager),
user_input_monitor_(user_input_monitor),
make_scoped_refptr(controller)));
}
-void AudioInputRendererHost::OnError(media::AudioInputController* controller) {
+void AudioInputRendererHost::OnError(media::AudioInputController* controller,
+ media::AudioInputController::ErrorCode error_code) {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(
&AudioInputRendererHost::DoHandleError,
this,
- make_scoped_refptr(controller)));
+ make_scoped_refptr(controller),
+ error_code));
}
void AudioInputRendererHost::OnData(media::AudioInputController* controller,
if (!PeerHandle()) {
NOTREACHED() << "Renderer process handle is invalid.";
- DeleteEntryOnError(entry);
+ DeleteEntryOnError(entry, INVALID_PEER_HANDLE);
return;
}
if (!entry->controller->LowLatencyMode()) {
NOTREACHED() << "Only low-latency mode is supported.";
- DeleteEntryOnError(entry);
+ DeleteEntryOnError(entry, INVALID_LATENCY_MODE);
return;
}
&foreign_memory_handle)) {
// If we failed to map and share the shared memory then close the audio
// stream and send an error message.
- DeleteEntryOnError(entry);
+ DeleteEntryOnError(entry, MEMORY_SHARING_FAILED);
return;
}
// the construction of audio input stream.
if (!writer->PrepareForeignSocketHandle(PeerHandle(),
&foreign_socket_handle)) {
- DeleteEntryOnError(entry);
+ DeleteEntryOnError(entry, SYNC_SOCKET_ERROR);
return;
}
}
void AudioInputRendererHost::DoHandleError(
- media::AudioInputController* controller) {
+ media::AudioInputController* controller,
+ media::AudioInputController::ErrorCode error_code) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
MediaStreamManager::SendMessageToNativeLog(
- "The AudioInputController signalled an error.");
+ base::StringPrintf("AudioInputController error: %d", error_code));
AudioEntry* entry = LookupByController(controller);
if (!entry)
return;
audio_log_->OnError(entry->stream_id);
- DeleteEntryOnError(entry);
+ DeleteEntryOnError(entry, AUDIO_INPUT_CONTROLLER_ERROR);
}
bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message,
// media::AudioParameters is validated in the deserializer.
if (LookupById(stream_id) != NULL) {
- SendErrorMessage(stream_id);
+ SendErrorMessage(stream_id, STREAM_ALREADY_EXISTS);
return;
}
const StreamDeviceInfo* info = media_stream_manager_->
audio_input_device_manager()->GetOpenedDeviceInfoById(session_id);
if (!info) {
- SendErrorMessage(stream_id);
+ SendErrorMessage(stream_id, PERMISSION_DENIED);
DLOG(WARNING) << "No permission has been granted to input stream with "
<< "session_id=" << session_id;
return;
// Create the shared memory and share it with the renderer process
// using a new SyncWriter object.
- if (!entry->shared_memory.CreateAndMapAnonymous(
- segment_size * entry->shared_memory_segment_count)) {
+ base::CheckedNumeric<uint32> size = segment_size;
+ size *= entry->shared_memory_segment_count;
+ if (!size.IsValid() ||
+ !entry->shared_memory.CreateAndMapAnonymous(size.ValueOrDie())) {
// If creation of shared memory failed then send an error message.
- SendErrorMessage(stream_id);
+ SendErrorMessage(stream_id, SHARED_MEMORY_CREATE_FAILED);
return;
}
entry->shared_memory_segment_count));
if (!writer->Init()) {
- SendErrorMessage(stream_id);
+ SendErrorMessage(stream_id, SYNC_WRITER_INIT_FAILED);
return;
}
}
if (!entry->controller.get()) {
- SendErrorMessage(stream_id);
+ SendErrorMessage(stream_id, STREAM_CREATE_ERROR);
return;
}
AudioEntry* entry = LookupById(stream_id);
if (!entry) {
- SendErrorMessage(stream_id);
+ SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY);
return;
}
AudioEntry* entry = LookupById(stream_id);
if (!entry) {
- SendErrorMessage(stream_id);
+ SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY);
return;
}
audio_log_->OnSetVolume(stream_id, volume);
}
-void AudioInputRendererHost::SendErrorMessage(int stream_id) {
+void AudioInputRendererHost::SendErrorMessage(
+ int stream_id, ErrorCode error_code) {
MediaStreamManager::SendMessageToNativeLog(
- "An error occurred in AudioInputRendererHost.");
+ base::StringPrintf("AudioInputRendererHost error: %d", error_code));
Send(new AudioInputMsg_NotifyStreamStateChanged(
stream_id, media::AudioInputIPCDelegate::kError));
}
audio_entries_.erase(entry->stream_id);
}
-void AudioInputRendererHost::DeleteEntryOnError(AudioEntry* entry) {
+void AudioInputRendererHost::DeleteEntryOnError(AudioEntry* entry,
+ ErrorCode error_code) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
// Sends the error message first before we close the stream because
// |entry| is destroyed in DeleteEntry().
- SendErrorMessage(entry->stream_id);
+ SendErrorMessage(entry->stream_id, error_code);
CloseAndDeleteStream(entry);
}