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

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

Issue 10912004: Begin adding support for tab mirroring via the MediaStream audio/video capturing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Simplify: Use only one AudioInputDeviceManager and VideoCaptureManager, like before. Created 8 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
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/media_stream_manager.h" 5 #include "content/browser/renderer_host/media/media_stream_manager.h"
6 6
7 #include <list> 7 #include <list>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 29 matching lines...) Expand all
40 for (size_t i = 0; i < label.size(); ++i) { 40 for (size_t i = 0; i < label.size(); ++i) {
41 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); 41 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1);
42 label[i] = kAlphabet[random_char]; 42 label[i] = kAlphabet[random_char];
43 } 43 }
44 return label; 44 return label;
45 } 45 }
46 46
47 // Helper to verify if a media stream type is part of options or not. 47 // Helper to verify if a media stream type is part of options or not.
48 static bool Requested(const StreamOptions& options, 48 static bool Requested(const StreamOptions& options,
49 MediaStreamType stream_type) { 49 MediaStreamType stream_type) {
50 return (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && 50 return (options.audio_type == stream_type ||
51 options.video) || 51 options.video_type == stream_type);
52 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE &&
53 options.audio);
54 } 52 }
55 53
56 DeviceThread::DeviceThread(const char* name) 54 DeviceThread::DeviceThread(const char* name)
57 : base::Thread(name) { 55 : base::Thread(name) {
58 } 56 }
59 57
60 DeviceThread::~DeviceThread() { 58 DeviceThread::~DeviceThread() {
61 Stop(); 59 Stop();
62 } 60 }
63 61
(...skipping 19 matching lines...) Expand all
83 }; 81 };
84 82
85 enum RequestType { 83 enum RequestType {
86 GENERATE_STREAM = 0, 84 GENERATE_STREAM = 0,
87 ENUMERATE_DEVICES, 85 ENUMERATE_DEVICES,
88 OPEN_DEVICE 86 OPEN_DEVICE
89 }; 87 };
90 88
91 DeviceRequest() 89 DeviceRequest()
92 : requester(NULL), 90 : requester(NULL),
93 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), 91 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED),
94 type(GENERATE_STREAM), 92 type(GENERATE_STREAM),
95 render_process_id(-1), 93 render_process_id(-1),
96 render_view_id(-1) { 94 render_view_id(-1) {
97 options.audio = false;
98 options.video = false;
99 } 95 }
100 96
101 DeviceRequest(MediaStreamRequester* requester, 97 DeviceRequest(MediaStreamRequester* requester,
102 const StreamOptions& request_options, 98 const StreamOptions& request_options,
103 int render_process_id, 99 int render_process_id,
104 int render_view_id, 100 int render_view_id,
105 const GURL& request_security_origin) 101 const GURL& request_security_origin)
106 : requester(requester), 102 : requester(requester),
107 options(request_options), 103 options(request_options),
108 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), 104 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED),
109 type(GENERATE_STREAM), 105 type(GENERATE_STREAM),
110 render_process_id(render_process_id), 106 render_process_id(render_process_id),
111 render_view_id(render_view_id), 107 render_view_id(render_view_id),
112 security_origin(request_security_origin) { 108 security_origin(request_security_origin) {
113 DCHECK(requester); 109 DCHECK(requester);
114 } 110 }
115 111
116 ~DeviceRequest() {} 112 ~DeviceRequest() {}
117 113
118 MediaStreamRequester* requester; 114 MediaStreamRequester* requester;
119 StreamOptions options; 115 StreamOptions options;
120 std::vector<RequestState> state; 116 std::vector<RequestState> state;
121 RequestType type; 117 RequestType type;
122 int render_process_id; 118 int render_process_id;
123 int render_view_id; 119 int render_view_id;
124 GURL security_origin; 120 GURL security_origin;
125 std::string requested_device_id; 121 std::string requested_device_id;
126 StreamDeviceInfoArray audio_devices; 122 StreamDeviceInfoArray devices;
127 StreamDeviceInfoArray video_devices;
128 }; 123 };
129 124
130 MediaStreamManager::EnumerationCache::EnumerationCache() 125 MediaStreamManager::EnumerationCache::EnumerationCache()
131 : valid(false) { 126 : valid(false) {
132 } 127 }
133 128
134 MediaStreamManager::EnumerationCache::~EnumerationCache() { 129 MediaStreamManager::EnumerationCache::~EnumerationCache() {
135 } 130 }
136 131
137 MediaStreamManager::MediaStreamManager( 132 MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager)
138 AudioInputDeviceManager* audio_input_device_manager,
139 VideoCaptureManager* video_capture_manager)
140 : ALLOW_THIS_IN_INITIALIZER_LIST( 133 : ALLOW_THIS_IN_INITIALIZER_LIST(
141 device_settings_(new MediaStreamDeviceSettings(this))), 134 device_settings_(new MediaStreamDeviceSettings(this))),
142 audio_input_device_manager_(audio_input_device_manager), 135 audio_manager_(audio_manager),
143 video_capture_manager_(video_capture_manager),
144 monitoring_started_(false), 136 monitoring_started_(false),
145 io_loop_(NULL) { 137 io_loop_(NULL) {
138 DCHECK(audio_manager_);
146 memset(active_enumeration_ref_count_, 0, 139 memset(active_enumeration_ref_count_, 0,
147 sizeof(active_enumeration_ref_count_)); 140 sizeof(active_enumeration_ref_count_));
148 } 141 }
149 142
150 MediaStreamManager::~MediaStreamManager() { 143 MediaStreamManager::~MediaStreamManager() {
151 DCHECK(requests_.empty()); 144 DCHECK(requests_.empty());
152 DCHECK(!device_thread_.get()); 145 DCHECK(!device_thread_.get());
153 DCHECK(!io_loop_); 146 DCHECK(!io_loop_);
154 } 147 }
155 148
156 VideoCaptureManager* MediaStreamManager::video_capture_manager() { 149 VideoCaptureManager* MediaStreamManager::video_capture_manager() {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
151 EnsureDeviceManagersStarted();
158 DCHECK(video_capture_manager_); 152 DCHECK(video_capture_manager_);
159 EnsureDeviceThreadAndListener();
160 return video_capture_manager_; 153 return video_capture_manager_;
161 } 154 }
162 155
163 AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() { 156 AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() {
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
158 EnsureDeviceManagersStarted();
165 DCHECK(audio_input_device_manager_); 159 DCHECK(audio_input_device_manager_);
166 EnsureDeviceThreadAndListener();
167 return audio_input_device_manager_; 160 return audio_input_device_manager_;
168 } 161 }
169 162
170 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, 163 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester,
171 int render_process_id, 164 int render_process_id,
172 int render_view_id, 165 int render_view_id,
173 const StreamOptions& options, 166 const StreamOptions& options,
174 const GURL& security_origin, 167 const GURL& security_origin,
175 std::string* label) { 168 std::string* label) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
177 170
178 // Create a new request based on options. 171 // Create a new request based on options.
179 DeviceRequest new_request(requester, options, 172 DeviceRequest new_request(requester, options,
180 render_process_id, 173 render_process_id,
181 render_view_id, 174 render_view_id,
182 security_origin); 175 security_origin);
183 StartEnumeration(&new_request, label); 176 StartEnumeration(&new_request, label);
184 177
185 // Get user confirmation to use capture devices. 178 // Get user confirmation to use capture devices.
186 device_settings_->RequestCaptureDeviceUsage(*label, 179 device_settings_->RequestCaptureDeviceUsage(*label,
187 render_process_id, 180 render_process_id,
188 render_view_id, 181 render_view_id,
189 options, 182 options,
190 security_origin); 183 security_origin);
191 } 184 }
192 185
186 void MediaStreamManager::GenerateStreamForDevice(
187 MediaStreamRequester* requester, int render_process_id, int render_view_id,
188 const StreamOptions& options, const std::string& device_id,
189 const GURL& security_origin, std::string* label) {
190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
191
192 // Create a new request based on options.
193 AddRequest(DeviceRequest(requester, options,
194 render_process_id, render_view_id,
195 security_origin),
196 label);
197 DeviceRequest& request = requests_[*label];
198
199 // Get user confirmation to use the capture device.
200 device_settings_->RequestCaptureDeviceUsage(*label,
201 render_process_id,
202 render_view_id,
203 options,
204 security_origin);
205 // TODO(miu): We should ask the device manager whether a device with id
206 // |device_id| actually exists. Note that no such MediaStreamProvider API for
207 // this currently exists. Also, we don't have a user-friendly device name for
208 // the infobar UI.
209 if (content::IsAudioMediaType(options.audio_type)) {
210 request.state[options.audio_type] = DeviceRequest::STATE_PENDING_APPROVAL;
211 device_settings_->AvailableDevices(
212 *label, options.audio_type, StreamDeviceInfoArray(
213 1, StreamDeviceInfo(options.audio_type, device_id, device_id,
214 false)));
215 }
216 if (content::IsVideoMediaType(options.video_type)) {
217 request.state[options.video_type] = DeviceRequest::STATE_PENDING_APPROVAL;
218 device_settings_->AvailableDevices(
219 *label, options.video_type, StreamDeviceInfoArray(
220 1, StreamDeviceInfo(options.video_type, device_id, device_id,
221 false)));
222 }
223 }
224
193 void MediaStreamManager::CancelGenerateStream(const std::string& label) { 225 void MediaStreamManager::CancelGenerateStream(const std::string& label) {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
195 227
196 DeviceRequests::iterator it = requests_.find(label); 228 DeviceRequests::iterator it = requests_.find(label);
197 if (it != requests_.end()) { 229 if (it != requests_.end()) {
198 // The request isn't complete. 230 // The request isn't complete.
199 if (!RequestDone(it->second)) { 231 if (!RequestDone(it->second)) {
200 DeviceRequest* request = &(it->second); 232 DeviceRequest& request = it->second;
201 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == 233 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
202 DeviceRequest::STATE_OPENING) { 234 ++i) {
203 for (StreamDeviceInfoArray::iterator it = 235 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
204 request->audio_devices.begin(); it != request->audio_devices.end(); 236 if (request.state[stream_type] != DeviceRequest::STATE_OPENING) {
205 ++it) { 237 continue;
206 audio_input_device_manager()->Close(it->session_id);
207 } 238 }
208 } 239 for (StreamDeviceInfoArray::const_iterator device_it =
209 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == 240 request.devices.begin();
210 DeviceRequest::STATE_OPENING) { 241 device_it != request.devices.end(); ++device_it) {
211 for (StreamDeviceInfoArray::iterator it = 242 if (device_it->stream_type == stream_type) {
212 request->video_devices.begin(); it != request->video_devices.end(); 243 GetDeviceManager(stream_type)->Close(device_it->session_id);
213 ++it) { 244 }
214 video_capture_manager()->Close(it->session_id);
215 } 245 }
216 } 246 }
217 requests_.erase(it); 247 requests_.erase(it);
218 } else { 248 } else {
219 StopGeneratedStream(label); 249 StopGeneratedStream(label);
220 } 250 }
221 device_settings_->RemovePendingCaptureRequest(label); 251 device_settings_->RemovePendingCaptureRequest(label);
222 } 252 }
223 } 253 }
224 254
225 void MediaStreamManager::StopGeneratedStream(const std::string& label) { 255 void MediaStreamManager::StopGeneratedStream(const std::string& label) {
226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
227 // Find the request and close all open devices for the request. 257 // Find the request and close all open devices for the request.
228 DeviceRequests::iterator it = requests_.find(label); 258 DeviceRequests::iterator it = requests_.find(label);
229 if (it != requests_.end()) { 259 if (it != requests_.end()) {
230 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) { 260 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) {
231 StopEnumerateDevices(label); 261 StopEnumerateDevices(label);
232 return; 262 return;
233 } 263 }
234 for (StreamDeviceInfoArray::iterator audio_it = 264 for (StreamDeviceInfoArray::const_iterator device_it =
235 it->second.audio_devices.begin(); 265 it->second.devices.begin();
236 audio_it != it->second.audio_devices.end(); ++audio_it) { 266 device_it != it->second.devices.end(); ++device_it) {
237 audio_input_device_manager()->Close(audio_it->session_id); 267 GetDeviceManager(device_it->stream_type)->Close(device_it->session_id);
238 }
239 for (StreamDeviceInfoArray::iterator video_it =
240 it->second.video_devices.begin();
241 video_it != it->second.video_devices.end(); ++video_it) {
242 video_capture_manager()->Close(video_it->session_id);
243 } 268 }
244 if (it->second.type == DeviceRequest::GENERATE_STREAM && 269 if (it->second.type == DeviceRequest::GENERATE_STREAM &&
245 RequestDone(it->second)) { 270 RequestDone(it->second)) {
246 NotifyObserverDevicesClosed(&(it->second)); 271 NotifyObserverDevicesClosed(&(it->second));
247 } 272 }
248 requests_.erase(it); 273 requests_.erase(it);
249 } 274 }
250 } 275 }
251 276
252 void MediaStreamManager::EnumerateDevices( 277 void MediaStreamManager::EnumerateDevices(
253 MediaStreamRequester* requester, 278 MediaStreamRequester* requester,
254 int render_process_id, 279 int render_process_id,
255 int render_view_id, 280 int render_view_id,
256 MediaStreamType type, 281 MediaStreamType type,
257 const GURL& security_origin, 282 const GURL& security_origin,
258 std::string* label) { 283 std::string* label) {
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 284 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
260 DCHECK(type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || 285 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
261 type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); 286 type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
262 287
263 // Create a new request. 288 // Create a new request.
264 StreamOptions options; 289 StreamOptions options;
265 EnumerationCache* cache = NULL; 290 EnumerationCache* cache = NULL;
266 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 291 if (type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
267 options.audio = true; 292 options.audio_type = type;
268 cache = &audio_enumeration_cache_; 293 cache = &audio_enumeration_cache_;
294 } else if (type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
295 options.video_type = type;
296 cache = &video_enumeration_cache_;
269 } else { 297 } else {
270 options.video = true; 298 NOTREACHED();
271 cache = &video_enumeration_cache_; 299 return;
272 } 300 }
273 301
274 DeviceRequest new_request(requester, options, 302 DeviceRequest new_request(requester, options,
275 render_process_id, 303 render_process_id,
276 render_view_id, 304 render_view_id,
277 security_origin); 305 security_origin);
278 new_request.type = DeviceRequest::ENUMERATE_DEVICES; 306 new_request.type = DeviceRequest::ENUMERATE_DEVICES;
279 307
280 if (cache->valid) { 308 if (cache->valid) {
281 // Cached device list of this type exists. Just send it out. 309 // Cached device list of this type exists. Just send it out.
282 new_request.state[type] = DeviceRequest::STATE_REQUESTED; 310 new_request.state[type] = DeviceRequest::STATE_REQUESTED;
283 AddRequest(&new_request, label); 311 AddRequest(new_request, label);
284 // Need to post a task since the requester won't have label till 312 // Need to post a task since the requester won't have label till
285 // this function returns. 313 // this function returns.
286 BrowserThread::PostTask(BrowserThread::IO, 314 BrowserThread::PostTask(BrowserThread::IO,
287 FROM_HERE, 315 FROM_HERE,
288 base::Bind(&MediaStreamManager::SendCachedDeviceList, 316 base::Bind(&MediaStreamManager::SendCachedDeviceList,
289 base::Unretained(this), cache, *label)); 317 base::Unretained(this), cache, *label));
290 } else { 318 } else {
291 StartEnumeration(&new_request, label); 319 StartEnumeration(&new_request, label);
292 StartMonitoring(); 320 StartMonitoring();
293 } 321 }
(...skipping 14 matching lines...) Expand all
308 336
309 void MediaStreamManager::OpenDevice( 337 void MediaStreamManager::OpenDevice(
310 MediaStreamRequester* requester, 338 MediaStreamRequester* requester,
311 int render_process_id, 339 int render_process_id,
312 int render_view_id, 340 int render_view_id,
313 const std::string& device_id, 341 const std::string& device_id,
314 MediaStreamType type, 342 MediaStreamType type,
315 const GURL& security_origin, 343 const GURL& security_origin,
316 std::string* label) { 344 std::string* label) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
346 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
347 type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
318 348
319 // Create a new request. 349 // Create a new request.
320 StreamOptions options; 350 StreamOptions options;
321 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 351 if (content::IsAudioMediaType(type)) {
322 options.audio = true; 352 options.audio_type = type;
323 else 353 } else if (content::IsVideoMediaType(type)) {
324 options.video = true; 354 options.video_type = type;
355 } else {
356 NOTREACHED();
357 return;
358 }
325 359
326 DeviceRequest new_request(requester, options, 360 DeviceRequest new_request(requester, options,
327 render_process_id, 361 render_process_id,
328 render_view_id, 362 render_view_id,
329 security_origin); 363 security_origin);
330 new_request.type = DeviceRequest::OPEN_DEVICE; 364 new_request.type = DeviceRequest::OPEN_DEVICE;
331 new_request.requested_device_id = device_id; 365 new_request.requested_device_id = device_id;
332 366
333 StartEnumeration(&new_request, label); 367 StartEnumeration(&new_request, label);
334 } 368 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { 400 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) {
367 DCHECK_EQ(MessageLoop::current(), io_loop_); 401 DCHECK_EQ(MessageLoop::current(), io_loop_);
368 cache->valid = false; 402 cache->valid = false;
369 } 403 }
370 404
371 void MediaStreamManager::StartEnumeration( 405 void MediaStreamManager::StartEnumeration(
372 DeviceRequest* new_request, 406 DeviceRequest* new_request,
373 std::string* label) { 407 std::string* label) {
374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
375 409
376 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 410 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
377 if (Requested(new_request->options, stream_type)) { 411 ++i) {
378 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; 412 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
379 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 413 if (Requested(new_request->options, stream_type)) {
380 if (!active_enumeration_ref_count_[stream_type]) { 414 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED;
381 ++active_enumeration_ref_count_[stream_type]; 415 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
382 GetDeviceManager(stream_type)->EnumerateDevices(); 416 if (active_enumeration_ref_count_[stream_type] == 0) {
383 } 417 ++active_enumeration_ref_count_[stream_type];
384 } 418 GetDeviceManager(stream_type)->EnumerateDevices();
385 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 419 }
386 if (Requested(new_request->options, stream_type)) {
387 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED;
388 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
389 if (!active_enumeration_ref_count_[stream_type]) {
390 ++active_enumeration_ref_count_[stream_type];
391 GetDeviceManager(stream_type)->EnumerateDevices();
392 } 420 }
393 } 421 }
394 422
395 AddRequest(new_request, label); 423 AddRequest(*new_request, label);
396 } 424 }
397 425
398 void MediaStreamManager::AddRequest( 426 void MediaStreamManager::AddRequest(
399 DeviceRequest* new_request, 427 const DeviceRequest& new_request,
400 std::string* label) { 428 std::string* label) {
401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 429 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
402 430
403 // Create a label for this request and verify it is unique. 431 // Create a label for this request and verify it is unique.
404 std::string request_label; 432 std::string request_label;
405 do { 433 do {
406 request_label = RandomLabel(); 434 request_label = RandomLabel();
407 } while (requests_.find(request_label) != requests_.end()); 435 } while (requests_.find(request_label) != requests_.end());
408 436
409 requests_.insert(std::make_pair(request_label, *new_request)); 437 requests_.insert(std::make_pair(request_label, new_request));
410 438
411 (*label) = request_label; 439 (*label) = request_label;
412 } 440 }
413 441
414 void MediaStreamManager::EnsureDeviceThreadAndListener() { 442 void MediaStreamManager::EnsureDeviceManagersStarted() {
415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
416 if (device_thread_.get()) 444 if (device_thread_.get())
417 return; 445 return;
418 446
419 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); 447 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread"));
420 CHECK(device_thread_->Start()); 448 CHECK(device_thread_->Start());
421 449
450 audio_input_device_manager_ =
451 new media_stream::AudioInputDeviceManager(audio_manager_);
422 audio_input_device_manager_->Register(this, 452 audio_input_device_manager_->Register(this,
423 device_thread_->message_loop_proxy()); 453 device_thread_->message_loop_proxy());
424 video_capture_manager_->Register(this, device_thread_->message_loop_proxy()); 454
455 video_capture_manager_ = new media_stream::VideoCaptureManager();
456 video_capture_manager_->Register(this,
457 device_thread_->message_loop_proxy());
425 458
426 // We want to be notified of IO message loop destruction to delete the thread 459 // We want to be notified of IO message loop destruction to delete the thread
427 // and the device managers. 460 // and the device managers.
428 io_loop_ = MessageLoop::current(); 461 io_loop_ = MessageLoop::current();
429 io_loop_->AddDestructionObserver(this); 462 io_loop_->AddDestructionObserver(this);
430 } 463 }
431 464
432 void MediaStreamManager::Opened(MediaStreamType stream_type, 465 void MediaStreamManager::Opened(MediaStreamType stream_type,
433 int capture_session_id) { 466 int capture_session_id) {
434 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
435 468
436 // Find the request containing this device and mark it as used. 469 // Find the request containing this device and mark it as used.
437 DeviceRequest* request = NULL; 470 DeviceRequest* request = NULL;
438 StreamDeviceInfoArray* devices = NULL; 471 StreamDeviceInfoArray* devices = NULL;
439 std::string label; 472 std::string label;
440 for (DeviceRequests::iterator request_it = requests_.begin(); 473 for (DeviceRequests::iterator request_it = requests_.begin();
441 request_it != requests_.end() && request == NULL; ++request_it) { 474 request_it != requests_.end() && request == NULL; ++request_it) {
442 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 475 devices = &(request_it->second.devices);
443 devices = &(request_it->second.audio_devices);
444 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
445 devices = &(request_it->second.video_devices);
446 } else {
447 NOTREACHED();
448 }
449
450 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 476 for (StreamDeviceInfoArray::iterator device_it = devices->begin();
451 device_it != devices->end(); ++device_it) { 477 device_it != devices->end(); ++device_it) {
452 if (device_it->session_id == capture_session_id) { 478 if (device_it->stream_type == stream_type &&
479 device_it->session_id == capture_session_id) {
453 // We've found the request. 480 // We've found the request.
454 device_it->in_use = true; 481 device_it->in_use = true;
455 label = request_it->first; 482 label = request_it->first;
456 request = &(request_it->second); 483 request = &(request_it->second);
457 break; 484 break;
458 } 485 }
459 } 486 }
460 } 487 }
461 if (request == NULL) { 488 if (request == NULL) {
462 // The request doesn't exist. 489 // The request doesn't exist.
463 return; 490 return;
464 } 491 }
465 492
466 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); 493 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED);
467 494
468 // Check if all devices for this stream type are opened. Update the state if 495 // Check if all devices for this stream type are opened. Update the state if
469 // they are. 496 // they are.
470 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 497 for (StreamDeviceInfoArray::iterator device_it = devices->begin();
471 device_it != devices->end(); ++device_it) { 498 device_it != devices->end(); ++device_it) {
499 if (device_it->stream_type != stream_type) {
500 continue;
501 }
472 if (device_it->in_use == false) { 502 if (device_it->in_use == false) {
473 // Wait for more devices to be opened before we're done. 503 // Wait for more devices to be opened before we're done.
474 return; 504 return;
475 } 505 }
476 } 506 }
477 request->state[stream_type] = DeviceRequest::STATE_DONE; 507 request->state[stream_type] = DeviceRequest::STATE_DONE;
478 508
479 if (!RequestDone(*request)) { 509 if (!RequestDone(*request)) {
480 // This stream_type is done, but not the other type. 510 // This stream_type is done, but not the other type.
481 return; 511 return;
482 } 512 }
483 513
484 switch (request->type) { 514 switch (request->type) {
485 case DeviceRequest::OPEN_DEVICE: 515 case DeviceRequest::OPEN_DEVICE:
486 request->requester->DeviceOpened(label, (*devices)[0]); 516 request->requester->DeviceOpened(label, devices->front());
487 break; 517 break;
488 case DeviceRequest::GENERATE_STREAM: 518 case DeviceRequest::GENERATE_STREAM: {
489 request->requester->StreamGenerated(label, request->audio_devices, 519 // Partition the array of devices into audio vs video.
490 request->video_devices); 520 StreamDeviceInfoArray audio_devices, video_devices;
521 for (StreamDeviceInfoArray::const_iterator device_it = devices->begin();
522 device_it != devices->end(); ++device_it) {
523 if (content::IsAudioMediaType(device_it->stream_type)) {
524 audio_devices.push_back(*device_it);
525 } else if (content::IsVideoMediaType(device_it->stream_type)) {
526 video_devices.push_back(*device_it);
527 } else {
528 NOTREACHED();
529 }
530 }
531
532 request->requester->StreamGenerated(label, audio_devices, video_devices);
491 NotifyObserverDevicesOpened(request); 533 NotifyObserverDevicesOpened(request);
492 break; 534 break;
535 }
493 default: 536 default:
494 NOTREACHED(); 537 NOTREACHED();
538 break;
495 } 539 }
496 } 540 }
497 541
498 void MediaStreamManager::Closed(MediaStreamType stream_type, 542 void MediaStreamManager::Closed(MediaStreamType stream_type,
499 int capture_session_id) { 543 int capture_session_id) {
500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
501 } 545 }
502 546
503 void MediaStreamManager::DevicesEnumerated( 547 void MediaStreamManager::DevicesEnumerated(
504 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { 548 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) {
505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 549 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
506 550
507 // Only cache device list when there is EnumerateDevices request, since 551 // Only cache the device list when there is an EnumerateDevices request, since
508 // other requests don't turn on device monitoring. 552 // other requests don't turn on device monitoring.
509 bool need_update_clients = false; 553 bool need_update_clients = false;
510 EnumerationCache* cache = 554 EnumerationCache* cache =
511 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ? 555 (stream_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ?
512 &audio_enumeration_cache_ : &video_enumeration_cache_); 556 &audio_enumeration_cache_ : &video_enumeration_cache_);
513 if (HasEnumerationRequest(stream_type) && 557 if (HasEnumerationRequest(stream_type) &&
514 (!cache->valid || 558 (!cache->valid ||
515 devices.size() != cache->devices.size() || 559 devices.size() != cache->devices.size() ||
516 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), 560 !std::equal(devices.begin(), devices.end(), cache->devices.begin(),
517 media_stream::StreamDeviceInfo::IsEqual))) { 561 media_stream::StreamDeviceInfo::IsEqual))) {
518 cache->valid = true; 562 cache->valid = true;
519 cache->devices = devices; 563 cache->devices = devices;
520 need_update_clients = true; 564 need_update_clients = true;
521 } 565 }
(...skipping 14 matching lines...) Expand all
536 } 580 }
537 for (std::list<std::string>::iterator it = label_list.begin(); 581 for (std::list<std::string>::iterator it = label_list.begin();
538 it != label_list.end(); ++it) { 582 it != label_list.end(); ++it) {
539 DeviceRequest& request = requests_[*it]; 583 DeviceRequest& request = requests_[*it];
540 switch (request.type) { 584 switch (request.type) {
541 case DeviceRequest::ENUMERATE_DEVICES: 585 case DeviceRequest::ENUMERATE_DEVICES:
542 if (need_update_clients) 586 if (need_update_clients)
543 request.requester->DevicesEnumerated(*it, devices); 587 request.requester->DevicesEnumerated(*it, devices);
544 break; 588 break;
545 case DeviceRequest::OPEN_DEVICE: 589 case DeviceRequest::OPEN_DEVICE:
590 DCHECK(!request.requested_device_id.empty());
546 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); 591 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin();
547 device_it != devices.end(); device_it++) { 592 device_it != devices.end(); ++device_it) {
548 if (request.requested_device_id == device_it->device_id) { 593 if (request.requested_device_id == device_it->device_id) {
549 StreamDeviceInfo device = *device_it; 594 StreamDeviceInfo device = *device_it;
550 device.in_use = false; 595 device.in_use = false;
551 device.session_id = 596 device.session_id =
552 GetDeviceManager(device_it->stream_type)->Open(device); 597 GetDeviceManager(device_it->stream_type)->Open(device);
553 request.state[device_it->stream_type] = 598 request.state[device_it->stream_type] =
554 DeviceRequest::STATE_OPENING; 599 DeviceRequest::STATE_OPENING;
555 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 600 request.devices.push_back(device);
556 request.audio_devices.push_back(device);
557 else
558 request.video_devices.push_back(device);
559 break; 601 break;
560 } 602 }
561 } 603 }
562 break; 604 break;
563 default: 605 default:
564 device_settings_->AvailableDevices(*it, stream_type, devices); 606 device_settings_->AvailableDevices(*it, stream_type, devices);
607 break;
565 } 608 }
566 } 609 }
567 label_list.clear(); 610 label_list.clear();
568 --active_enumeration_ref_count_[stream_type]; 611 --active_enumeration_ref_count_[stream_type];
569 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 612 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
570 } 613 }
571 614
572 void MediaStreamManager::Error(MediaStreamType stream_type, 615 void MediaStreamManager::Error(MediaStreamType stream_type,
573 int capture_session_id, 616 int capture_session_id,
574 MediaStreamProviderError error) { 617 MediaStreamProviderError error) {
575 // Find the device for the error call. 618 // Find the device for the error call.
576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 619 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
620
577 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); 621 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end();
578 ++it) { 622 ++it) {
579 StreamDeviceInfoArray* devices = NULL; 623 StreamDeviceInfoArray& devices = it->second.devices;
580 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
581 devices = &(it->second.audio_devices);
582 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
583 devices = &(it->second.video_devices);
584 } else {
585 NOTREACHED();
586 }
587 624
588 int device_idx = 0; 625 int audio_device_idx = -1;
589 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 626 int video_device_idx = -1;
590 device_it != devices->end(); ++device_it, ++device_idx) { 627 for (StreamDeviceInfoArray::iterator device_it = devices.begin();
591 if (device_it->session_id == capture_session_id) { 628 device_it != devices.end(); ++device_it) {
592 // We've found the failing device. Find the error case: 629 if (content::IsAudioMediaType(device_it->stream_type)) {
593 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) { 630 ++audio_device_idx;
594 // 1. Already opened -> signal device failure and close device. 631 } else if (content::IsVideoMediaType(device_it->stream_type)) {
595 // Use device_idx to signal which of the devices encountered an 632 ++video_device_idx;
596 // error. 633 } else {
597 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 634 NOTREACHED();
598 it->second.requester->AudioDeviceFailed(it->first, device_idx); 635 continue;
599 } else if (stream_type == 636 }
600 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 637 if (device_it->stream_type != stream_type ||
601 it->second.requester->VideoDeviceFailed(it->first, device_idx); 638 device_it->session_id != capture_session_id) {
602 } 639 continue;
603 GetDeviceManager(stream_type)->Close(capture_session_id); 640 }
604 // We don't erase the devices here so that we can update the UI 641 // We've found the failing device. Find the error case:
605 // properly in StopGeneratedStream(). 642 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) {
606 it->second.state[stream_type] = DeviceRequest::STATE_ERROR; 643 // 1. Already opened -> signal device failure and close device.
644 // Use device_idx to signal which of the devices encountered an
645 // error.
646 if (content::IsAudioMediaType(stream_type)) {
647 it->second.requester->AudioDeviceFailed(it->first, audio_device_idx);
tommi (sloooow) - chröme 2012/09/10 09:17:25 Using the index here seems to be a bug to me. May
no longer working on chromium 2012/09/10 11:00:17 I agree the code is quite messy here, probably a f
tommi (sloooow) - chröme 2012/09/10 11:29:01 I don't think so. Read through the example I gave
no longer working on chromium 2012/09/10 12:28:03 Thanks for the pointing it out. It is indeed a pro
miu 2012/09/10 21:24:38 This seemed funny to me. I had modified this code
648 } else if (content::IsVideoMediaType(stream_type)) {
649 it->second.requester->VideoDeviceFailed(it->first, video_device_idx);
607 } else { 650 } else {
608 // Request is not done, devices are not opened in this case. 651 NOTREACHED();
609 if ((it->second.audio_devices.size() + 652 return;
610 it->second.video_devices.size()) <= 1) {
611 // 2. Device not opened and no other devices for this request ->
612 // signal stream error and remove the request.
613 it->second.requester->StreamGenerationFailed(it->first);
614 requests_.erase(it);
615 } else {
616 // 3. Not opened but other devices exists for this request -> remove
617 // device from list, but don't signal an error.
618 devices->erase(device_it);
619 }
620 } 653 }
621 return; 654 GetDeviceManager(stream_type)->Close(capture_session_id);
655 // We don't erase the devices here so that we can update the UI
656 // properly in StopGeneratedStream().
657 it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
658 } else {
659 // Request is not done, devices are not opened in this case.
660 if (devices.size() <= 1) {
661 // 2. Device not opened and no other devices for this request ->
662 // signal stream error and remove the request.
663 it->second.requester->StreamGenerationFailed(it->first);
664 requests_.erase(it);
665 } else {
666 // 3. Not opened but other devices exists for this request -> remove
667 // device from list, but don't signal an error.
668 devices.erase(device_it); // NOTE: This invalidates device_it!
669 }
622 } 670 }
671 return;
623 } 672 }
624 } 673 }
625 } 674 }
626 675
627 void MediaStreamManager::DevicesAccepted(const std::string& label, 676 void MediaStreamManager::DevicesAccepted(const std::string& label,
628 const StreamDeviceInfoArray& devices) { 677 const StreamDeviceInfoArray& devices) {
629 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
630 DeviceRequests::iterator request_it = requests_.find(label); 679 DeviceRequests::iterator request_it = requests_.find(label);
631 if (request_it != requests_.end()) { 680 if (request_it == requests_.end()) {
632 if (devices.empty()) { 681 return;
633 // No available devices or user didn't accept device usage. 682 }
634 request_it->second.requester->StreamGenerationFailed(request_it->first); 683
635 requests_.erase(request_it); 684 DeviceRequest& request = request_it->second;
636 return; 685
686 if (devices.empty()) {
687 // No available devices or user didn't accept device usage.
688 request.requester->StreamGenerationFailed(request_it->first);
689 requests_.erase(request_it);
690 return;
691 }
692
693 // Process all newly-accepted devices for this request.
694 bool found_audio = false, found_video = false;
695 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin();
696 device_it != devices.end(); ++device_it) {
697 StreamDeviceInfo device_info = *device_it; // Make a copy.
698
699 // Set in_use to false to be able to track if this device has been
700 // opened. in_use might be true if the device type can be used in more
701 // than one session.
702 DCHECK_EQ(request.state[device_it->stream_type],
703 DeviceRequest::STATE_PENDING_APPROVAL);
704 device_info.in_use = false;
705 device_info.session_id =
706 GetDeviceManager(device_info.stream_type)->Open(device_info);
707 request.state[device_it->stream_type] = DeviceRequest::STATE_OPENING;
708 request.devices.push_back(device_info);
709
710 if (device_info.stream_type == request.options.audio_type) {
711 found_audio = true;
712 } else if (device_info.stream_type == request.options.video_type) {
713 found_video = true;
637 } 714 }
715 }
638 716
639 // Loop through all device types for this request. 717 // Check whether we've received all stream types requested.
640 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); 718 if (request.options.audio_type != content::MEDIA_NO_SERVICE &&
no longer working on chromium 2012/09/10 09:11:04 nit, using content::IsAudioMediaType(request.optio
miu 2012/09/10 21:24:38 Done.
641 device_it != devices.end(); ++device_it) { 719 !found_audio) {
642 StreamDeviceInfo device_info = *device_it; 720 request.state[request.options.audio_type] = DeviceRequest::STATE_ERROR;
643 721 }
644 // Set in_use to false to be able to track if this device has been 722 if (request.options.video_type != content::MEDIA_NO_SERVICE &&
no longer working on chromium 2012/09/10 09:11:04 ditto
miu 2012/09/10 21:24:38 Done.
645 // opened. in_use might be true if the device type can be used in more 723 !found_video) {
646 // than one session. 724 request.state[request.options.video_type] = DeviceRequest::STATE_ERROR;
647 DCHECK_EQ(request_it->second.state[device_it->stream_type],
648 DeviceRequest::STATE_PENDING_APPROVAL);
649 device_info.in_use = false;
650 device_info.session_id =
651 GetDeviceManager(device_info.stream_type)->Open(device_info);
652 request_it->second.state[device_it->stream_type] =
653 DeviceRequest::STATE_OPENING;
654 if (device_info.stream_type ==
655 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
656 request_it->second.audio_devices.push_back(device_info);
657 } else if (device_info.stream_type ==
658 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
659 request_it->second.video_devices.push_back(device_info);
660 } else {
661 NOTREACHED();
662 }
663 }
664 // Check if we received all stream types requested.
665 MediaStreamType stream_type =
666 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
667 if (Requested(request_it->second.options, stream_type) &&
668 request_it->second.audio_devices.size() == 0) {
669 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
670 }
671 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE;
672 if (Requested(request_it->second.options, stream_type) &&
673 request_it->second.video_devices.size() == 0) {
674 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
675 }
676 return;
677 } 725 }
678 } 726 }
679 727
680 void MediaStreamManager::SettingsError(const std::string& label) { 728 void MediaStreamManager::SettingsError(const std::string& label) {
681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 729 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
682 // Erase this request and report an error. 730 // Erase this request and report an error.
683 DeviceRequests::iterator it = requests_.find(label); 731 DeviceRequests::iterator it = requests_.find(label);
684 if (it != requests_.end()) { 732 if (it != requests_.end()) {
685 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); 733 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM);
686 it->second.requester->StreamGenerationFailed(label); 734 it->second.requester->StreamGenerationFailed(label);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 DevicesFromRequest(request, &closed_devices); 778 DevicesFromRequest(request, &closed_devices);
731 if (closed_devices.empty()) 779 if (closed_devices.empty())
732 return; 780 return;
733 media_observer->OnCaptureDevicesClosed(request->render_process_id, 781 media_observer->OnCaptureDevicesClosed(request->render_process_id,
734 request->render_view_id, 782 request->render_view_id,
735 closed_devices); 783 closed_devices);
736 } 784 }
737 785
738 void MediaStreamManager::DevicesFromRequest( 786 void MediaStreamManager::DevicesFromRequest(
739 DeviceRequest* request, content::MediaStreamDevices* devices) { 787 DeviceRequest* request, content::MediaStreamDevices* devices) {
740 StreamDeviceInfoArray::const_iterator it = request->audio_devices.begin(); 788 for (StreamDeviceInfoArray::const_iterator it = request->devices.begin();
741 for (; it != request->audio_devices.end(); ++it) { 789 it != request->devices.end(); ++it) {
742 devices->push_back( 790 devices->push_back(content::MediaStreamDevice(
743 content::MediaStreamDevice( 791 it->stream_type, it->device_id, it->name));
744 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE,
745 it->device_id,
746 it->name));
747 }
748 for (it = request->video_devices.begin(); it != request->video_devices.end();
749 ++it) {
750 devices->push_back(
751 content::MediaStreamDevice(
752 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE,
753 it->device_id,
754 it->name));
755 } 792 }
756 } 793 }
757 794
758 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { 795 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const {
759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 796 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
760 // Check if all devices are opened.
761 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
762 if (Requested(request.options, stream_type)) {
763 if (request.state[stream_type] != DeviceRequest::STATE_DONE &&
764 request.state[stream_type] != DeviceRequest::STATE_ERROR) {
765 return false;
766 }
767 797
768 for (StreamDeviceInfoArray::const_iterator it = 798 const bool requested_audio =
769 request.audio_devices.begin(); it != request.audio_devices.end(); 799 content::IsAudioMediaType(request.options.audio_type);
770 ++it) { 800 const bool requested_video =
771 if (it->in_use == false) { 801 content::IsVideoMediaType(request.options.video_type);
772 return false; 802
773 } 803 const bool audio_done =
774 } 804 !requested_audio ||
805 request.state[request.options.audio_type] == DeviceRequest::STATE_DONE ||
806 request.state[request.options.audio_type] == DeviceRequest::STATE_ERROR;
807 if (!audio_done) {
808 return false;
775 } 809 }
776 810
777 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 811 const bool video_done =
778 if (Requested(request.options, stream_type)) { 812 !requested_video ||
779 if (request.state[stream_type] != DeviceRequest::STATE_DONE && 813 request.state[request.options.video_type] == DeviceRequest::STATE_DONE ||
780 request.state[stream_type] != DeviceRequest::STATE_ERROR) { 814 request.state[request.options.video_type] == DeviceRequest::STATE_ERROR;
815 if (!video_done) {
816 return false;
817 }
818
819 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin();
820 it != request.devices.end(); ++it) {
821 if (it->in_use == false) {
781 return false; 822 return false;
782 } 823 }
783
784 for (StreamDeviceInfoArray::const_iterator it =
785 request.video_devices.begin(); it != request.video_devices.end();
786 ++it) {
787 if (it->in_use == false) {
788 return false;
789 }
790 }
791 } 824 }
792 825
793 return true; 826 return true;
794 } 827 }
795 828
796 // Called to get media capture device manager of specified type.
797 MediaStreamProvider* MediaStreamManager::GetDeviceManager( 829 MediaStreamProvider* MediaStreamManager::GetDeviceManager(
798 MediaStreamType stream_type) { 830 MediaStreamType stream_type) {
799 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 831 if (content::IsVideoMediaType(stream_type)) {
800 return video_capture_manager(); 832 return video_capture_manager();
801 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 833 } else if (content::IsAudioMediaType(stream_type)) {
802 return audio_input_device_manager(); 834 return audio_input_device_manager();
803 } 835 }
804 NOTREACHED(); 836 NOTREACHED();
805 return NULL; 837 return NULL;
806 } 838 }
807 839
808 void MediaStreamManager::OnDevicesChanged( 840 void MediaStreamManager::OnDevicesChanged(
809 base::SystemMonitor::DeviceType device_type) { 841 base::SystemMonitor::DeviceType device_type) {
810 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
843
844 // NOTE: This method is only called in response to physical audio/video device
845 // changes (from the operating system).
846
811 MediaStreamType stream_type; 847 MediaStreamType stream_type;
812 EnumerationCache* cache; 848 EnumerationCache* cache;
813 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { 849 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) {
814 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 850 stream_type = content::MEDIA_DEVICE_AUDIO_CAPTURE;
815 cache = &audio_enumeration_cache_; 851 cache = &audio_enumeration_cache_;
816 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { 852 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) {
817 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 853 stream_type = content::MEDIA_DEVICE_VIDEO_CAPTURE;
818 cache = &video_enumeration_cache_; 854 cache = &video_enumeration_cache_;
819 } else { 855 } else {
820 return; // Uninteresting device change. 856 return; // Uninteresting device change.
821 } 857 }
822 858
823 if (!HasEnumerationRequest(stream_type)) { 859 if (!HasEnumerationRequest(stream_type)) {
824 // There is no request for that type, No need to enumerate devices. 860 // There is no request for that type, No need to enumerate devices.
825 // Therefore, invalidate the cache of that type. 861 // Therefore, invalidate the cache of that type.
826 ClearEnumerationCache(cache); 862 ClearEnumerationCache(cache);
827 return; 863 return;
(...skipping 24 matching lines...) Expand all
852 it != requests_.end(); ++it) { 888 it != requests_.end(); ++it) {
853 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && 889 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES &&
854 Requested(it->second.options, stream_type)) { 890 Requested(it->second.options, stream_type)) {
855 return true; 891 return true;
856 } 892 }
857 } 893 }
858 return false; 894 return false;
859 } 895 }
860 896
861 } // namespace media_stream 897 } // namespace media_stream
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698