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

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

Issue 12440027: Do not pass the string device_id via IPC message to create an audio input stream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed Per's comments. Created 7 years, 9 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
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_device_manager.h" 5 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "content/browser/renderer_host/media/audio_input_device_manager_event_h andler.h"
10 #include "content/public/browser/browser_thread.h" 9 #include "content/public/browser/browser_thread.h"
11 #include "content/public/common/media_stream_request.h" 10 #include "content/public/common/media_stream_request.h"
12 #include "media/audio/audio_device_name.h" 11 #include "media/audio/audio_device_name.h"
13 #include "media/audio/audio_input_ipc.h" 12 #include "media/audio/audio_input_ipc.h"
14 #include "media/audio/audio_manager_base.h" 13 #include "media/audio/audio_manager_base.h"
15 #include "media/audio/audio_parameters.h" 14 #include "media/audio/audio_parameters.h"
16 #include "media/base/channel_layout.h" 15 #include "media/base/channel_layout.h"
17 16
18 namespace content { 17 namespace content {
19 18
20 const int AudioInputDeviceManager::kFakeOpenSessionId = 1; 19 const int AudioInputDeviceManager::kFakeOpenSessionId = 1;
21 20
22 namespace { 21 namespace {
23 // Starting id for the first capture session. 22 // Starting id for the first capture session.
24 const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1; 23 const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1;
25 } 24 }
26 25
27 AudioInputDeviceManager::AudioInputDeviceManager( 26 AudioInputDeviceManager::AudioInputDeviceManager(
28 media::AudioManager* audio_manager) 27 media::AudioManager* audio_manager)
29 : listener_(NULL), 28 : listener_(NULL),
30 next_capture_session_id_(kFirstSessionId), 29 next_capture_session_id_(kFirstSessionId),
31 use_fake_device_(false), 30 use_fake_device_(false),
32 audio_manager_(audio_manager) { 31 audio_manager_(audio_manager) {
33 } 32 }
34 33
35 AudioInputDeviceManager::~AudioInputDeviceManager() { 34 AudioInputDeviceManager::~AudioInputDeviceManager() {
36 } 35 }
37 36
37 const StreamDeviceInfo* AudioInputDeviceManager::GetOpenedDeviceInfoById(
38 int session_id) {
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
40 StreamDeviceList::iterator device = GetDevice(session_id);
41 if (device == devices_.end())
42 return NULL;
43
44 return &(*device);
45 }
46
38 void AudioInputDeviceManager::Register( 47 void AudioInputDeviceManager::Register(
39 MediaStreamProviderListener* listener, 48 MediaStreamProviderListener* listener,
40 base::MessageLoopProxy* device_thread_loop) { 49 base::MessageLoopProxy* device_thread_loop) {
41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
42 DCHECK(!listener_); 51 DCHECK(!listener_);
43 DCHECK(!device_loop_); 52 DCHECK(!device_loop_);
44 listener_ = listener; 53 listener_ = listener;
45 device_loop_ = device_thread_loop; 54 device_loop_ = device_thread_loop;
46 } 55 }
47 56
(...skipping 20 matching lines...) Expand all
68 FROM_HERE, 77 FROM_HERE,
69 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread, 78 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread,
70 this, session_id, device)); 79 this, session_id, device));
71 80
72 return session_id; 81 return session_id;
73 } 82 }
74 83
75 void AudioInputDeviceManager::Close(int session_id) { 84 void AudioInputDeviceManager::Close(int session_id) {
76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
77 DCHECK(listener_); 86 DCHECK(listener_);
78 // Check if the device has been stopped, if not, send stop signal. 87 StreamDeviceList::iterator device = GetDevice(session_id);
79 EventHandlerMap::iterator it = event_handlers_.find(session_id); 88 if (device == devices_.end())
80 if (it != event_handlers_.end()) { 89 return;
81 it->second->OnDeviceStopped(session_id); 90 const MediaStreamType stream_type = device->device.type;
82 event_handlers_.erase(it); 91 devices_.erase(device);
83 }
84 92
85 device_loop_->PostTask( 93 // Post a callback through the listener on IO thread since
86 FROM_HERE, 94 // MediaStreamManager is expecting the callback asynchronously.
87 base::Bind(&AudioInputDeviceManager::CloseOnDeviceThread, 95 BrowserThread::PostTask(BrowserThread::IO,
88 this, session_id)); 96 FROM_HERE,
89 } 97 base::Bind(&AudioInputDeviceManager::ClosedOnIOThread,
90 98 this, stream_type, session_id));
91 void AudioInputDeviceManager::Start(
92 int session_id, AudioInputDeviceManagerEventHandler* handler) {
93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
94 DCHECK(handler);
95
96 // Solution for not using MediaStreamManager. This is needed when Start() is
97 // called without using Open(), we post default device for test purpose.
98 // And we do not store the info for the kFakeOpenSessionId but return
99 // the callback immediately.
100 if (session_id == kFakeOpenSessionId) {
101 handler->OnDeviceStarted(session_id,
102 media::AudioManagerBase::kDefaultDeviceId);
103 return;
104 }
105
106 // Look up the device_id of the session so we can notify the renderer that
107 // the device has started. If the session has not been started,
108 // use the empty device_id to indicate that Start() failed.
109 std::string device_id;
110 if (event_handlers_.insert(std::make_pair(session_id, handler)).second) {
111 StreamDeviceMap::const_iterator it = devices_.find(session_id);
112 if (it != devices_.end())
113 device_id = it->second.device.id;
114 }
115
116 // Post a callback through the AudioInputRendererHost to notify the renderer
117 // that the device has started.
118 handler->OnDeviceStarted(session_id, device_id);
119 }
120
121 void AudioInputDeviceManager::Stop(int session_id) {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
123
124 // Erase the event handler referenced by the session_id.
125 event_handlers_.erase(session_id);
126 } 99 }
127 100
128 void AudioInputDeviceManager::UseFakeDevice() { 101 void AudioInputDeviceManager::UseFakeDevice() {
129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
130 use_fake_device_ = true; 103 use_fake_device_ = true;
131 } 104 }
132 105
133 bool AudioInputDeviceManager::ShouldUseFakeDevice() const { 106 bool AudioInputDeviceManager::ShouldUseFakeDevice() const {
134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
135 return use_fake_device_; 108 return use_fake_device_;
(...skipping 13 matching lines...) Expand all
149 break; 122 break;
150 123
151 default: 124 default:
152 NOTREACHED(); 125 NOTREACHED();
153 break; 126 break;
154 } 127 }
155 128
156 scoped_ptr<StreamDeviceInfoArray> devices(new StreamDeviceInfoArray()); 129 scoped_ptr<StreamDeviceInfoArray> devices(new StreamDeviceInfoArray());
157 for (media::AudioDeviceNames::iterator it = device_names.begin(); 130 for (media::AudioDeviceNames::iterator it = device_names.begin();
158 it != device_names.end(); ++it) { 131 it != device_names.end(); ++it) {
159 // Get the preferred sample rate and channel configuration for the
160 // current audio device.
161 media::AudioParameters default_params =
162 audio_manager_->GetInputStreamParameters(it->unique_id);
163
164 // Add device information to device vector. 132 // Add device information to device vector.
165 devices->push_back(StreamDeviceInfo( 133 devices->push_back(StreamDeviceInfo(
166 stream_type, it->device_name, it->unique_id, 134 stream_type, it->device_name, it->unique_id, false));
167 default_params.sample_rate(), default_params.channel_layout(), false));
168 } 135 }
169 136
170 // Return the device list through the listener by posting a task on 137 // Return the device list through the listener by posting a task on
171 // IO thread since MediaStreamManager handles the callback asynchronously. 138 // IO thread since MediaStreamManager handles the callback asynchronously.
172 BrowserThread::PostTask( 139 BrowserThread::PostTask(
173 BrowserThread::IO, 140 BrowserThread::IO,
174 FROM_HERE, 141 FROM_HERE,
175 base::Bind(&AudioInputDeviceManager::DevicesEnumeratedOnIOThread, 142 base::Bind(&AudioInputDeviceManager::DevicesEnumeratedOnIOThread,
176 this, stream_type, base::Passed(&devices))); 143 this, stream_type, base::Passed(&devices)));
177 } 144 }
178 145
179 void AudioInputDeviceManager::OpenOnDeviceThread( 146 void AudioInputDeviceManager::OpenOnDeviceThread(
180 int session_id, const StreamDeviceInfo& device) { 147 int session_id, const StreamDeviceInfo& info) {
181 DCHECK(IsOnDeviceThread()); 148 DCHECK(IsOnDeviceThread());
182 149
183 // Add the session_id and device to the map. 150 // Get the preferred sample rate and channel configuration for the
184 if (!devices_.insert(std::make_pair(session_id, device)).second) { 151 // audio device.
185 NOTREACHED(); 152 media::AudioParameters params =
186 devices_[session_id] = device; 153 audio_manager_->GetInputStreamParameters(info.device.id);
187 } 154
155 StreamDeviceInfo out(info.device.type, info.device.name, info.device.id,
156 params.sample_rate(), params.channel_layout(), false);
157 out.session_id = session_id;
188 158
189 // Return the |session_id| through the listener by posting a task on 159 // Return the |session_id| through the listener by posting a task on
190 // IO thread since MediaStreamManager handles the callback asynchronously. 160 // IO thread since MediaStreamManager handles the callback asynchronously.
191 BrowserThread::PostTask(BrowserThread::IO, 161 BrowserThread::PostTask(BrowserThread::IO,
192 FROM_HERE, 162 FROM_HERE,
193 base::Bind(&AudioInputDeviceManager::OpenedOnIOThread, 163 base::Bind(&AudioInputDeviceManager::OpenedOnIOThread,
194 this, device.device.type, session_id)); 164 this, session_id, out));
195 }
196
197 void AudioInputDeviceManager::CloseOnDeviceThread(int session_id) {
198 DCHECK(IsOnDeviceThread());
199
200 StreamDeviceMap::iterator it = devices_.find(session_id);
201 if (it == devices_.end())
202 return;
203 const MediaStreamType stream_type = it->second.device.type;
204 devices_.erase(it);
205
206 // Post a callback through the listener on IO thread since
207 // MediaStreamManager handles the callback asynchronously.
208 BrowserThread::PostTask(BrowserThread::IO,
209 FROM_HERE,
210 base::Bind(&AudioInputDeviceManager::ClosedOnIOThread,
211 this, stream_type, session_id));
212 } 165 }
213 166
214 void AudioInputDeviceManager::DevicesEnumeratedOnIOThread( 167 void AudioInputDeviceManager::DevicesEnumeratedOnIOThread(
215 MediaStreamType stream_type, 168 MediaStreamType stream_type,
216 scoped_ptr<StreamDeviceInfoArray> devices) { 169 scoped_ptr<StreamDeviceInfoArray> devices) {
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
218 // Ensure that |devices| gets deleted on exit. 171 // Ensure that |devices| gets deleted on exit.
219 if (listener_) 172 if (listener_)
220 listener_->DevicesEnumerated(stream_type, *devices); 173 listener_->DevicesEnumerated(stream_type, *devices);
221 } 174 }
222 175
223 void AudioInputDeviceManager::OpenedOnIOThread(MediaStreamType stream_type, 176 void AudioInputDeviceManager::OpenedOnIOThread(int session_id,
224 int session_id) { 177 const StreamDeviceInfo& info) {
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
179 DCHECK_EQ(session_id, info.session_id);
180 DCHECK(GetDevice(session_id) == devices_.end());
181 devices_.push_back(info);
182
226 if (listener_) 183 if (listener_)
227 listener_->Opened(stream_type, session_id); 184 listener_->Opened(info.device.type, session_id);
228 } 185 }
229 186
230 void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type, 187 void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type,
231 int session_id) { 188 int session_id) {
232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
233 if (listener_) 190 if (listener_)
234 listener_->Closed(stream_type, session_id); 191 listener_->Closed(stream_type, session_id);
235 } 192 }
236 193
237 bool AudioInputDeviceManager::IsOnDeviceThread() const { 194 bool AudioInputDeviceManager::IsOnDeviceThread() const {
238 return device_loop_->BelongsToCurrentThread(); 195 return device_loop_->BelongsToCurrentThread();
239 } 196 }
240 197
198 AudioInputDeviceManager::StreamDeviceList::iterator
199 AudioInputDeviceManager::GetDevice(int session_id) {
200 for (StreamDeviceList::iterator i(devices_.begin()); i != devices_.end();
201 ++i) {
202 if (i->session_id == session_id)
203 return i;
204 }
205
206 return devices_.end();
207 }
208
241 } // namespace content 209 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698