| 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/command_line.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 const int AudioInputDeviceManager::kFakeOpenSessionId = 1; | 27 const int AudioInputDeviceManager::kFakeOpenSessionId = 1; |
| 28 | 28 |
| 29 namespace { | 29 namespace { |
| 30 // Starting id for the first capture session. | 30 // Starting id for the first capture session. |
| 31 const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1; | 31 const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1; |
| 32 } | 32 } |
| 33 | 33 |
| 34 AudioInputDeviceManager::AudioInputDeviceManager( | 34 AudioInputDeviceManager::AudioInputDeviceManager( |
| 35 media::AudioManager* audio_manager) | 35 media::AudioManager* audio_manager) |
| 36 : listener_(nullptr), | 36 : next_capture_session_id_(kFirstSessionId), |
| 37 next_capture_session_id_(kFirstSessionId), | |
| 38 #if defined(OS_CHROMEOS) | 37 #if defined(OS_CHROMEOS) |
| 39 keyboard_mic_streams_count_(0), | 38 keyboard_mic_streams_count_(0), |
| 40 #endif | 39 #endif |
| 41 audio_manager_(audio_manager), | 40 audio_manager_(audio_manager), |
| 42 device_task_runner_(audio_manager_->GetTaskRunner()) { | 41 device_task_runner_(audio_manager_->GetTaskRunner()) { |
| 43 } | 42 } |
| 44 | 43 |
| 45 AudioInputDeviceManager::~AudioInputDeviceManager() { | 44 AudioInputDeviceManager::~AudioInputDeviceManager() { |
| 46 } | 45 } |
| 47 | 46 |
| 48 const StreamDeviceInfo* AudioInputDeviceManager::GetOpenedDeviceInfoById( | 47 const StreamDeviceInfo* AudioInputDeviceManager::GetOpenedDeviceInfoById( |
| 49 int session_id) { | 48 int session_id) { |
| 50 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 49 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 51 StreamDeviceList::iterator device = GetDevice(session_id); | 50 StreamDeviceList::iterator device = GetDevice(session_id); |
| 52 if (device == devices_.end()) | 51 if (device == devices_.end()) |
| 53 return nullptr; | 52 return nullptr; |
| 54 | 53 |
| 55 return &(*device); | 54 return &(*device); |
| 56 } | 55 } |
| 57 | 56 |
| 58 void AudioInputDeviceManager::RegisterListener( | 57 void AudioInputDeviceManager::RegisterListener( |
| 59 MediaStreamProviderListener* listener) { | 58 MediaStreamProviderListener* listener) { |
| 60 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 59 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 61 DCHECK(!listener_); | 60 DCHECK(listener); |
| 62 DCHECK(device_task_runner_); | 61 DCHECK(device_task_runner_); |
| 63 listener_ = listener; | 62 listeners_.AddObserver(listener); |
| 64 } | 63 } |
| 65 | 64 |
| 66 void AudioInputDeviceManager::UnregisterListener() { | 65 void AudioInputDeviceManager::UnregisterListener( |
| 66 MediaStreamProviderListener* listener) { |
| 67 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 67 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 68 DCHECK(listener_); | 68 DCHECK(listener); |
| 69 listener_ = nullptr; | 69 listeners_.RemoveObserver(listener); |
| 70 } | 70 } |
| 71 | 71 |
| 72 int AudioInputDeviceManager::Open(const StreamDeviceInfo& device) { | 72 int AudioInputDeviceManager::Open(const MediaStreamDevice& device) { |
| 73 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 73 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 74 // Generate a new id for this device. | 74 // Generate a new id for this device. |
| 75 int session_id = next_capture_session_id_++; | 75 int session_id = next_capture_session_id_++; |
| 76 device_task_runner_->PostTask( | 76 device_task_runner_->PostTask( |
| 77 FROM_HERE, | 77 FROM_HERE, |
| 78 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread, | 78 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread, |
| 79 this, session_id, device)); | 79 this, session_id, device)); |
| 80 | 80 |
| 81 return session_id; | 81 return session_id; |
| 82 } | 82 } |
| 83 | 83 |
| 84 void AudioInputDeviceManager::Close(int session_id) { | 84 void AudioInputDeviceManager::Close(int session_id) { |
| 85 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 85 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 86 DCHECK(listener_); | |
| 87 StreamDeviceList::iterator device = GetDevice(session_id); | 86 StreamDeviceList::iterator device = GetDevice(session_id); |
| 88 if (device == devices_.end()) | 87 if (device == devices_.end()) |
| 89 return; | 88 return; |
| 90 const MediaStreamType stream_type = device->device.type; | 89 const MediaStreamType stream_type = device->device.type; |
| 91 if (session_id != kFakeOpenSessionId) | 90 if (session_id != kFakeOpenSessionId) |
| 92 devices_.erase(device); | 91 devices_.erase(device); |
| 93 | 92 |
| 94 // Post a callback through the listener on IO thread since | 93 // Post a callback through the listener on IO thread since |
| 95 // MediaStreamManager is expecting the callback asynchronously. | 94 // MediaStreamManager is expecting the callback asynchronously. |
| 96 BrowserThread::PostTask(BrowserThread::IO, | 95 BrowserThread::PostTask(BrowserThread::IO, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 FROM_HERE, | 129 FROM_HERE, |
| 131 base::Bind( | 130 base::Bind( |
| 132 &AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread, | 131 &AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread, |
| 133 this, | 132 this, |
| 134 false)); | 133 false)); |
| 135 } | 134 } |
| 136 } | 135 } |
| 137 #endif | 136 #endif |
| 138 | 137 |
| 139 void AudioInputDeviceManager::OpenOnDeviceThread( | 138 void AudioInputDeviceManager::OpenOnDeviceThread( |
| 140 int session_id, const StreamDeviceInfo& info) { | 139 int session_id, |
| 140 const MediaStreamDevice& device) { |
| 141 SCOPED_UMA_HISTOGRAM_TIMER( | 141 SCOPED_UMA_HISTOGRAM_TIMER( |
| 142 "Media.AudioInputDeviceManager.OpenOnDeviceThreadTime"); | 142 "Media.AudioInputDeviceManager.OpenOnDeviceThreadTime"); |
| 143 DCHECK(IsOnDeviceThread()); | 143 DCHECK(IsOnDeviceThread()); |
| 144 | 144 |
| 145 StreamDeviceInfo out(info.device.type, info.device.name, info.device.id, 0, 0, | 145 StreamDeviceInfo out(device.type, device.name, device.id, 0, 0, 0); |
| 146 0); | |
| 147 out.session_id = session_id; | 146 out.session_id = session_id; |
| 148 | 147 |
| 149 MediaStreamDevice::AudioDeviceParameters& input_params = out.device.input; | 148 MediaStreamDevice::AudioDeviceParameters& input_params = out.device.input; |
| 150 | 149 |
| 151 // Add preferred output device information if a matching output device | 150 // Add preferred output device information if a matching output device |
| 152 // exists. | 151 // exists. |
| 153 out.device.matched_output_device_id = | 152 out.device.matched_output_device_id = |
| 154 audio_manager_->GetAssociatedOutputDeviceID(info.device.id); | 153 audio_manager_->GetAssociatedOutputDeviceID(device.id); |
| 155 | 154 |
| 156 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 155 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 157 switches::kUseFakeDeviceForMediaStream)) { | 156 switches::kUseFakeDeviceForMediaStream)) { |
| 158 // Don't need to query the hardware information if using fake device. | 157 // Don't need to query the hardware information if using fake device. |
| 159 input_params.sample_rate = 44100; | 158 input_params.sample_rate = 44100; |
| 160 input_params.channel_layout = media::CHANNEL_LAYOUT_STEREO; | 159 input_params.channel_layout = media::CHANNEL_LAYOUT_STEREO; |
| 161 if (!out.device.matched_output_device_id.empty()) { | 160 if (!out.device.matched_output_device_id.empty()) { |
| 162 out.device.matched_output.sample_rate = 44100; | 161 out.device.matched_output.sample_rate = 44100; |
| 163 out.device.matched_output.channel_layout = media::CHANNEL_LAYOUT_STEREO; | 162 out.device.matched_output.channel_layout = media::CHANNEL_LAYOUT_STEREO; |
| 164 } | 163 } |
| 165 } else { | 164 } else { |
| 166 // TODO(tommi): As is, we hit this code path when device.type is | 165 // TODO(tommi): As is, we hit this code path when device.type is |
| 167 // MEDIA_TAB_AUDIO_CAPTURE and the device id is not a device that | 166 // MEDIA_TAB_AUDIO_CAPTURE and the device id is not a device that |
| 168 // the AudioManager can know about. This currently does not fail because | 167 // the AudioManager can know about. This currently does not fail because |
| 169 // the implementation of GetInputStreamParameters returns valid parameters | 168 // the implementation of GetInputStreamParameters returns valid parameters |
| 170 // by default for invalid devices. That behavior is problematic because it | 169 // by default for invalid devices. That behavior is problematic because it |
| 171 // causes other parts of the code to attempt to open truly invalid or | 170 // causes other parts of the code to attempt to open truly invalid or |
| 172 // missing devices and falling back on alternate devices (and likely fail | 171 // missing devices and falling back on alternate devices (and likely fail |
| 173 // twice in a row). Tab audio capture should not pass through here and | 172 // twice in a row). Tab audio capture should not pass through here and |
| 174 // GetInputStreamParameters should return invalid parameters for invalid | 173 // GetInputStreamParameters should return invalid parameters for invalid |
| 175 // devices. | 174 // devices. |
| 176 | 175 |
| 177 // Get the preferred sample rate and channel configuration for the | 176 // Get the preferred sample rate and channel configuration for the |
| 178 // audio device. | 177 // audio device. |
| 179 media::AudioParameters params = | 178 media::AudioParameters params = |
| 180 audio_manager_->GetInputStreamParameters(info.device.id); | 179 audio_manager_->GetInputStreamParameters(device.id); |
| 181 input_params.sample_rate = params.sample_rate(); | 180 input_params.sample_rate = params.sample_rate(); |
| 182 input_params.channel_layout = params.channel_layout(); | 181 input_params.channel_layout = params.channel_layout(); |
| 183 input_params.frames_per_buffer = params.frames_per_buffer(); | 182 input_params.frames_per_buffer = params.frames_per_buffer(); |
| 184 input_params.effects = params.effects(); | 183 input_params.effects = params.effects(); |
| 185 input_params.mic_positions = params.mic_positions(); | 184 input_params.mic_positions = params.mic_positions(); |
| 186 if (!out.device.matched_output_device_id.empty()) { | 185 if (!out.device.matched_output_device_id.empty()) { |
| 187 params = audio_manager_->GetOutputStreamParameters( | 186 params = audio_manager_->GetOutputStreamParameters( |
| 188 out.device.matched_output_device_id); | 187 out.device.matched_output_device_id); |
| 189 MediaStreamDevice::AudioDeviceParameters& matched_output_params = | 188 MediaStreamDevice::AudioDeviceParameters& matched_output_params = |
| 190 out.device.matched_output; | 189 out.device.matched_output; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 203 } | 202 } |
| 204 | 203 |
| 205 void AudioInputDeviceManager::OpenedOnIOThread(int session_id, | 204 void AudioInputDeviceManager::OpenedOnIOThread(int session_id, |
| 206 const StreamDeviceInfo& info) { | 205 const StreamDeviceInfo& info) { |
| 207 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 206 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 208 DCHECK_EQ(session_id, info.session_id); | 207 DCHECK_EQ(session_id, info.session_id); |
| 209 DCHECK(GetDevice(session_id) == devices_.end()); | 208 DCHECK(GetDevice(session_id) == devices_.end()); |
| 210 | 209 |
| 211 devices_.push_back(info); | 210 devices_.push_back(info); |
| 212 | 211 |
| 213 if (listener_) | 212 for (auto& listener : listeners_) |
| 214 listener_->Opened(info.device.type, session_id); | 213 listener.Opened(info.device.type, session_id); |
| 215 } | 214 } |
| 216 | 215 |
| 217 void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type, | 216 void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type, |
| 218 int session_id) { | 217 int session_id) { |
| 219 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 218 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 220 if (listener_) | 219 for (auto& listener : listeners_) |
| 221 listener_->Closed(stream_type, session_id); | 220 listener.Closed(stream_type, session_id); |
| 222 } | 221 } |
| 223 | 222 |
| 224 bool AudioInputDeviceManager::IsOnDeviceThread() const { | 223 bool AudioInputDeviceManager::IsOnDeviceThread() const { |
| 225 return device_task_runner_->BelongsToCurrentThread(); | 224 return device_task_runner_->BelongsToCurrentThread(); |
| 226 } | 225 } |
| 227 | 226 |
| 228 AudioInputDeviceManager::StreamDeviceList::iterator | 227 AudioInputDeviceManager::StreamDeviceList::iterator |
| 229 AudioInputDeviceManager::GetDevice(int session_id) { | 228 AudioInputDeviceManager::GetDevice(int session_id) { |
| 230 for (StreamDeviceList::iterator i(devices_.begin()); i != devices_.end(); | 229 for (StreamDeviceList::iterator i(devices_.begin()); i != devices_.end(); |
| 231 ++i) { | 230 ++i) { |
| 232 if (i->session_id == session_id) | 231 if (i->session_id == session_id) |
| 233 return i; | 232 return i; |
| 234 } | 233 } |
| 235 | 234 |
| 236 return devices_.end(); | 235 return devices_.end(); |
| 237 } | 236 } |
| 238 | 237 |
| 239 #if defined(OS_CHROMEOS) | 238 #if defined(OS_CHROMEOS) |
| 240 void AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread( | 239 void AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread( |
| 241 bool active) { | 240 bool active) { |
| 242 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 241 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 243 chromeos::CrasAudioHandler::Get()->SetKeyboardMicActive(active); | 242 chromeos::CrasAudioHandler::Get()->SetKeyboardMicActive(active); |
| 244 } | 243 } |
| 245 #endif | 244 #endif |
| 246 | 245 |
| 247 | 246 |
| 248 } // namespace content | 247 } // namespace content |
| OLD | NEW |