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/media_stream_manager.h" | 5 #include "content/browser/renderer_host/media/media_stream_manager.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
15 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
16 #include "content/browser/renderer_host/media/audio_input_device_manager.h" | 16 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
17 #include "content/browser/renderer_host/media/device_request_message_filter.h" | 17 #include "content/browser/renderer_host/media/device_request_message_filter.h" |
18 #include "content/browser/renderer_host/media/media_source_id_factory.h" | |
18 #include "content/browser/renderer_host/media/media_stream_requester.h" | 19 #include "content/browser/renderer_host/media/media_stream_requester.h" |
19 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" | 20 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" |
20 #include "content/browser/renderer_host/media/video_capture_manager.h" | 21 #include "content/browser/renderer_host/media/video_capture_manager.h" |
21 #include "content/browser/renderer_host/media/web_contents_capture_util.h" | 22 #include "content/browser/renderer_host/media/web_contents_capture_util.h" |
22 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
23 #include "content/public/browser/content_browser_client.h" | 24 #include "content/public/browser/content_browser_client.h" |
24 #include "content/public/browser/media_observer.h" | 25 #include "content/public/browser/media_observer.h" |
25 #include "content/public/browser/media_request_state.h" | 26 #include "content/public/browser/media_request_state.h" |
26 #include "content/public/common/content_switches.h" | 27 #include "content/public/common/content_switches.h" |
27 #include "content/public/common/media_stream_request.h" | 28 #include "content/public/common/media_stream_request.h" |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
191 // Create a new request based on options. | 192 // Create a new request based on options. |
192 MediaStreamRequest stream_request( | 193 MediaStreamRequest stream_request( |
193 render_process_id, render_view_id, page_request_id, std::string(), | 194 render_process_id, render_view_id, page_request_id, std::string(), |
194 security_origin, MEDIA_DEVICE_ACCESS, std::string(), std::string(), | 195 security_origin, MEDIA_DEVICE_ACCESS, std::string(), std::string(), |
195 options.audio_type, options.video_type); | 196 options.audio_type, options.video_type); |
196 DeviceRequest* request = new DeviceRequest(NULL, stream_request); | 197 DeviceRequest* request = new DeviceRequest(NULL, stream_request); |
197 const std::string& label = AddRequest(request); | 198 const std::string& label = AddRequest(request); |
198 | 199 |
199 request->callback = callback; | 200 request->callback = callback; |
200 | 201 BrowserThread::PostTask( |
201 HandleRequest(label); | 202 BrowserThread::IO, FROM_HERE, |
202 | 203 base::Bind(&MediaStreamManager::HandleRequest, |
no longer working on chromium
2013/10/25 08:16:39
I don't fully understand this change, how can't we
perkj_chrome
2013/10/25 13:33:50
Yes. the label is used in error reporting.
In orde
| |
204 base::Unretained(this), label)); | |
203 return label; | 205 return label; |
204 } | 206 } |
205 | 207 |
206 std::string MediaStreamManager::GenerateStream( | 208 std::string MediaStreamManager::GenerateStream( |
no longer working on chromium
2013/10/25 12:00:07
make remove the code in the dispatcher which handl
perkj_chrome
2013/10/25 13:33:50
Done.
| |
207 MediaStreamRequester* requester, | 209 MediaStreamRequester* requester, |
208 int render_process_id, | 210 int render_process_id, |
209 int render_view_id, | 211 int render_view_id, |
210 int page_request_id, | 212 int page_request_id, |
211 const StreamOptions& options, | 213 const StreamOptions& options, |
212 const GURL& security_origin) { | 214 const GURL& security_origin) { |
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
214 if (CommandLine::ForCurrentProcess()->HasSwitch( | 216 if (CommandLine::ForCurrentProcess()->HasSwitch( |
215 switches::kUseFakeDeviceForMediaStream)) { | 217 switches::kUseFakeDeviceForMediaStream)) { |
216 UseFakeDevice(); | 218 UseFakeDevice(); |
(...skipping 24 matching lines...) Expand all Loading... | |
241 if (!has_valid_device_id || | 243 if (!has_valid_device_id || |
242 (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE && | 244 (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE && |
243 options.audio_type != MEDIA_NO_SERVICE) || | 245 options.audio_type != MEDIA_NO_SERVICE) || |
244 (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && | 246 (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && |
245 options.video_type != MEDIA_NO_SERVICE)) { | 247 options.video_type != MEDIA_NO_SERVICE)) { |
246 LOG(ERROR) << "Invalid request."; | 248 LOG(ERROR) << "Invalid request."; |
247 return std::string(); | 249 return std::string(); |
248 } | 250 } |
249 } | 251 } |
250 | 252 |
251 std::string translated_audio_device_id; | |
252 std::string translated_video_device_id; | |
253 if (options.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE) { | |
254 bool found_match = TranslateGUIDToRawId( | |
255 MEDIA_DEVICE_AUDIO_CAPTURE, security_origin, options.audio_device_id, | |
256 &translated_audio_device_id); | |
257 DCHECK(found_match || translated_audio_device_id.empty()); | |
258 } | |
259 | |
260 if (options.video_type == MEDIA_DEVICE_VIDEO_CAPTURE) { | |
261 bool found_match = TranslateGUIDToRawId( | |
262 MEDIA_DEVICE_VIDEO_CAPTURE, security_origin, options.video_device_id, | |
263 &translated_video_device_id); | |
264 DCHECK(found_match || translated_video_device_id.empty()); | |
265 } | |
266 | |
267 if (options.video_type == MEDIA_DESKTOP_VIDEO_CAPTURE || | 253 if (options.video_type == MEDIA_DESKTOP_VIDEO_CAPTURE || |
268 options.audio_type == MEDIA_LOOPBACK_AUDIO_CAPTURE) { | 254 options.audio_type == MEDIA_LOOPBACK_AUDIO_CAPTURE) { |
269 // For screen capture we only support two valid combinations: | 255 // For screen capture we only support two valid combinations: |
270 // (1) screen video capture only, or | 256 // (1) screen video capture only, or |
271 // (2) screen video capture with loopback audio capture. | 257 // (2) screen video capture with loopback audio capture. |
272 if (options.video_type != MEDIA_DESKTOP_VIDEO_CAPTURE || | 258 if (options.video_type != MEDIA_DESKTOP_VIDEO_CAPTURE || |
273 (options.audio_type != MEDIA_NO_SERVICE && | 259 (options.audio_type != MEDIA_NO_SERVICE && |
274 options.audio_type != MEDIA_LOOPBACK_AUDIO_CAPTURE)) { | 260 options.audio_type != MEDIA_LOOPBACK_AUDIO_CAPTURE)) { |
275 // TODO(sergeyu): Surface error message to the calling JS code. | 261 // TODO(sergeyu): Surface error message to the calling JS code. |
276 LOG(ERROR) << "Invalid screen capture request."; | 262 LOG(ERROR) << "Invalid screen capture request."; |
277 return std::string(); | 263 return std::string(); |
278 } | 264 } |
279 translated_video_device_id = options.video_device_id; | |
280 } | 265 } |
281 | 266 |
282 // Create a new request based on options. | 267 // Create a new request based on options. |
283 MediaStreamRequest stream_request( | 268 MediaStreamRequest stream_request( |
284 target_render_process_id, target_render_view_id, page_request_id, | 269 target_render_process_id, target_render_view_id, page_request_id, |
285 tab_capture_device_id, security_origin, MEDIA_GENERATE_STREAM, | 270 tab_capture_device_id, security_origin, MEDIA_GENERATE_STREAM, |
286 translated_audio_device_id, translated_video_device_id, | 271 options.audio_device_id, options.video_device_id, |
287 options.audio_type, options.video_type); | 272 options.audio_type, options.video_type); |
288 DeviceRequest* request = new DeviceRequest(requester, stream_request); | 273 DeviceRequest* request = new DeviceRequest(requester, stream_request); |
289 const std::string& label = AddRequest(request); | 274 const std::string& label = AddRequest(request); |
290 HandleRequest(label); | 275 |
276 // Need to post a task since the requester won't have label till | |
277 // this function returns. | |
278 BrowserThread::PostTask( | |
279 BrowserThread::IO, FROM_HERE, | |
280 base::Bind(&MediaStreamManager::HandleRequest, | |
281 base::Unretained(this), label)); | |
291 return label; | 282 return label; |
292 } | 283 } |
293 | 284 |
294 void MediaStreamManager::CancelRequest(const std::string& label) { | 285 void MediaStreamManager::CancelRequest(const std::string& label) { |
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
296 | 287 |
288 BrowserThread::PostTask( | |
289 BrowserThread::IO, FROM_HERE, | |
290 base::Bind(&MediaStreamManager::DoCancelRequest, | |
291 base::Unretained(this), label)); | |
292 } | |
293 | |
294 void MediaStreamManager::DoCancelRequest(const std::string& label) { | |
297 DeviceRequests::iterator request_it = requests_.find(label); | 295 DeviceRequests::iterator request_it = requests_.find(label); |
298 if (request_it == requests_.end()) { | 296 if (request_it == requests_.end()) { |
299 NOTREACHED(); | 297 NOTREACHED(); |
300 return; | 298 return; |
301 } | 299 } |
302 scoped_ptr<DeviceRequest> request(request_it->second); | |
303 RemoveRequest(request_it); | |
304 | 300 |
301 DeviceRequest* request(request_it->second); | |
305 if (request->request.request_type == MEDIA_ENUMERATE_DEVICES) { | 302 if (request->request.request_type == MEDIA_ENUMERATE_DEVICES) { |
303 DeleteRequest(request_it); | |
306 return; | 304 return; |
307 } | 305 } |
308 | 306 |
309 // This is a request for opening one or more devices. | 307 // This is a request for opening one or more devices. |
310 for (StreamDeviceInfoArray::iterator device_it = request->devices.begin(); | 308 for (StreamDeviceInfoArray::iterator device_it = request->devices.begin(); |
311 device_it != request->devices.end(); ++device_it) { | 309 device_it != request->devices.end(); ++device_it) { |
312 // If we have not yet requested the device to be opened - just ignore it. | 310 // If we have not yet requested the device to be opened - just ignore it. |
313 if (request->state(device_it->device.type) != MEDIA_REQUEST_STATE_OPENING | 311 if (request->state(device_it->device.type) != MEDIA_REQUEST_STATE_OPENING |
314 && | 312 && |
315 request->state(device_it->device.type) != MEDIA_REQUEST_STATE_DONE) { | 313 request->state(device_it->device.type) != MEDIA_REQUEST_STATE_DONE) { |
316 continue; | 314 continue; |
317 } | 315 } |
318 // Stop the opening/opened devices of the requests. | 316 // Stop the opening/opened devices of the requests. |
319 StopDevice(*device_it); | 317 StopDevice(*device_it); |
320 } | 318 } |
321 | 319 |
322 // Cancel the request if still pending at UI side. | 320 // Cancel the request if still pending at UI side. |
323 request->SetState(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_CLOSING); | 321 request->SetState(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_CLOSING); |
322 DeleteRequest(request_it); | |
324 } | 323 } |
325 | 324 |
326 void MediaStreamManager::CancelAllRequests(int render_process_id) { | 325 void MediaStreamManager::CancelAllRequests(int render_process_id) { |
327 DeviceRequests::iterator request_it = requests_.begin(); | 326 DeviceRequests::iterator request_it = requests_.begin(); |
328 while (request_it != requests_.end()) { | 327 while (request_it != requests_.end()) { |
329 if (request_it->second->request.render_process_id != render_process_id) { | 328 if (request_it->second->request.render_process_id != render_process_id) { |
330 ++request_it; | 329 ++request_it; |
331 continue; | 330 continue; |
332 } | 331 } |
333 | 332 |
334 std::string label = request_it->first; | 333 std::string label = request_it->first; |
335 ++request_it; | 334 ++request_it; |
336 CancelRequest(label); | 335 BrowserThread::PostTask( |
336 BrowserThread::IO, FROM_HERE, | |
337 base::Bind(&MediaStreamManager::DoCancelRequest, | |
no longer working on chromium
2013/10/25 08:16:39
same question here too.
perkj_chrome
2013/10/25 13:33:50
Same answer- we need to post always or never.
| |
338 base::Unretained(this), label)); | |
337 } | 339 } |
338 } | 340 } |
339 | 341 |
340 void MediaStreamManager::StopStreamDevice(int render_process_id, | 342 void MediaStreamManager::StopStreamDevice(int render_process_id, |
341 int render_view_id, | 343 int render_view_id, |
342 const std::string& device_id) { | 344 const std::string& device_id) { |
343 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
344 DVLOG(1) << "StopStreamDevice({render_view_id = " << render_view_id << "} " | 346 DVLOG(1) << "StopStreamDevice({render_view_id = " << render_view_id << "} " |
345 << ", {device_id = " << device_id << "})"; | 347 << ", {device_id = " << device_id << "})"; |
348 BrowserThread::PostTask( | |
349 BrowserThread::IO, FROM_HERE, | |
350 base::Bind(&MediaStreamManager::DoStopStreamDevice, | |
351 base::Unretained(this), render_process_id, render_view_id, | |
352 device_id)); | |
353 } | |
346 | 354 |
355 void MediaStreamManager::DoStopStreamDevice(int render_process_id, | |
356 int render_view_id, | |
357 const std::string& device_id) { | |
347 // Find all requests for this |render_process_id| and |render_view_id| of type | 358 // Find all requests for this |render_process_id| and |render_view_id| of type |
348 // MEDIA_GENERATE_STREAM that has requested to use |device_id|. | 359 // MEDIA_GENERATE_STREAM that has requested to use |device_id|. |
349 DeviceRequests::iterator request_it = requests_.begin(); | 360 DeviceRequests::iterator request_it = requests_.begin(); |
350 while (request_it != requests_.end()) { | 361 while (request_it != requests_.end()) { |
351 const MediaStreamRequest& ms_request = request_it->second->request; | 362 const MediaStreamRequest& ms_request = request_it->second->request; |
352 if (ms_request.render_process_id != render_process_id || | 363 if (ms_request.render_process_id != render_process_id || |
353 ms_request.render_view_id != render_view_id || | 364 ms_request.render_view_id != render_view_id || |
354 ms_request.request_type != MEDIA_GENERATE_STREAM) { | 365 ms_request.request_type != MEDIA_GENERATE_STREAM) { |
355 ++request_it; | 366 ++request_it; |
356 continue; | 367 continue; |
(...skipping 11 matching lines...) Expand all Loading... | |
368 device_it = devices->erase(device_it); | 379 device_it = devices->erase(device_it); |
369 } else { | 380 } else { |
370 ++device_it; | 381 ++device_it; |
371 } | 382 } |
372 } | 383 } |
373 | 384 |
374 // If this request doesn't have any active devices, remove the request. | 385 // If this request doesn't have any active devices, remove the request. |
375 if (devices->empty()) { | 386 if (devices->empty()) { |
376 DeviceRequests::iterator del_itor(request_it); | 387 DeviceRequests::iterator del_itor(request_it); |
377 ++request_it; | 388 ++request_it; |
378 scoped_ptr<DeviceRequest> request(del_itor->second); | 389 DeleteRequest(del_itor); |
379 RemoveRequest(del_itor); | |
380 } else { | 390 } else { |
381 ++request_it; | 391 ++request_it; |
382 } | 392 } |
383 } | 393 } |
384 } | 394 } |
385 | 395 |
386 void MediaStreamManager::StopDevice(const StreamDeviceInfo& device_info) { | 396 void MediaStreamManager::StopDevice(const StreamDeviceInfo& device_info) { |
387 DVLOG(1) << "StopDevice(" | 397 DVLOG(1) << "StopDevice(" |
388 << "{device_info.session_id = " << device_info.session_id << "} " | 398 << "{device_info.session_id = " << device_info.session_id << "} " |
389 << "{device_id = " << device_info.device.id << "})"; | 399 << "{device_id = " << device_info.device.id << "})"; |
(...skipping 30 matching lines...) Expand all Loading... | |
420 // starts monitoring devices. | 430 // starts monitoring devices. |
421 if (!requester) { | 431 if (!requester) { |
422 if (!monitoring_started_) | 432 if (!monitoring_started_) |
423 StartMonitoring(); | 433 StartMonitoring(); |
424 | 434 |
425 return std::string(); | 435 return std::string(); |
426 } | 436 } |
427 | 437 |
428 // Create a new request. | 438 // Create a new request. |
429 StreamOptions options; | 439 StreamOptions options; |
430 EnumerationCache* cache = NULL; | |
431 if (type == MEDIA_DEVICE_AUDIO_CAPTURE) { | 440 if (type == MEDIA_DEVICE_AUDIO_CAPTURE) { |
432 options.audio_type = type; | 441 options.audio_type = type; |
433 cache = &audio_enumeration_cache_; | |
434 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { | 442 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { |
435 options.video_type = type; | 443 options.video_type = type; |
436 cache = &video_enumeration_cache_; | |
437 } else { | 444 } else { |
438 NOTREACHED(); | 445 NOTREACHED(); |
439 return std::string(); | 446 return std::string(); |
440 } | 447 } |
441 | 448 |
442 MediaStreamRequest stream_request( | 449 MediaStreamRequest stream_request( |
443 render_process_id, render_view_id, page_request_id, std::string(), | 450 render_process_id, render_view_id, page_request_id, std::string(), |
444 security_origin, MEDIA_ENUMERATE_DEVICES, std::string(), std::string(), | 451 security_origin, MEDIA_ENUMERATE_DEVICES, std::string(), std::string(), |
445 options.audio_type, options.video_type); | 452 options.audio_type, options.video_type); |
446 DeviceRequest* request = new DeviceRequest(requester, stream_request); | 453 DeviceRequest* request = new DeviceRequest(requester, stream_request); |
447 const std::string& label = AddRequest(request); | 454 const std::string& label = AddRequest(request); |
455 BrowserThread::PostTask( | |
456 BrowserThread::IO, FROM_HERE, | |
457 base::Bind(&MediaStreamManager::DoEnumerateDevices, | |
458 base::Unretained(this), label)); | |
459 | |
460 return label; | |
461 } | |
462 | |
463 void MediaStreamManager::DoEnumerateDevices(const std::string& label) { | |
464 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
465 DeviceRequest* request = requests_[label]; | |
466 | |
467 const MediaStreamType type = | |
468 request->request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | |
469 MEDIA_DEVICE_AUDIO_CAPTURE : MEDIA_DEVICE_VIDEO_CAPTURE; | |
470 | |
471 EnumerationCache* cache = | |
472 request->request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | |
473 &audio_enumeration_cache_ : &video_enumeration_cache_; | |
448 | 474 |
449 if (cache->valid) { | 475 if (cache->valid) { |
450 // Cached device list of this type exists. Just send it out. | 476 // Cached device list of this type exists. Just send it out. |
451 request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED); | 477 request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED); |
452 | 478 request->devices = cache->devices; |
453 // Need to post a task since the requester won't have label till | 479 FinalizeEnumerateDevices(label, request); |
454 // this function returns. | |
455 BrowserThread::PostTask( | |
456 BrowserThread::IO, FROM_HERE, | |
457 base::Bind(&MediaStreamManager::SendCachedDeviceList, | |
458 base::Unretained(this), cache, label)); | |
459 } else { | 480 } else { |
460 StartEnumeration(request); | 481 StartEnumeration(request); |
461 } | 482 } |
462 | |
463 return label; | |
464 } | 483 } |
465 | 484 |
466 std::string MediaStreamManager::OpenDevice( | 485 std::string MediaStreamManager::OpenDevice( |
467 MediaStreamRequester* requester, | 486 MediaStreamRequester* requester, |
468 int render_process_id, | 487 int render_process_id, |
469 int render_view_id, | 488 int render_view_id, |
470 int page_request_id, | 489 int page_request_id, |
471 const std::string& device_id, | 490 const std::string& device_id, |
472 MediaStreamType type, | 491 MediaStreamType type, |
473 const GURL& security_origin) { | 492 const GURL& security_origin) { |
474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 493 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
475 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 494 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
476 type == MEDIA_DEVICE_VIDEO_CAPTURE); | 495 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
477 | 496 |
478 // Create a new request. | 497 // Create a new request. |
479 StreamOptions options; | 498 StreamOptions options; |
480 if (IsAudioMediaType(type)) { | 499 if (IsAudioMediaType(type)) { |
481 options.audio_type = type; | 500 options.audio_type = type; |
482 options.audio_device_id = device_id; | 501 options.audio_device_id = device_id; |
483 } else if (IsVideoMediaType(type)) { | 502 } else if (IsVideoMediaType(type)) { |
484 options.video_type = type; | 503 options.video_type = type; |
485 options.video_device_id = device_id; | 504 options.video_device_id = device_id; |
486 } else { | 505 } else { |
487 NOTREACHED(); | 506 NOTREACHED(); |
488 return std::string(); | 507 return std::string(); |
489 } | 508 } |
490 | 509 |
491 MediaStreamRequest stream_request( | 510 MediaStreamRequest stream_request( |
492 render_process_id, render_view_id, page_request_id, std::string(), | 511 render_process_id, render_view_id, page_request_id, std::string(), |
493 security_origin, MEDIA_OPEN_DEVICE, options.audio_device_id, | 512 security_origin, MEDIA_OPEN_DEVICE, options.audio_device_id, |
494 options.video_device_id, options.audio_type, options.video_type); | 513 options.video_device_id, options.audio_type, options.video_type); |
495 DeviceRequest* request = new DeviceRequest(requester, stream_request); | 514 DeviceRequest* request = new DeviceRequest(requester, stream_request); |
496 const std::string& label = AddRequest(request); | 515 const std::string& label = AddRequest(request); |
497 StartEnumeration(request); | 516 BrowserThread::PostTask( |
517 BrowserThread::IO, FROM_HERE, | |
518 base::Bind(&MediaStreamManager::HandleRequest, | |
519 base::Unretained(this), label)); | |
498 | 520 |
499 return label; | 521 return label; |
500 } | 522 } |
501 | 523 |
502 void MediaStreamManager::SendCachedDeviceList( | |
503 EnumerationCache* cache, | |
504 const std::string& label) { | |
505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
506 if (cache->valid) { | |
507 DeviceRequests::iterator it = requests_.find(label); | |
508 if (it != requests_.end()) { | |
509 it->second->requester->DevicesEnumerated(label, cache->devices); | |
510 } | |
511 } | |
512 } | |
513 | |
514 void MediaStreamManager::StartMonitoring() { | 524 void MediaStreamManager::StartMonitoring() { |
515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
516 if (!base::SystemMonitor::Get()) | 526 if (!base::SystemMonitor::Get()) |
517 return; | 527 return; |
518 | 528 |
519 if (!monitoring_started_) { | 529 if (!monitoring_started_) { |
520 monitoring_started_ = true; | 530 monitoring_started_ = true; |
521 base::SystemMonitor::Get()->AddDevicesChangedObserver(this); | 531 base::SystemMonitor::Get()->AddDevicesChangedObserver(this); |
522 | 532 |
523 // Enumerate both the audio and video devices to cache the device lists | 533 // Enumerate both the audio and video devices to cache the device lists |
524 // and send them to media observer. | 534 // and send them to media observer. |
525 ++active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_CAPTURE]; | 535 ++active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_CAPTURE]; |
526 audio_input_device_manager_->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE); | 536 audio_input_device_manager_->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE); |
527 ++active_enumeration_ref_count_[MEDIA_DEVICE_VIDEO_CAPTURE]; | 537 ++active_enumeration_ref_count_[MEDIA_DEVICE_VIDEO_CAPTURE]; |
528 video_capture_manager_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE); | 538 video_capture_manager_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE); |
529 } | 539 } |
530 } | 540 } |
531 | 541 |
532 void MediaStreamManager::StopMonitoring() { | 542 void MediaStreamManager::StopMonitoring() { |
533 DCHECK_EQ(base::MessageLoop::current(), io_loop_); | 543 DCHECK_EQ(base::MessageLoop::current(), io_loop_); |
534 if (monitoring_started_) { | 544 if (monitoring_started_) { |
535 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); | 545 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); |
536 monitoring_started_ = false; | 546 monitoring_started_ = false; |
537 ClearEnumerationCache(&audio_enumeration_cache_); | 547 ClearEnumerationCache(&audio_enumeration_cache_); |
538 ClearEnumerationCache(&video_enumeration_cache_); | 548 ClearEnumerationCache(&video_enumeration_cache_); |
539 } | 549 } |
540 } | 550 } |
541 | 551 |
542 bool MediaStreamManager::TranslateGUIDToRawId(MediaStreamType stream_type, | 552 bool MediaStreamManager::TransLateRequestedSourceIdToDeviceId( |
543 const GURL& security_origin, | 553 MediaStreamRequest* request) { |
544 const std::string& device_guid, | 554 // If a specific device has been requested we need to find the real device id. |
545 std::string* raw_device_id) { | 555 if (request->audio_type == MEDIA_DEVICE_AUDIO_CAPTURE && |
556 !request->requested_audio_device_id.empty()) { | |
557 if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_AUDIO_CAPTURE, | |
558 request->security_origin, | |
559 request->requested_audio_device_id, | |
560 &request->requested_audio_device_id)) { | |
561 // TODO(perkj): guM should support mandatory and optional constraints. | |
no longer working on chromium
2013/10/25 12:00:07
nit, gUM
perkj_chrome
2013/10/25 13:33:50
Done.
| |
562 // Ie - if the sourceId is optional but it does not match - guM should | |
563 // not fail. For now we treat sourceId as a mandatory constraint. | |
564 return false; | |
565 } | |
566 } | |
567 | |
568 if (request->video_type == MEDIA_DEVICE_VIDEO_CAPTURE && | |
569 !request->requested_video_device_id.empty()) { | |
570 if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_VIDEO_CAPTURE, | |
571 request->security_origin, | |
572 request->requested_video_device_id, | |
573 &request->requested_video_device_id)) { | |
574 // TODO(perkj): guM should support mandatory and optional constraints. | |
575 // Ie - if the sourceId is optional but it does not match - guM should | |
576 // not fail. For now we treat sourceId as a mandatory constraint. | |
577 return false; | |
578 } | |
579 } | |
580 DVLOG(1) << "Requested audio device " << request->requested_audio_device_id; | |
581 DVLOG(1) << "Requested video device " << request->requested_video_device_id; | |
582 return true; | |
583 } | |
584 | |
585 | |
586 bool MediaStreamManager::TranslateSourceIdToDeviceId( | |
587 MediaStreamType stream_type, | |
588 const GURL& security_origin, | |
589 const std::string& source_id, | |
590 std::string* device_id) { | |
546 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || | 591 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || |
547 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); | 592 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); |
548 if (device_guid.empty()) | 593 if (source_id.empty()) |
549 return false; | 594 return false; |
550 | 595 |
551 EnumerationCache* cache = | 596 EnumerationCache* cache = |
552 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | 597 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? |
553 &audio_enumeration_cache_ : &video_enumeration_cache_; | 598 &audio_enumeration_cache_ : &video_enumeration_cache_; |
554 | 599 |
555 // If device monitoring hasn't started, the |device_guid| is not valid. | 600 // If device monitoring hasn't started, the |device_guid| is not valid. |
556 if (!cache->valid) | 601 if (!cache->valid) |
557 return false; | 602 return false; |
558 | 603 |
559 for (StreamDeviceInfoArray::const_iterator it = cache->devices.begin(); | 604 for (StreamDeviceInfoArray::const_iterator it = cache->devices.begin(); |
560 it != cache->devices.end(); | 605 it != cache->devices.end(); |
561 ++it) { | 606 ++it) { |
562 if (DeviceRequestMessageFilter::DoesRawIdMatchGuid( | 607 if (MediaSourceIdFactory::DoesSourceIdMatchDeviceId( |
563 security_origin, device_guid, it->device.id)) { | 608 security_origin, source_id, it->device.id)) { |
564 *raw_device_id = it->device.id; | 609 *device_id = it->device.id; |
565 return true; | 610 return true; |
566 } | 611 } |
567 } | 612 } |
568 return false; | 613 return false; |
569 } | 614 } |
570 | 615 |
571 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | 616 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { |
572 DCHECK_EQ(base::MessageLoop::current(), io_loop_); | 617 DCHECK_EQ(base::MessageLoop::current(), io_loop_); |
573 cache->valid = false; | 618 cache->valid = false; |
574 } | 619 } |
(...skipping 27 matching lines...) Expand all Loading... | |
602 std::string unique_label; | 647 std::string unique_label; |
603 do { | 648 do { |
604 unique_label = RandomLabel(); | 649 unique_label = RandomLabel(); |
605 } while (requests_.find(unique_label) != requests_.end()); | 650 } while (requests_.find(unique_label) != requests_.end()); |
606 | 651 |
607 requests_.insert(std::make_pair(unique_label, request)); | 652 requests_.insert(std::make_pair(unique_label, request)); |
608 | 653 |
609 return unique_label; | 654 return unique_label; |
610 } | 655 } |
611 | 656 |
612 void MediaStreamManager::RemoveRequest(DeviceRequests::iterator it) { | 657 void MediaStreamManager::DeleteRequest(DeviceRequests::iterator it) { |
658 delete it->second; | |
no longer working on chromium
2013/10/25 12:00:07
I think it is safer to use smart pointer to do the
perkj_chrome
2013/10/25 13:33:50
ok- but I think delete NULL is ok.
| |
613 requests_.erase(it); | 659 requests_.erase(it); |
614 } | 660 } |
615 | 661 |
616 void MediaStreamManager::PostRequestToUI(const std::string& label) { | 662 void MediaStreamManager::PostRequestToUI(const std::string& label) { |
617 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 663 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
618 DeviceRequest* request = requests_[label]; | 664 DeviceRequest* request = requests_[label]; |
619 | 665 |
620 if (use_fake_ui_) { | 666 if (use_fake_ui_) { |
621 if (!fake_ui_) | 667 if (!fake_ui_) |
622 fake_ui_.reset(new FakeMediaStreamUIProxy()); | 668 fake_ui_.reset(new FakeMediaStreamUIProxy()); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
666 | 712 |
667 if (!is_web_contents_capture && | 713 if (!is_web_contents_capture && |
668 !is_screen_capture && | 714 !is_screen_capture && |
669 ((IsAudioMediaType(audio_type) && !audio_enumeration_cache_.valid) || | 715 ((IsAudioMediaType(audio_type) && !audio_enumeration_cache_.valid) || |
670 (IsVideoMediaType(video_type) && !video_enumeration_cache_.valid))) { | 716 (IsVideoMediaType(video_type) && !video_enumeration_cache_.valid))) { |
671 // Enumerate the devices if there is no valid device lists to be used. | 717 // Enumerate the devices if there is no valid device lists to be used. |
672 StartEnumeration(request); | 718 StartEnumeration(request); |
673 return; | 719 return; |
674 } | 720 } |
675 | 721 |
722 // If a specific device has been requested we need to find the real device id. | |
723 if (!TransLateRequestedSourceIdToDeviceId(&request->request)) { | |
724 FinalizeRequestFailed(label); | |
725 return; | |
726 } | |
727 | |
676 // No need to do new device enumerations, post the request to UI | 728 // No need to do new device enumerations, post the request to UI |
677 // immediately. | 729 // immediately. |
678 if (IsAudioMediaType(audio_type)) | 730 if (IsAudioMediaType(audio_type)) |
679 request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 731 request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
680 if (IsVideoMediaType(video_type)) | 732 if (IsVideoMediaType(video_type)) |
681 request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 733 request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
682 | 734 |
683 PostRequestToUI(label); | 735 PostRequestToUI(label); |
684 } | 736 } |
685 | 737 |
738 bool MediaStreamManager::FindRequestedDeviceInfo( | |
739 const std::string& source_id, | |
740 int render_process_id, | |
741 int render_view_id, | |
742 MediaStreamRequestType type, | |
743 StreamDeviceInfo* device_info) { | |
744 for (DeviceRequests::const_iterator it = requests_.begin(); | |
745 it != requests_.end() ; ++it) { | |
746 const DeviceRequest* request = it->second; | |
747 if (request->request.render_process_id ==render_process_id && | |
748 request->request.render_view_id == render_view_id && | |
749 request->request.request_type == type) { | |
750 for (StreamDeviceInfoArray::const_iterator device_it = | |
751 request->devices.begin(); | |
752 device_it != request->devices.end(); ++device_it) { | |
753 if (source_id == device_it->device.id) { | |
754 if (device_info) | |
755 *device_info = *device_it; | |
756 return true; | |
757 } | |
758 } | |
759 } | |
760 } | |
761 return false; | |
762 } | |
763 | |
686 bool MediaStreamManager::FindExistingRequestedDeviceInfo( | 764 bool MediaStreamManager::FindExistingRequestedDeviceInfo( |
687 int render_process_id, | 765 int render_process_id, |
688 int render_view_id, | 766 int render_view_id, |
767 GURL security_origin, | |
689 MediaStreamRequestType type, | 768 MediaStreamRequestType type, |
690 const std::string& device_id, | 769 const std::string& device_id, |
691 StreamDeviceInfo* device_info, | 770 StreamDeviceInfo* device_info, |
692 MediaRequestState* request_state) const { | 771 MediaRequestState* request_state) const { |
693 DCHECK(device_info); | 772 DCHECK(device_info); |
694 DCHECK(request_state); | 773 DCHECK(request_state); |
774 | |
775 std::string source_id; | |
776 MediaSourceIdFactory::GenerateSourceId(security_origin, | |
777 device_id, | |
778 &source_id); | |
779 | |
695 for (DeviceRequests::const_iterator it = requests_.begin(); | 780 for (DeviceRequests::const_iterator it = requests_.begin(); |
696 it != requests_.end() ; ++it) { | 781 it != requests_.end() ; ++it) { |
697 const DeviceRequest* request = it->second; | 782 const DeviceRequest* request = it->second; |
698 if (request->request.render_process_id ==render_process_id && | 783 if (request->request.render_process_id ==render_process_id && |
699 request->request.render_view_id == render_view_id && | 784 request->request.render_view_id == render_view_id && |
700 request->request.request_type == type) { | 785 request->request.request_type == type) { |
701 for (StreamDeviceInfoArray::const_iterator device_it = | 786 for (StreamDeviceInfoArray::const_iterator device_it = |
702 request->devices.begin(); | 787 request->devices.begin(); |
703 device_it != request->devices.end(); ++device_it) { | 788 device_it != request->devices.end(); ++device_it) { |
704 if (device_it->device.id == device_id) { | 789 if (device_it->device.id == source_id) { |
705 *device_info = *device_it; | 790 *device_info = *device_it; |
706 *request_state = request->state(device_it->device.type); | 791 *request_state = request->state(device_it->device.type); |
707 return true; | 792 return true; |
708 } | 793 } |
709 } | 794 } |
710 } | 795 } |
711 } | 796 } |
712 return false; | 797 return false; |
713 } | 798 } |
714 | 799 |
800 void MediaStreamManager::FinalizeGenerateStream(const std::string& label, | |
801 DeviceRequest* request) { | |
802 const StreamDeviceInfoArray& requested_devices = request->devices; | |
803 | |
804 // Partition the array of devices into audio vs video. | |
805 StreamDeviceInfoArray audio_devices, video_devices; | |
806 for (StreamDeviceInfoArray::const_iterator device_it = | |
807 requested_devices.begin(); | |
808 device_it != requested_devices.end(); ++device_it) { | |
809 if (IsAudioMediaType(device_it->device.type)) { | |
810 audio_devices.push_back(*device_it); | |
811 } else if (IsVideoMediaType(device_it->device.type)) { | |
812 video_devices.push_back(*device_it); | |
813 } else { | |
814 NOTREACHED(); | |
815 } | |
816 } | |
817 | |
818 request->requester->StreamGenerated(label, audio_devices, video_devices); | |
819 } | |
820 | |
821 void MediaStreamManager::FinalizeRequestFailed( | |
822 const std::string& label) { | |
823 DeviceRequests::iterator request_it = requests_.find(label); | |
824 if (request_it == requests_.end()) { | |
no longer working on chromium
2013/10/25 12:00:07
nit, no need {}
perkj_chrome
2013/10/25 13:33:50
Done.
| |
825 return; | |
826 } | |
827 DeviceRequest* request(request_it->second); | |
828 if (request->requester) | |
829 request->requester->StreamGenerationFailed(label); | |
830 | |
831 if (request->request.request_type == MEDIA_DEVICE_ACCESS && | |
832 !request->callback.is_null()) { | |
833 request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass()); | |
834 } | |
835 | |
836 DeleteRequest(request_it); | |
837 } | |
838 | |
839 void MediaStreamManager::FinalizeOpenDevice(const std::string& label, | |
840 DeviceRequest* request) { | |
841 const StreamDeviceInfoArray& requested_devices = request->devices; | |
842 request->requester->DeviceOpened(label, requested_devices.front()); | |
843 } | |
844 | |
845 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label, | |
846 DeviceRequest* request) { | |
847 StreamDeviceInfoArray hmaced_devices; | |
848 MediaSourceIdFactory::GenerateSourceIds(request->request.security_origin, | |
849 request->devices, | |
850 &hmaced_devices); | |
851 request->requester->DevicesEnumerated(label, hmaced_devices); | |
852 } | |
853 | |
854 void MediaStreamManager::FinalizeMediaAccessRequest( | |
855 const std::string& label, | |
856 const MediaStreamDevices& devices) { | |
857 DeviceRequests::iterator request_it = requests_.find(label); | |
858 if (request_it == requests_.end()) { | |
no longer working on chromium
2013/10/25 12:00:07
ditto
perkj_chrome
2013/10/25 13:33:50
Done.
| |
859 return; | |
860 } | |
861 DeviceRequest* request(request_it->second); | |
862 | |
863 if (!request->callback.is_null()) | |
864 request->callback.Run(devices, request->ui_proxy.Pass()); | |
865 | |
866 // Delete the request since it is done. | |
867 DeleteRequest(request_it); | |
868 return; | |
no longer working on chromium
2013/10/25 12:00:07
you don't need the return
perkj_chrome
2013/10/25 13:33:50
Done.
| |
869 } | |
870 | |
715 void MediaStreamManager::InitializeDeviceManagersOnIOThread() { | 871 void MediaStreamManager::InitializeDeviceManagersOnIOThread() { |
716 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 872 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
717 if (device_thread_) | 873 if (device_thread_) |
718 return; | 874 return; |
719 | 875 |
720 device_thread_.reset(new base::Thread("MediaStreamDeviceThread")); | 876 device_thread_.reset(new base::Thread("MediaStreamDeviceThread")); |
721 #if defined(OS_WIN) | 877 #if defined(OS_WIN) |
722 device_thread_->init_com_with_mta(true); | 878 device_thread_->init_com_with_mta(true); |
723 #endif | 879 #endif |
724 CHECK(device_thread_->Start()); | 880 CHECK(device_thread_->Start()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
759 request->SetState(device_it->device.type, MEDIA_REQUEST_STATE_DONE); | 915 request->SetState(device_it->device.type, MEDIA_REQUEST_STATE_DONE); |
760 | 916 |
761 if (IsAudioMediaType(device_it->device.type)) { | 917 if (IsAudioMediaType(device_it->device.type)) { |
762 // Store the native audio parameters in the device struct. | 918 // Store the native audio parameters in the device struct. |
763 // TODO(xians): Handle the tab capture sample rate/channel layout | 919 // TODO(xians): Handle the tab capture sample rate/channel layout |
764 // in AudioInputDeviceManager::Open(). | 920 // in AudioInputDeviceManager::Open(). |
765 if (device_it->device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { | 921 if (device_it->device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { |
766 const StreamDeviceInfo* info = | 922 const StreamDeviceInfo* info = |
767 audio_input_device_manager_->GetOpenedDeviceInfoById( | 923 audio_input_device_manager_->GetOpenedDeviceInfoById( |
768 device_it->session_id); | 924 device_it->session_id); |
769 DCHECK_EQ(info->device.id, device_it->device.id); | |
770 device_it->device.input = info->device.input; | 925 device_it->device.input = info->device.input; |
771 device_it->device.matched_output = info->device.matched_output; | 926 device_it->device.matched_output = info->device.matched_output; |
772 } | 927 } |
773 } | 928 } |
774 if (RequestDone(*request)) | 929 if (RequestDone(*request)) |
775 HandleRequestDone(label, request); | 930 HandleRequestDone(label, request); |
776 break; | 931 break; |
777 } | 932 } |
778 } | 933 } |
779 } | 934 } |
780 } | 935 } |
781 | 936 |
782 void MediaStreamManager::HandleRequestDone(const std::string& label, | 937 void MediaStreamManager::HandleRequestDone(const std::string& label, |
783 DeviceRequest* request) { | 938 DeviceRequest* request) { |
784 DCHECK(RequestDone(*request)); | 939 DCHECK(RequestDone(*request)); |
785 DVLOG(1) << "HandleRequestDone(" | 940 DVLOG(1) << "HandleRequestDone(" |
786 << ", {label = " << label << "})"; | 941 << ", {label = " << label << "})"; |
787 | 942 |
788 const StreamDeviceInfoArray& requested_devices = request->devices; | |
789 switch (request->request.request_type) { | 943 switch (request->request.request_type) { |
790 case MEDIA_OPEN_DEVICE: | 944 case MEDIA_OPEN_DEVICE: |
791 request->requester->DeviceOpened(label, requested_devices.front()); | 945 FinalizeOpenDevice(label, request); |
792 break; | 946 break; |
793 case MEDIA_GENERATE_STREAM: { | 947 case MEDIA_GENERATE_STREAM: { |
794 // Partition the array of devices into audio vs video. | 948 FinalizeGenerateStream(label, request); |
795 StreamDeviceInfoArray audio_devices, video_devices; | |
796 for (StreamDeviceInfoArray::const_iterator device_it = | |
797 requested_devices.begin(); | |
798 device_it != requested_devices.end(); ++device_it) { | |
799 if (IsAudioMediaType(device_it->device.type)) { | |
800 audio_devices.push_back(*device_it); | |
801 } else if (IsVideoMediaType(device_it->device.type)) { | |
802 video_devices.push_back(*device_it); | |
803 } else { | |
804 NOTREACHED(); | |
805 } | |
806 } | |
807 | |
808 request->requester->StreamGenerated(label, audio_devices, video_devices); | |
809 break; | 949 break; |
810 } | 950 } |
811 default: | 951 default: |
812 NOTREACHED(); | 952 NOTREACHED(); |
813 break; | 953 break; |
814 } | 954 } |
815 | 955 |
816 if (request->ui_proxy.get()) { | 956 if (request->ui_proxy.get()) { |
817 request->ui_proxy->OnStarted( | 957 request->ui_proxy->OnStarted( |
818 base::Bind(&MediaStreamManager::StopStreamFromUI, | 958 base::Bind(&MediaStreamManager::StopStreamFromUI, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
858 if (it->second->request.request_type != MEDIA_ENUMERATE_DEVICES) | 998 if (it->second->request.request_type != MEDIA_ENUMERATE_DEVICES) |
859 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 999 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
860 label_list.push_back(it->first); | 1000 label_list.push_back(it->first); |
861 } | 1001 } |
862 } | 1002 } |
863 for (std::list<std::string>::iterator it = label_list.begin(); | 1003 for (std::list<std::string>::iterator it = label_list.begin(); |
864 it != label_list.end(); ++it) { | 1004 it != label_list.end(); ++it) { |
865 DeviceRequest* request = requests_[*it]; | 1005 DeviceRequest* request = requests_[*it]; |
866 switch (request->request.request_type) { | 1006 switch (request->request.request_type) { |
867 case MEDIA_ENUMERATE_DEVICES: | 1007 case MEDIA_ENUMERATE_DEVICES: |
868 if (need_update_clients && request->requester) | 1008 if (need_update_clients && request->requester) { |
869 request->requester->DevicesEnumerated(*it, devices); | 1009 request->devices = devices; |
1010 FinalizeEnumerateDevices(*it, request); | |
1011 } | |
870 break; | 1012 break; |
871 default: | 1013 default: |
872 if (request->state(request->request.audio_type) == | 1014 if (request->state(request->request.audio_type) == |
873 MEDIA_REQUEST_STATE_REQUESTED || | 1015 MEDIA_REQUEST_STATE_REQUESTED || |
874 request->state(request->request.video_type) == | 1016 request->state(request->request.video_type) == |
875 MEDIA_REQUEST_STATE_REQUESTED) { | 1017 MEDIA_REQUEST_STATE_REQUESTED) { |
876 // We are doing enumeration for other type of media, wait until it is | 1018 // We are doing enumeration for other type of media, wait until it is |
877 // all done before posting the request to UI because UI needs | 1019 // all done before posting the request to UI because UI needs |
878 // the device lists to handle the request. | 1020 // the device lists to handle the request. |
879 break; | 1021 break; |
880 } | 1022 } |
881 | 1023 |
882 // Post the request to UI for permission approval. | 1024 // Continue to handle the request. |
883 PostRequestToUI(*it); | 1025 HandleRequest(*it); |
884 break; | 1026 break; |
885 } | 1027 } |
886 } | 1028 } |
887 label_list.clear(); | 1029 label_list.clear(); |
888 --active_enumeration_ref_count_[stream_type]; | 1030 --active_enumeration_ref_count_[stream_type]; |
889 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 1031 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
890 } | 1032 } |
891 | 1033 |
892 void MediaStreamManager::Error(MediaStreamType stream_type, | |
893 int capture_session_id, | |
894 MediaStreamProviderError error) { | |
895 // Find the device for the error call. | |
896 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
897 DVLOG(1) << "Error(" | |
898 << "{stream_type = " << stream_type << "} ," | |
899 << "{capture_session_id = " << capture_session_id << "})"; | |
900 | |
901 | |
902 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | |
903 ++it) { | |
904 StreamDeviceInfoArray& devices = it->second->devices; | |
905 | |
906 // TODO(miu): BUG. It's possible for the audio (or video) device array in | |
907 // the "requester" to become out-of-sync with the order of devices we have | |
908 // here. See http://crbug.com/147650 | |
909 int audio_device_idx = -1; | |
910 int video_device_idx = -1; | |
911 for (StreamDeviceInfoArray::iterator device_it = devices.begin(); | |
912 device_it != devices.end(); ++device_it) { | |
913 if (IsAudioMediaType(device_it->device.type)) { | |
914 ++audio_device_idx; | |
915 } else if (IsVideoMediaType(device_it->device.type)) { | |
916 ++video_device_idx; | |
917 } else { | |
918 NOTREACHED(); | |
919 continue; | |
920 } | |
921 if (device_it->device.type != stream_type || | |
922 device_it->session_id != capture_session_id) { | |
923 continue; | |
924 } | |
925 // We've found the failing device. Find the error case: | |
926 // An error should only be reported to the MediaStreamManager if | |
927 // the request has not been fulfilled yet. | |
928 DCHECK(it->second->state(stream_type) != MEDIA_REQUEST_STATE_DONE); | |
929 if (it->second->state(stream_type) != MEDIA_REQUEST_STATE_DONE) { | |
930 // Request is not done, devices are not opened in this case. | |
931 if (devices.size() <= 1) { | |
932 scoped_ptr<DeviceRequest> request(it->second); | |
933 // 1. Device not opened and no other devices for this request -> | |
934 // signal stream error and remove the request. | |
935 if (request->requester) | |
936 request->requester->StreamGenerationFailed(it->first); | |
937 | |
938 RemoveRequest(it); | |
939 } else { | |
940 // 2. Not opened but other devices exists for this request -> remove | |
941 // device from list, but don't signal an error. | |
942 devices.erase(device_it); // NOTE: This invalidates device_it! | |
943 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_ERROR); | |
944 DVLOG(1) << "Error(" | |
945 << ", {capture_session_id = " << capture_session_id << "})"; | |
946 } | |
947 } | |
948 if (RequestDone(*it->second)) | |
949 HandleRequestDone(it->first, it->second); | |
950 break; | |
951 } | |
952 } | |
953 } | |
954 | |
955 void MediaStreamManager::HandleAccessRequestResponse( | 1034 void MediaStreamManager::HandleAccessRequestResponse( |
956 const std::string& label, | 1035 const std::string& label, |
957 const MediaStreamDevices& devices) { | 1036 const MediaStreamDevices& devices) { |
958 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1037 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
959 DVLOG(1) << "HandleAccessRequestResponse(" | 1038 DVLOG(1) << "HandleAccessRequestResponse(" |
960 << ", {label = " << label << "})"; | 1039 << ", {label = " << label << "})"; |
961 | 1040 |
962 DeviceRequests::iterator request_it = requests_.find(label); | 1041 DeviceRequests::iterator request_it = requests_.find(label); |
963 if (request_it == requests_.end()) { | 1042 if (request_it == requests_.end()) { |
964 return; | 1043 return; |
965 } | 1044 } |
966 | 1045 |
1046 DeviceRequest* request = request_it->second; | |
1047 if (request->request.request_type == MEDIA_DEVICE_ACCESS) { | |
1048 FinalizeMediaAccessRequest(label, devices); | |
1049 return; | |
1050 } | |
1051 | |
967 // Handle the case when the request was denied. | 1052 // Handle the case when the request was denied. |
968 if (devices.empty()) { | 1053 if (devices.empty()) { |
969 // Notify the users about the request result. | 1054 FinalizeRequestFailed(label); |
970 scoped_ptr<DeviceRequest> request(request_it->second); | |
971 if (request->requester) | |
972 request->requester->StreamGenerationFailed(label); | |
973 | |
974 if (request->request.request_type == MEDIA_DEVICE_ACCESS && | |
975 !request->callback.is_null()) { | |
976 request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass()); | |
977 } | |
978 | |
979 RemoveRequest(request_it); | |
980 return; | |
981 } | |
982 | |
983 if (request_it->second->request.request_type == MEDIA_DEVICE_ACCESS) { | |
984 scoped_ptr<DeviceRequest> request(request_it->second); | |
985 if (!request->callback.is_null()) | |
986 request->callback.Run(devices, request->ui_proxy.Pass()); | |
987 | |
988 // Delete the request since it is done. | |
989 RemoveRequest(request_it); | |
990 return; | 1055 return; |
991 } | 1056 } |
992 | 1057 |
993 // Process all newly-accepted devices for this request. | 1058 // Process all newly-accepted devices for this request. |
994 DeviceRequest* request = request_it->second; | |
995 bool found_audio = false; | 1059 bool found_audio = false; |
996 bool found_video = false; | 1060 bool found_video = false; |
997 for (MediaStreamDevices::const_iterator device_it = devices.begin(); | 1061 for (MediaStreamDevices::const_iterator device_it = devices.begin(); |
998 device_it != devices.end(); ++device_it) { | 1062 device_it != devices.end(); ++device_it) { |
999 StreamDeviceInfo device_info; | 1063 StreamDeviceInfo device_info; |
1000 device_info.device = *device_it; | 1064 device_info.device = *device_it; |
1001 | 1065 |
1002 // TODO(justinlin): Nicer way to do this? | 1066 // TODO(justinlin): Nicer way to do this? |
1003 // Re-append the device's id since we lost it when posting request to UI. | 1067 // Re-append the device's id since we lost it when posting request to UI. |
1004 if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE || | 1068 if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE || |
(...skipping 20 matching lines...) Expand all Loading... | |
1025 if (device_info.device.type == request->request.audio_type) { | 1089 if (device_info.device.type == request->request.audio_type) { |
1026 found_audio = true; | 1090 found_audio = true; |
1027 } else if (device_info.device.type == request->request.video_type) { | 1091 } else if (device_info.device.type == request->request.video_type) { |
1028 found_video = true; | 1092 found_video = true; |
1029 } | 1093 } |
1030 | 1094 |
1031 // If this is request for a new MediaStream, a device is only opened once | 1095 // If this is request for a new MediaStream, a device is only opened once |
1032 // per render view. This is so that the permission to use a device can be | 1096 // per render view. This is so that the permission to use a device can be |
1033 // revoked by a single call to StopStreamDevice regardless of how many | 1097 // revoked by a single call to StopStreamDevice regardless of how many |
1034 // MediaStreams it is being used in. | 1098 // MediaStreams it is being used in. |
1035 | |
1036 if (request->request.request_type == MEDIA_GENERATE_STREAM) { | 1099 if (request->request.request_type == MEDIA_GENERATE_STREAM) { |
1037 MediaRequestState state; | 1100 MediaRequestState state; |
1038 if (FindExistingRequestedDeviceInfo(request->request.render_process_id, | 1101 if (FindExistingRequestedDeviceInfo(request->request.render_process_id, |
1039 request->request.render_view_id, | 1102 request->request.render_view_id, |
1103 request->request.security_origin, | |
1040 request->request.request_type, | 1104 request->request.request_type, |
1041 device_it->id, | 1105 device_it->id, |
1042 &device_info, | 1106 &device_info, |
1043 &state)) { | 1107 &state)) { |
1044 request->devices.push_back(device_info); | 1108 request->devices.push_back(device_info); |
1045 request->SetState(device_info.device.type, state); | 1109 request->SetState(device_info.device.type, state); |
1046 DVLOG(1) << "HandleAccessRequestResponse - device already opened " | 1110 DVLOG(1) << "HandleAccessRequestResponse - device already opened " |
1047 << ", {label = " << label << "}" | 1111 << ", {label = " << label << "}" |
1048 << ", device_id = " << device_it->id << "}"; | 1112 << ", device_id = " << device_it->id << "}"; |
1049 continue; | 1113 continue; |
1050 } | 1114 } |
1051 } | 1115 } |
1052 device_info.session_id = | 1116 device_info.session_id = |
1053 GetDeviceManager(device_info.device.type)->Open(device_info); | 1117 GetDeviceManager(device_info.device.type)->Open(device_info); |
1118 MediaSourceIdFactory::GenerateSourceId( | |
1119 request->request.security_origin, | |
1120 device_it->id, | |
1121 &device_info.device.id); | |
1054 request->devices.push_back(device_info); | 1122 request->devices.push_back(device_info); |
1123 | |
1055 request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING); | 1124 request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING); |
1056 DVLOG(1) << "HandleAccessRequestResponse - opening device " | 1125 DVLOG(1) << "HandleAccessRequestResponse - opening device " |
1057 << ", {label = " << label << "}" | 1126 << ", {label = " << label << "}" |
1058 << ", {device_id = " << device_it->id << "}" | 1127 << ", {device_id = " << device_it->id << "}" |
1059 << ", {session_id = " << device_info.session_id << "}"; | 1128 << ", {session_id = " << device_info.session_id << "}"; |
1060 } | 1129 } |
1061 | 1130 |
1062 // Check whether we've received all stream types requested. | 1131 // Check whether we've received all stream types requested. |
1063 if (!found_audio && IsAudioMediaType(request->request.audio_type)) { | 1132 if (!found_audio && IsAudioMediaType(request->request.audio_type)) { |
1064 request->SetState(request->request.audio_type, MEDIA_REQUEST_STATE_ERROR); | 1133 request->SetState(request->request.audio_type, MEDIA_REQUEST_STATE_ERROR); |
(...skipping 29 matching lines...) Expand all Loading... | |
1094 audio_input_device_manager()->UseFakeDevice(); | 1163 audio_input_device_manager()->UseFakeDevice(); |
1095 } | 1164 } |
1096 | 1165 |
1097 void MediaStreamManager::UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui) { | 1166 void MediaStreamManager::UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui) { |
1098 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
1099 use_fake_ui_ = true; | 1168 use_fake_ui_ = true; |
1100 fake_ui_ = fake_ui.Pass(); | 1169 fake_ui_ = fake_ui.Pass(); |
1101 } | 1170 } |
1102 | 1171 |
1103 void MediaStreamManager::WillDestroyCurrentMessageLoop() { | 1172 void MediaStreamManager::WillDestroyCurrentMessageLoop() { |
1173 DVLOG(3) << "MediaStreamManager::WillDestroyCurrentMessageLoop()"; | |
1104 DCHECK_EQ(base::MessageLoop::current(), io_loop_); | 1174 DCHECK_EQ(base::MessageLoop::current(), io_loop_); |
1105 DCHECK(requests_.empty()); | 1175 DCHECK(requests_.empty()); |
1106 if (device_thread_) { | 1176 if (device_thread_) { |
1107 StopMonitoring(); | 1177 StopMonitoring(); |
1108 | 1178 |
1109 video_capture_manager_->Unregister(); | 1179 video_capture_manager_->Unregister(); |
1110 audio_input_device_manager_->Unregister(); | 1180 audio_input_device_manager_->Unregister(); |
1111 device_thread_.reset(); | 1181 device_thread_.reset(); |
1112 } | 1182 } |
1113 | 1183 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1195 } | 1265 } |
1196 | 1266 |
1197 // Always do enumeration even though some enumeration is in progress, | 1267 // Always do enumeration even though some enumeration is in progress, |
1198 // because those enumeration commands could be sent before these devices | 1268 // because those enumeration commands could be sent before these devices |
1199 // change. | 1269 // change. |
1200 ++active_enumeration_ref_count_[stream_type]; | 1270 ++active_enumeration_ref_count_[stream_type]; |
1201 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); | 1271 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); |
1202 } | 1272 } |
1203 | 1273 |
1204 } // namespace content | 1274 } // namespace content |
OLD | NEW |