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" |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 } | 154 } |
155 } | 155 } |
156 return output_string; | 156 return output_string; |
157 } | 157 } |
158 | 158 |
159 // Needed for MediaStreamManager::GenerateStream below. | 159 // Needed for MediaStreamManager::GenerateStream below. |
160 std::string ReturnEmptySalt() { | 160 std::string ReturnEmptySalt() { |
161 return std::string(); | 161 return std::string(); |
162 } | 162 } |
163 | 163 |
| 164 // Clears the MediaStreamDevice.name from all devices in |devices|. |
| 165 static void ClearDeviceLabels(content::StreamDeviceInfoArray* devices) { |
| 166 for (content::StreamDeviceInfoArray::iterator device_itr = devices->begin(); |
| 167 device_itr != devices->end(); |
| 168 ++device_itr) { |
| 169 device_itr->device.name.clear(); |
| 170 } |
| 171 } |
| 172 |
164 } // namespace | 173 } // namespace |
165 | 174 |
166 | 175 |
167 // MediaStreamManager::DeviceRequest represents a request to either enumerate | 176 // MediaStreamManager::DeviceRequest represents a request to either enumerate |
168 // available devices or open one or more devices. | 177 // available devices or open one or more devices. |
169 // TODO(perkj): MediaStreamManager still needs refactoring. I propose we create | 178 // TODO(perkj): MediaStreamManager still needs refactoring. I propose we create |
170 // several subclasses of DeviceRequest and move some of the responsibility of | 179 // several subclasses of DeviceRequest and move some of the responsibility of |
171 // the MediaStreamManager to the subclasses to get rid of the way too many if | 180 // the MediaStreamManager to the subclasses to get rid of the way too many if |
172 // statements in MediaStreamManager. | 181 // statements in MediaStreamManager. |
173 class MediaStreamManager::DeviceRequest { | 182 class MediaStreamManager::DeviceRequest { |
174 public: | 183 public: |
175 DeviceRequest(MediaStreamRequester* requester, | 184 DeviceRequest(MediaStreamRequester* requester, |
176 int requesting_process_id, | 185 int requesting_process_id, |
177 int requesting_view_id, | 186 int requesting_view_id, |
178 int page_request_id, | 187 int page_request_id, |
179 const GURL& security_origin, | 188 const GURL& security_origin, |
| 189 bool have_permission, |
180 bool user_gesture, | 190 bool user_gesture, |
181 MediaStreamRequestType request_type, | 191 MediaStreamRequestType request_type, |
182 const StreamOptions& options, | 192 const StreamOptions& options, |
183 const ResourceContext::SaltCallback& salt_callback) | 193 const ResourceContext::SaltCallback& salt_callback) |
184 : requester(requester), | 194 : requester(requester), |
185 requesting_process_id(requesting_process_id), | 195 requesting_process_id(requesting_process_id), |
186 requesting_view_id(requesting_view_id), | 196 requesting_view_id(requesting_view_id), |
187 page_request_id(page_request_id), | 197 page_request_id(page_request_id), |
188 security_origin(security_origin), | 198 security_origin(security_origin), |
| 199 have_permission(have_permission), |
189 user_gesture(user_gesture), | 200 user_gesture(user_gesture), |
190 request_type(request_type), | 201 request_type(request_type), |
191 options(options), | 202 options(options), |
192 salt_callback(salt_callback), | 203 salt_callback(salt_callback), |
193 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), | 204 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), |
194 audio_type_(MEDIA_NO_SERVICE), | 205 audio_type_(MEDIA_NO_SERVICE), |
195 video_type_(MEDIA_NO_SERVICE) { | 206 video_type_(MEDIA_NO_SERVICE) { |
196 } | 207 } |
197 | 208 |
198 ~DeviceRequest() {} | 209 ~DeviceRequest() {} |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 // will receive a handle to the MediaStream. This may be different from | 311 // will receive a handle to the MediaStream. This may be different from |
301 // MediaStreamRequest::render_view_id which in the tab capture case | 312 // MediaStreamRequest::render_view_id which in the tab capture case |
302 // specifies the target renderer from which audio and video is captured. | 313 // specifies the target renderer from which audio and video is captured. |
303 const int requesting_view_id; | 314 const int requesting_view_id; |
304 | 315 |
305 // An ID the render view provided to identify this request. | 316 // An ID the render view provided to identify this request. |
306 const int page_request_id; | 317 const int page_request_id; |
307 | 318 |
308 const GURL security_origin; | 319 const GURL security_origin; |
309 | 320 |
| 321 // This is used when enumerating devices; if we don't have device access |
| 322 // permission, we remove the device label. |
| 323 bool have_permission; |
| 324 |
310 const bool user_gesture; | 325 const bool user_gesture; |
311 | 326 |
312 const MediaStreamRequestType request_type; | 327 const MediaStreamRequestType request_type; |
313 | 328 |
314 const StreamOptions options; | 329 const StreamOptions options; |
315 | 330 |
316 ResourceContext::SaltCallback salt_callback; | 331 ResourceContext::SaltCallback salt_callback; |
317 | 332 |
318 StreamDeviceInfoArray devices; | 333 StreamDeviceInfoArray devices; |
319 | 334 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 const MediaRequestResponseCallback& callback) { | 419 const MediaRequestResponseCallback& callback) { |
405 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 420 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
406 | 421 |
407 // TODO(perkj): The argument list with NULL parameters to DeviceRequest | 422 // TODO(perkj): The argument list with NULL parameters to DeviceRequest |
408 // suggests that this is the wrong design. Can this be refactored? | 423 // suggests that this is the wrong design. Can this be refactored? |
409 DeviceRequest* request = new DeviceRequest(NULL, | 424 DeviceRequest* request = new DeviceRequest(NULL, |
410 render_process_id, | 425 render_process_id, |
411 render_view_id, | 426 render_view_id, |
412 page_request_id, | 427 page_request_id, |
413 security_origin, | 428 security_origin, |
| 429 true, |
414 false, // user gesture | 430 false, // user gesture |
415 MEDIA_DEVICE_ACCESS, | 431 MEDIA_DEVICE_ACCESS, |
416 options, | 432 options, |
417 base::Bind(&ReturnEmptySalt)); | 433 base::Bind(&ReturnEmptySalt)); |
418 | 434 |
419 const std::string& label = AddRequest(request); | 435 const std::string& label = AddRequest(request); |
420 | 436 |
421 request->callback = callback; | 437 request->callback = callback; |
422 // Post a task and handle the request asynchronously. The reason is that the | 438 // Post a task and handle the request asynchronously. The reason is that the |
423 // requester won't have a label for the request until this function returns | 439 // requester won't have a label for the request until this function returns |
(...skipping 20 matching lines...) Expand all Loading... |
444 if (CommandLine::ForCurrentProcess()->HasSwitch( | 460 if (CommandLine::ForCurrentProcess()->HasSwitch( |
445 switches::kUseFakeUIForMediaStream)) { | 461 switches::kUseFakeUIForMediaStream)) { |
446 UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>()); | 462 UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>()); |
447 } | 463 } |
448 | 464 |
449 DeviceRequest* request = new DeviceRequest(requester, | 465 DeviceRequest* request = new DeviceRequest(requester, |
450 render_process_id, | 466 render_process_id, |
451 render_view_id, | 467 render_view_id, |
452 page_request_id, | 468 page_request_id, |
453 security_origin, | 469 security_origin, |
| 470 true, |
454 user_gesture, | 471 user_gesture, |
455 MEDIA_GENERATE_STREAM, | 472 MEDIA_GENERATE_STREAM, |
456 options, | 473 options, |
457 sc); | 474 sc); |
458 | 475 |
459 const std::string& label = AddRequest(request); | 476 const std::string& label = AddRequest(request); |
460 | 477 |
461 // Post a task and handle the request asynchronously. The reason is that the | 478 // Post a task and handle the request asynchronously. The reason is that the |
462 // requester won't have a label for the request until this function returns | 479 // requester won't have a label for the request until this function returns |
463 // and thus can not handle a response. Using base::Unretained is safe since | 480 // and thus can not handle a response. Using base::Unretained is safe since |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 } | 643 } |
627 } | 644 } |
628 | 645 |
629 std::string MediaStreamManager::EnumerateDevices( | 646 std::string MediaStreamManager::EnumerateDevices( |
630 MediaStreamRequester* requester, | 647 MediaStreamRequester* requester, |
631 int render_process_id, | 648 int render_process_id, |
632 int render_view_id, | 649 int render_view_id, |
633 const ResourceContext::SaltCallback& sc, | 650 const ResourceContext::SaltCallback& sc, |
634 int page_request_id, | 651 int page_request_id, |
635 MediaStreamType type, | 652 MediaStreamType type, |
636 const GURL& security_origin) { | 653 const GURL& security_origin, |
| 654 bool have_permission) { |
637 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 655 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
638 DCHECK(requester); | 656 DCHECK(requester); |
639 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 657 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
640 type == MEDIA_DEVICE_VIDEO_CAPTURE); | 658 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
641 | 659 |
642 DeviceRequest* request = new DeviceRequest(requester, | 660 DeviceRequest* request = new DeviceRequest(requester, |
643 render_process_id, | 661 render_process_id, |
644 render_view_id, | 662 render_view_id, |
645 page_request_id, | 663 page_request_id, |
646 security_origin, | 664 security_origin, |
| 665 have_permission, |
647 false, // user gesture | 666 false, // user gesture |
648 MEDIA_ENUMERATE_DEVICES, | 667 MEDIA_ENUMERATE_DEVICES, |
649 StreamOptions(), | 668 StreamOptions(), |
650 sc); | 669 sc); |
651 if (IsAudioMediaType(type)) | 670 if (IsAudioMediaType(type)) |
652 request->SetAudioType(type); | 671 request->SetAudioType(type); |
653 else if (IsVideoMediaType(type)) | 672 else if (IsVideoMediaType(type)) |
654 request->SetVideoType(type); | 673 request->SetVideoType(type); |
655 | 674 |
656 const std::string& label = AddRequest(request); | 675 const std::string& label = AddRequest(request); |
(...skipping 16 matching lines...) Expand all Loading... |
673 return; // This can happen if the request has been canceled. | 692 return; // This can happen if the request has been canceled. |
674 | 693 |
675 MediaStreamType type; | 694 MediaStreamType type; |
676 EnumerationCache* cache; | 695 EnumerationCache* cache; |
677 if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE) { | 696 if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE) { |
678 DCHECK_EQ(MEDIA_NO_SERVICE, request->video_type()); | 697 DCHECK_EQ(MEDIA_NO_SERVICE, request->video_type()); |
679 type = MEDIA_DEVICE_AUDIO_CAPTURE; | 698 type = MEDIA_DEVICE_AUDIO_CAPTURE; |
680 cache = &audio_enumeration_cache_; | 699 cache = &audio_enumeration_cache_; |
681 } else { | 700 } else { |
682 DCHECK_EQ(MEDIA_DEVICE_VIDEO_CAPTURE, request->video_type()); | 701 DCHECK_EQ(MEDIA_DEVICE_VIDEO_CAPTURE, request->video_type()); |
| 702 DCHECK_EQ(MEDIA_NO_SERVICE, request->audio_type()); |
683 type = MEDIA_DEVICE_VIDEO_CAPTURE; | 703 type = MEDIA_DEVICE_VIDEO_CAPTURE; |
684 cache = &video_enumeration_cache_; | 704 cache = &video_enumeration_cache_; |
685 } | 705 } |
686 | 706 |
687 if (!EnumerationRequired(cache, type)) { | 707 if (!EnumerationRequired(cache, type)) { |
688 // Cached device list of this type exists. Just send it out. | 708 // Cached device list of this type exists. Just send it out. |
689 request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED); | 709 request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED); |
690 request->devices = cache->devices; | 710 request->devices = cache->devices; |
691 FinalizeEnumerateDevices(label, request); | 711 FinalizeEnumerateDevices(label, request); |
692 } else { | 712 } else { |
(...skipping 24 matching lines...) Expand all Loading... |
717 options.mandatory_video.push_back( | 737 options.mandatory_video.push_back( |
718 StreamOptions::Constraint(kMediaStreamSourceInfoId, device_id)); | 738 StreamOptions::Constraint(kMediaStreamSourceInfoId, device_id)); |
719 } else { | 739 } else { |
720 NOTREACHED(); | 740 NOTREACHED(); |
721 } | 741 } |
722 DeviceRequest* request = new DeviceRequest(requester, | 742 DeviceRequest* request = new DeviceRequest(requester, |
723 render_process_id, | 743 render_process_id, |
724 render_view_id, | 744 render_view_id, |
725 page_request_id, | 745 page_request_id, |
726 security_origin, | 746 security_origin, |
| 747 true, |
727 false, // user gesture | 748 false, // user gesture |
728 MEDIA_OPEN_DEVICE, | 749 MEDIA_OPEN_DEVICE, |
729 options, | 750 options, |
730 sc); | 751 sc); |
731 | 752 |
732 const std::string& label = AddRequest(request); | 753 const std::string& label = AddRequest(request); |
733 // Post a task and handle the request asynchronously. The reason is that the | 754 // Post a task and handle the request asynchronously. The reason is that the |
734 // requester won't have a label for the request until this function returns | 755 // requester won't have a label for the request until this function returns |
735 // and thus can not handle a response. Using base::Unretained is safe since | 756 // and thus can not handle a response. Using base::Unretained is safe since |
736 // MediaStreamManager is deleted on the UI thread, after the IO thread has | 757 // MediaStreamManager is deleted on the UI thread, after the IO thread has |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1368 | 1389 |
1369 if (request->security_origin.is_valid()) { | 1390 if (request->security_origin.is_valid()) { |
1370 for (StreamDeviceInfoArray::iterator it = request->devices.begin(); | 1391 for (StreamDeviceInfoArray::iterator it = request->devices.begin(); |
1371 it != request->devices.end(); ++it) { | 1392 it != request->devices.end(); ++it) { |
1372 TranslateDeviceIdToSourceId(request, &it->device); | 1393 TranslateDeviceIdToSourceId(request, &it->device); |
1373 } | 1394 } |
1374 } else { | 1395 } else { |
1375 request->devices.clear(); | 1396 request->devices.clear(); |
1376 } | 1397 } |
1377 | 1398 |
| 1399 if (!request->have_permission) |
| 1400 ClearDeviceLabels(&request->devices); |
| 1401 |
1378 request->requester->DevicesEnumerated( | 1402 request->requester->DevicesEnumerated( |
1379 request->requesting_view_id, | 1403 request->requesting_view_id, |
1380 request->page_request_id, | 1404 request->page_request_id, |
1381 label, | 1405 label, |
1382 request->devices); | 1406 request->devices); |
1383 | 1407 |
1384 // TODO(tommi): | 1408 // TODO(tommi): |
1385 // Ideally enumeration requests should be deleted once they have been served | 1409 // Ideally enumeration requests should be deleted once they have been served |
1386 // (as any request). However, this implementation mixes requests and | 1410 // (as any request). However, this implementation mixes requests and |
1387 // notifications together so enumeration requests are kept open by some | 1411 // notifications together so enumeration requests are kept open by some |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1928 if (it->device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { | 1952 if (it->device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
1929 video_capture_manager_->SetDesktopCaptureWindowId(it->session_id, | 1953 video_capture_manager_->SetDesktopCaptureWindowId(it->session_id, |
1930 window_id); | 1954 window_id); |
1931 break; | 1955 break; |
1932 } | 1956 } |
1933 } | 1957 } |
1934 } | 1958 } |
1935 } | 1959 } |
1936 | 1960 |
1937 } // namespace content | 1961 } // namespace content |
OLD | NEW |