| OLD | NEW |
| 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_device_manager.h" | 5 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" |
| 10 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
| 11 #include "build/build_config.h" | 12 #include "build/build_config.h" |
| 12 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 13 #include "content/public/common/media_stream_request.h" | 14 #include "content/public/common/media_stream_request.h" |
| 14 #include "media/audio/audio_input_ipc.h" | 15 #include "media/audio/audio_input_ipc.h" |
| 15 #include "media/audio/audio_manager_base.h" | 16 #include "media/audio/audio_manager_base.h" |
| 16 #include "media/base/audio_parameters.h" | 17 #include "media/base/audio_parameters.h" |
| 17 #include "media/base/channel_layout.h" | 18 #include "media/base/channel_layout.h" |
| 19 #include "media/base/media_switches.h" |
| 18 | 20 |
| 19 #if defined(OS_CHROMEOS) | 21 #if defined(OS_CHROMEOS) |
| 20 #include "chromeos/audio/cras_audio_handler.h" | 22 #include "chromeos/audio/cras_audio_handler.h" |
| 21 #endif | 23 #endif |
| 22 | 24 |
| 23 namespace content { | 25 namespace content { |
| 24 | 26 |
| 25 const int AudioInputDeviceManager::kFakeOpenSessionId = 1; | 27 const int AudioInputDeviceManager::kFakeOpenSessionId = 1; |
| 26 | 28 |
| 27 namespace { | 29 namespace { |
| 28 // Starting id for the first capture session. | 30 // Starting id for the first capture session. |
| 29 const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1; | 31 const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1; |
| 30 } | 32 } |
| 31 | 33 |
| 32 AudioInputDeviceManager::AudioInputDeviceManager( | 34 AudioInputDeviceManager::AudioInputDeviceManager( |
| 33 media::AudioManager* audio_manager) | 35 media::AudioManager* audio_manager) |
| 34 : listener_(NULL), | 36 : listener_(NULL), |
| 35 next_capture_session_id_(kFirstSessionId), | 37 next_capture_session_id_(kFirstSessionId), |
| 36 use_fake_device_(false), | |
| 37 #if defined(OS_CHROMEOS) | 38 #if defined(OS_CHROMEOS) |
| 38 keyboard_mic_streams_count_(0), | 39 keyboard_mic_streams_count_(0), |
| 39 #endif | 40 #endif |
| 40 audio_manager_(audio_manager) { | 41 audio_manager_(audio_manager) { |
| 41 } | 42 } |
| 42 | 43 |
| 43 AudioInputDeviceManager::~AudioInputDeviceManager() { | 44 AudioInputDeviceManager::~AudioInputDeviceManager() { |
| 44 } | 45 } |
| 45 | 46 |
| 46 const StreamDeviceInfo* AudioInputDeviceManager::GetOpenedDeviceInfoById( | 47 const StreamDeviceInfo* AudioInputDeviceManager::GetOpenedDeviceInfoById( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 61 DCHECK(!device_task_runner_.get()); | 62 DCHECK(!device_task_runner_.get()); |
| 62 listener_ = listener; | 63 listener_ = listener; |
| 63 device_task_runner_ = device_task_runner; | 64 device_task_runner_ = device_task_runner; |
| 64 } | 65 } |
| 65 | 66 |
| 66 void AudioInputDeviceManager::Unregister() { | 67 void AudioInputDeviceManager::Unregister() { |
| 67 DCHECK(listener_); | 68 DCHECK(listener_); |
| 68 listener_ = NULL; | 69 listener_ = NULL; |
| 69 } | 70 } |
| 70 | 71 |
| 71 void AudioInputDeviceManager::EnumerateDevices(MediaStreamType stream_type) { | |
| 72 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 73 DCHECK(listener_); | |
| 74 | |
| 75 device_task_runner_->PostTask( | |
| 76 FROM_HERE, | |
| 77 base::Bind(&AudioInputDeviceManager::EnumerateOnDeviceThread, | |
| 78 this, stream_type)); | |
| 79 } | |
| 80 | |
| 81 int AudioInputDeviceManager::Open(const StreamDeviceInfo& device) { | 72 int AudioInputDeviceManager::Open(const StreamDeviceInfo& device) { |
| 82 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 73 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 83 // Generate a new id for this device. | 74 // Generate a new id for this device. |
| 84 int session_id = next_capture_session_id_++; | 75 int session_id = next_capture_session_id_++; |
| 85 device_task_runner_->PostTask( | 76 device_task_runner_->PostTask( |
| 86 FROM_HERE, | 77 FROM_HERE, |
| 87 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread, | 78 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread, |
| 88 this, session_id, device)); | 79 this, session_id, device)); |
| 89 | 80 |
| 90 return session_id; | 81 return session_id; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 101 devices_.erase(device); | 92 devices_.erase(device); |
| 102 | 93 |
| 103 // Post a callback through the listener on IO thread since | 94 // Post a callback through the listener on IO thread since |
| 104 // MediaStreamManager is expecting the callback asynchronously. | 95 // MediaStreamManager is expecting the callback asynchronously. |
| 105 BrowserThread::PostTask(BrowserThread::IO, | 96 BrowserThread::PostTask(BrowserThread::IO, |
| 106 FROM_HERE, | 97 FROM_HERE, |
| 107 base::Bind(&AudioInputDeviceManager::ClosedOnIOThread, | 98 base::Bind(&AudioInputDeviceManager::ClosedOnIOThread, |
| 108 this, stream_type, session_id)); | 99 this, stream_type, session_id)); |
| 109 } | 100 } |
| 110 | 101 |
| 111 void AudioInputDeviceManager::UseFakeDevice() { | |
| 112 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 113 use_fake_device_ = true; | |
| 114 } | |
| 115 | |
| 116 bool AudioInputDeviceManager::ShouldUseFakeDevice() const { | |
| 117 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 118 return use_fake_device_; | |
| 119 } | |
| 120 | |
| 121 #if defined(OS_CHROMEOS) | 102 #if defined(OS_CHROMEOS) |
| 122 void AudioInputDeviceManager::RegisterKeyboardMicStream( | 103 void AudioInputDeviceManager::RegisterKeyboardMicStream( |
| 123 const base::Closure& callback) { | 104 const base::Closure& callback) { |
| 124 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 105 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 125 | 106 |
| 126 ++keyboard_mic_streams_count_; | 107 ++keyboard_mic_streams_count_; |
| 127 if (keyboard_mic_streams_count_ == 1) { | 108 if (keyboard_mic_streams_count_ == 1) { |
| 128 BrowserThread::PostTaskAndReply( | 109 BrowserThread::PostTaskAndReply( |
| 129 BrowserThread::UI, | 110 BrowserThread::UI, |
| 130 FROM_HERE, | 111 FROM_HERE, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 148 BrowserThread::UI, | 129 BrowserThread::UI, |
| 149 FROM_HERE, | 130 FROM_HERE, |
| 150 base::Bind( | 131 base::Bind( |
| 151 &AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread, | 132 &AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread, |
| 152 this, | 133 this, |
| 153 false)); | 134 false)); |
| 154 } | 135 } |
| 155 } | 136 } |
| 156 #endif | 137 #endif |
| 157 | 138 |
| 158 void AudioInputDeviceManager::EnumerateOnDeviceThread( | |
| 159 MediaStreamType stream_type) { | |
| 160 SCOPED_UMA_HISTOGRAM_TIMER( | |
| 161 "Media.AudioInputDeviceManager.EnumerateOnDeviceThreadTime"); | |
| 162 DCHECK(IsOnDeviceThread()); | |
| 163 DCHECK_EQ(MEDIA_DEVICE_AUDIO_CAPTURE, stream_type); | |
| 164 | |
| 165 media::AudioDeviceNames device_names; | |
| 166 if (use_fake_device_) { | |
| 167 // Use the fake devices. | |
| 168 GetFakeDeviceNames(&device_names); | |
| 169 } else { | |
| 170 // Enumerate the devices on the OS. | |
| 171 // AudioManager is guaranteed to outlive MediaStreamManager in | |
| 172 // BrowserMainloop. | |
| 173 audio_manager_->GetAudioInputDeviceNames(&device_names); | |
| 174 } | |
| 175 | |
| 176 std::unique_ptr<StreamDeviceInfoArray> devices(new StreamDeviceInfoArray()); | |
| 177 for (media::AudioDeviceNames::iterator it = device_names.begin(); | |
| 178 it != device_names.end(); ++it) { | |
| 179 // Add device information to device vector. | |
| 180 devices->emplace_back(stream_type, it->device_name, it->unique_id, | |
| 181 audio_manager_->GetGroupIDInput(it->unique_id)); | |
| 182 } | |
| 183 | |
| 184 // Return the device list through the listener by posting a task on | |
| 185 // IO thread since MediaStreamManager handles the callback asynchronously. | |
| 186 BrowserThread::PostTask( | |
| 187 BrowserThread::IO, | |
| 188 FROM_HERE, | |
| 189 base::Bind(&AudioInputDeviceManager::DevicesEnumeratedOnIOThread, | |
| 190 this, stream_type, base::Passed(&devices))); | |
| 191 } | |
| 192 | |
| 193 void AudioInputDeviceManager::OpenOnDeviceThread( | 139 void AudioInputDeviceManager::OpenOnDeviceThread( |
| 194 int session_id, const StreamDeviceInfo& info) { | 140 int session_id, const StreamDeviceInfo& info) { |
| 195 SCOPED_UMA_HISTOGRAM_TIMER( | 141 SCOPED_UMA_HISTOGRAM_TIMER( |
| 196 "Media.AudioInputDeviceManager.OpenOnDeviceThreadTime"); | 142 "Media.AudioInputDeviceManager.OpenOnDeviceThreadTime"); |
| 197 DCHECK(IsOnDeviceThread()); | 143 DCHECK(IsOnDeviceThread()); |
| 198 | 144 |
| 199 StreamDeviceInfo out(info.device.type, info.device.name, info.device.id, | 145 StreamDeviceInfo out(info.device.type, info.device.name, info.device.id, |
| 200 info.device.group_id, 0, 0, 0); | 146 info.device.group_id, 0, 0, 0); |
| 201 out.session_id = session_id; | 147 out.session_id = session_id; |
| 202 | 148 |
| 203 MediaStreamDevice::AudioDeviceParameters& input_params = out.device.input; | 149 MediaStreamDevice::AudioDeviceParameters& input_params = out.device.input; |
| 204 | 150 |
| 205 if (use_fake_device_) { | 151 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 152 switches::kUseFakeDeviceForMediaStream)) { |
| 206 // Don't need to query the hardware information if using fake device. | 153 // Don't need to query the hardware information if using fake device. |
| 207 input_params.sample_rate = 44100; | 154 input_params.sample_rate = 44100; |
| 208 input_params.channel_layout = media::CHANNEL_LAYOUT_STEREO; | 155 input_params.channel_layout = media::CHANNEL_LAYOUT_STEREO; |
| 209 } else { | 156 } else { |
| 210 // Get the preferred sample rate and channel configuration for the | 157 // Get the preferred sample rate and channel configuration for the |
| 211 // audio device. | 158 // audio device. |
| 212 media::AudioParameters params = | 159 media::AudioParameters params = |
| 213 audio_manager_->GetInputStreamParameters(info.device.id); | 160 audio_manager_->GetInputStreamParameters(info.device.id); |
| 214 input_params.sample_rate = params.sample_rate(); | 161 input_params.sample_rate = params.sample_rate(); |
| 215 input_params.channel_layout = params.channel_layout(); | 162 input_params.channel_layout = params.channel_layout(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 233 } | 180 } |
| 234 | 181 |
| 235 // Return the |session_id| through the listener by posting a task on | 182 // Return the |session_id| through the listener by posting a task on |
| 236 // IO thread since MediaStreamManager handles the callback asynchronously. | 183 // IO thread since MediaStreamManager handles the callback asynchronously. |
| 237 BrowserThread::PostTask(BrowserThread::IO, | 184 BrowserThread::PostTask(BrowserThread::IO, |
| 238 FROM_HERE, | 185 FROM_HERE, |
| 239 base::Bind(&AudioInputDeviceManager::OpenedOnIOThread, | 186 base::Bind(&AudioInputDeviceManager::OpenedOnIOThread, |
| 240 this, session_id, out)); | 187 this, session_id, out)); |
| 241 } | 188 } |
| 242 | 189 |
| 243 void AudioInputDeviceManager::DevicesEnumeratedOnIOThread( | |
| 244 MediaStreamType stream_type, | |
| 245 std::unique_ptr<StreamDeviceInfoArray> devices) { | |
| 246 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 247 // Ensure that |devices| gets deleted on exit. | |
| 248 if (listener_) | |
| 249 listener_->DevicesEnumerated(stream_type, *devices); | |
| 250 } | |
| 251 | |
| 252 void AudioInputDeviceManager::OpenedOnIOThread(int session_id, | 190 void AudioInputDeviceManager::OpenedOnIOThread(int session_id, |
| 253 const StreamDeviceInfo& info) { | 191 const StreamDeviceInfo& info) { |
| 254 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 192 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 255 DCHECK_EQ(session_id, info.session_id); | 193 DCHECK_EQ(session_id, info.session_id); |
| 256 DCHECK(GetDevice(session_id) == devices_.end()); | 194 DCHECK(GetDevice(session_id) == devices_.end()); |
| 257 | 195 |
| 258 devices_.push_back(info); | 196 devices_.push_back(info); |
| 259 | 197 |
| 260 if (listener_) | 198 if (listener_) |
| 261 listener_->Opened(info.device.type, session_id); | 199 listener_->Opened(info.device.type, session_id); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 276 AudioInputDeviceManager::GetDevice(int session_id) { | 214 AudioInputDeviceManager::GetDevice(int session_id) { |
| 277 for (StreamDeviceList::iterator i(devices_.begin()); i != devices_.end(); | 215 for (StreamDeviceList::iterator i(devices_.begin()); i != devices_.end(); |
| 278 ++i) { | 216 ++i) { |
| 279 if (i->session_id == session_id) | 217 if (i->session_id == session_id) |
| 280 return i; | 218 return i; |
| 281 } | 219 } |
| 282 | 220 |
| 283 return devices_.end(); | 221 return devices_.end(); |
| 284 } | 222 } |
| 285 | 223 |
| 286 void AudioInputDeviceManager::GetFakeDeviceNames( | |
| 287 media::AudioDeviceNames* device_names) { | |
| 288 static const char kFakeDeviceName1[] = "Fake Audio 1"; | |
| 289 static const char kFakeDeviceId1[] = "fake_audio_1"; | |
| 290 static const char kFakeDeviceName2[] = "Fake Audio 2"; | |
| 291 static const char kFakeDeviceId2[] = "fake_audio_2"; | |
| 292 DCHECK(device_names->empty()); | |
| 293 DCHECK(use_fake_device_); | |
| 294 device_names->push_back(media::AudioDeviceName(kFakeDeviceName1, | |
| 295 kFakeDeviceId1)); | |
| 296 device_names->push_back(media::AudioDeviceName(kFakeDeviceName2, | |
| 297 kFakeDeviceId2)); | |
| 298 } | |
| 299 | |
| 300 #if defined(OS_CHROMEOS) | 224 #if defined(OS_CHROMEOS) |
| 301 void AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread( | 225 void AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread( |
| 302 bool active) { | 226 bool active) { |
| 303 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 227 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 304 chromeos::CrasAudioHandler::Get()->SetKeyboardMicActive(active); | 228 chromeos::CrasAudioHandler::Get()->SetKeyboardMicActive(active); |
| 305 } | 229 } |
| 306 #endif | 230 #endif |
| 307 | 231 |
| 308 | 232 |
| 309 } // namespace content | 233 } // namespace content |
| OLD | NEW |