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 <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 #include <string.h> | 9 #include <string.h> |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 const StreamDeviceInfoArray& device_infos) { | 170 const StreamDeviceInfoArray& device_infos) { |
171 std::string output_string = | 171 std::string output_string = |
172 base::StringPrintf("Getting devices for stream type %d:\n", stream_type); | 172 base::StringPrintf("Getting devices for stream type %d:\n", stream_type); |
173 if (device_infos.empty()) | 173 if (device_infos.empty()) |
174 return output_string + "No devices found."; | 174 return output_string + "No devices found."; |
175 for (const content::StreamDeviceInfo& device_info : device_infos) | 175 for (const content::StreamDeviceInfo& device_info : device_infos) |
176 output_string += " " + device_info.device.name + "\n"; | 176 output_string += " " + device_info.device.name + "\n"; |
177 return output_string; | 177 return output_string; |
178 } | 178 } |
179 | 179 |
| 180 // Needed for MediaStreamManager::GenerateStream below. |
| 181 std::string ReturnEmptySalt() { |
| 182 return std::string(); |
| 183 } |
| 184 |
180 // Clears the MediaStreamDevice.name from all devices in |devices|. | 185 // Clears the MediaStreamDevice.name from all devices in |devices|. |
181 void ClearDeviceLabels(content::StreamDeviceInfoArray* devices) { | 186 void ClearDeviceLabels(content::StreamDeviceInfoArray* devices) { |
182 for (content::StreamDeviceInfo& device_info : *devices) | 187 for (content::StreamDeviceInfo& device_info : *devices) |
183 device_info.device.name.clear(); | 188 device_info.device.name.clear(); |
184 } | 189 } |
185 | 190 |
186 bool CalledOnIOThread() { | 191 bool CalledOnIOThread() { |
187 // Check if this function call is on the IO thread, except for unittests where | 192 // Check if this function call is on the IO thread, except for unittests where |
188 // an IO thread might not have been created. | 193 // an IO thread might not have been created. |
189 return BrowserThread::CurrentlyOn(BrowserThread::IO) || | 194 return BrowserThread::CurrentlyOn(BrowserThread::IO) || |
(...skipping 16 matching lines...) Expand all Loading... |
206 class MediaStreamManager::DeviceRequest { | 211 class MediaStreamManager::DeviceRequest { |
207 public: | 212 public: |
208 DeviceRequest(MediaStreamRequester* requester, | 213 DeviceRequest(MediaStreamRequester* requester, |
209 int requesting_process_id, | 214 int requesting_process_id, |
210 int requesting_frame_id, | 215 int requesting_frame_id, |
211 int page_request_id, | 216 int page_request_id, |
212 const url::Origin& security_origin, | 217 const url::Origin& security_origin, |
213 bool user_gesture, | 218 bool user_gesture, |
214 MediaStreamRequestType request_type, | 219 MediaStreamRequestType request_type, |
215 const StreamControls& controls, | 220 const StreamControls& controls, |
216 const std::string& salt) | 221 const ResourceContext::SaltCallback& salt_callback) |
217 : requester(requester), | 222 : requester(requester), |
218 requesting_process_id(requesting_process_id), | 223 requesting_process_id(requesting_process_id), |
219 requesting_frame_id(requesting_frame_id), | 224 requesting_frame_id(requesting_frame_id), |
220 page_request_id(page_request_id), | 225 page_request_id(page_request_id), |
221 security_origin(security_origin), | 226 security_origin(security_origin), |
222 user_gesture(user_gesture), | 227 user_gesture(user_gesture), |
223 request_type(request_type), | 228 request_type(request_type), |
224 controls(controls), | 229 controls(controls), |
225 salt(salt), | 230 salt_callback(salt_callback), |
226 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), | 231 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), |
227 audio_type_(MEDIA_NO_SERVICE), | 232 audio_type_(MEDIA_NO_SERVICE), |
228 video_type_(MEDIA_NO_SERVICE), | 233 video_type_(MEDIA_NO_SERVICE), |
229 target_process_id_(-1), | 234 target_process_id_(-1), |
230 target_frame_id_(-1) {} | 235 target_frame_id_(-1) {} |
231 | 236 |
232 ~DeviceRequest() {} | 237 ~DeviceRequest() {} |
233 | 238 |
234 void SetAudioType(MediaStreamType audio_type) { | 239 void SetAudioType(MediaStreamType audio_type) { |
235 DCHECK(IsAudioInputMediaType(audio_type) || | 240 DCHECK(IsAudioInputMediaType(audio_type) || |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 const int page_request_id; | 339 const int page_request_id; |
335 | 340 |
336 const url::Origin security_origin; | 341 const url::Origin security_origin; |
337 | 342 |
338 const bool user_gesture; | 343 const bool user_gesture; |
339 | 344 |
340 const MediaStreamRequestType request_type; | 345 const MediaStreamRequestType request_type; |
341 | 346 |
342 const StreamControls controls; | 347 const StreamControls controls; |
343 | 348 |
344 const std::string salt; | 349 ResourceContext::SaltCallback salt_callback; |
345 | 350 |
346 StreamDeviceInfoArray devices; | 351 StreamDeviceInfoArray devices; |
347 | 352 |
348 // Callback to the requester which audio/video devices have been selected. | 353 // Callback to the requester which audio/video devices have been selected. |
349 // It can be null if the requester has no interest to know the result. | 354 // It can be null if the requester has no interest to know the result. |
350 // Currently it is only used by |DEVICE_ACCESS| type. | 355 // Currently it is only used by |DEVICE_ACCESS| type. |
351 MediaStreamManager::MediaRequestResponseCallback callback; | 356 MediaStreamManager::MediaRequestResponseCallback callback; |
352 | 357 |
353 std::unique_ptr<MediaStreamUIProxy> ui_proxy; | 358 std::unique_ptr<MediaStreamUIProxy> ui_proxy; |
354 | 359 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 int render_process_id, | 459 int render_process_id, |
455 int render_frame_id, | 460 int render_frame_id, |
456 int page_request_id, | 461 int page_request_id, |
457 const StreamControls& controls, | 462 const StreamControls& controls, |
458 const url::Origin& security_origin, | 463 const url::Origin& security_origin, |
459 const MediaRequestResponseCallback& callback) { | 464 const MediaRequestResponseCallback& callback) { |
460 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 465 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
461 | 466 |
462 // TODO(perkj): The argument list with NULL parameters to DeviceRequest | 467 // TODO(perkj): The argument list with NULL parameters to DeviceRequest |
463 // suggests that this is the wrong design. Can this be refactored? | 468 // suggests that this is the wrong design. Can this be refactored? |
464 DeviceRequest* request = | 469 DeviceRequest* request = new DeviceRequest( |
465 new DeviceRequest(NULL, render_process_id, render_frame_id, | 470 NULL, render_process_id, render_frame_id, page_request_id, |
466 page_request_id, security_origin, | 471 security_origin, |
467 false, // user gesture | 472 false, // user gesture |
468 MEDIA_DEVICE_ACCESS, controls, std::string()); | 473 MEDIA_DEVICE_ACCESS, controls, base::Bind(&ReturnEmptySalt)); |
469 | 474 |
470 const std::string& label = AddRequest(request); | 475 const std::string& label = AddRequest(request); |
471 | 476 |
472 request->callback = callback; | 477 request->callback = callback; |
473 // 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 |
474 // 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 |
475 // 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 |
476 // MediaStreamManager is deleted on the UI thread, after the IO thread has | 481 // MediaStreamManager is deleted on the UI thread, after the IO thread has |
477 // been stopped. | 482 // been stopped. |
478 BrowserThread::PostTask( | 483 BrowserThread::PostTask( |
479 BrowserThread::IO, FROM_HERE, | 484 BrowserThread::IO, FROM_HERE, |
480 base::Bind(&MediaStreamManager::SetupRequest, | 485 base::Bind(&MediaStreamManager::SetupRequest, |
481 base::Unretained(this), label)); | 486 base::Unretained(this), label)); |
482 return label; | 487 return label; |
483 } | 488 } |
484 | 489 |
485 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, | 490 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, |
486 int render_process_id, | 491 int render_process_id, |
487 int render_frame_id, | 492 int render_frame_id, |
488 const std::string& salt, | 493 const ResourceContext::SaltCallback& sc, |
489 int page_request_id, | 494 int page_request_id, |
490 const StreamControls& controls, | 495 const StreamControls& controls, |
491 const url::Origin& security_origin, | 496 const url::Origin& security_origin, |
492 bool user_gesture) { | 497 bool user_gesture) { |
493 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 498 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
494 DVLOG(1) << "GenerateStream()"; | 499 DVLOG(1) << "GenerateStream()"; |
495 | 500 |
496 DeviceRequest* request = new DeviceRequest( | 501 DeviceRequest* request = new DeviceRequest( |
497 requester, render_process_id, render_frame_id, page_request_id, | 502 requester, render_process_id, render_frame_id, page_request_id, |
498 security_origin, user_gesture, MEDIA_GENERATE_STREAM, controls, salt); | 503 security_origin, user_gesture, MEDIA_GENERATE_STREAM, controls, sc); |
499 | 504 |
500 const std::string& label = AddRequest(request); | 505 const std::string& label = AddRequest(request); |
501 | 506 |
502 // Post a task and handle the request asynchronously. The reason is that the | 507 // Post a task and handle the request asynchronously. The reason is that the |
503 // requester won't have a label for the request until this function returns | 508 // requester won't have a label for the request until this function returns |
504 // and thus can not handle a response. Using base::Unretained is safe since | 509 // and thus can not handle a response. Using base::Unretained is safe since |
505 // MediaStreamManager is deleted on the UI thread, after the IO thread has | 510 // MediaStreamManager is deleted on the UI thread, after the IO thread has |
506 // been stopped. | 511 // been stopped. |
507 BrowserThread::PostTask( | 512 BrowserThread::PostTask( |
508 BrowserThread::IO, FROM_HERE, | 513 BrowserThread::IO, FROM_HERE, |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 request->SetState(type, MEDIA_REQUEST_STATE_CLOSING); | 678 request->SetState(type, MEDIA_REQUEST_STATE_CLOSING); |
674 } | 679 } |
675 } | 680 } |
676 } | 681 } |
677 } | 682 } |
678 | 683 |
679 std::string MediaStreamManager::EnumerateDevices( | 684 std::string MediaStreamManager::EnumerateDevices( |
680 MediaStreamRequester* requester, | 685 MediaStreamRequester* requester, |
681 int render_process_id, | 686 int render_process_id, |
682 int render_frame_id, | 687 int render_frame_id, |
683 const std::string& salt, | 688 const ResourceContext::SaltCallback& sc, |
684 int page_request_id, | 689 int page_request_id, |
685 MediaStreamType type, | 690 MediaStreamType type, |
686 const url::Origin& security_origin) { | 691 const url::Origin& security_origin) { |
687 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 692 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
688 DCHECK(requester); | 693 DCHECK(requester); |
689 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 694 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
690 type == MEDIA_DEVICE_VIDEO_CAPTURE || | 695 type == MEDIA_DEVICE_VIDEO_CAPTURE || |
691 type == MEDIA_DEVICE_AUDIO_OUTPUT); | 696 type == MEDIA_DEVICE_AUDIO_OUTPUT); |
692 | 697 |
693 DeviceRequest* request = | 698 DeviceRequest* request = |
694 new DeviceRequest(requester, render_process_id, render_frame_id, | 699 new DeviceRequest(requester, render_process_id, render_frame_id, |
695 page_request_id, security_origin, | 700 page_request_id, security_origin, |
696 false, // user gesture | 701 false, // user gesture |
697 MEDIA_ENUMERATE_DEVICES, StreamControls(), salt); | 702 MEDIA_ENUMERATE_DEVICES, StreamControls(), sc); |
698 if (IsAudioInputMediaType(type) || type == MEDIA_DEVICE_AUDIO_OUTPUT) | 703 if (IsAudioInputMediaType(type) || type == MEDIA_DEVICE_AUDIO_OUTPUT) |
699 request->SetAudioType(type); | 704 request->SetAudioType(type); |
700 else if (IsVideoMediaType(type)) | 705 else if (IsVideoMediaType(type)) |
701 request->SetVideoType(type); | 706 request->SetVideoType(type); |
702 | 707 |
703 const std::string& label = AddRequest(request); | 708 const std::string& label = AddRequest(request); |
704 // Post a task and handle the request asynchronously. The reason is that the | 709 // Post a task and handle the request asynchronously. The reason is that the |
705 // requester won't have a label for the request until this function returns | 710 // requester won't have a label for the request until this function returns |
706 // and thus can not handle a response. Using base::Unretained is safe since | 711 // and thus can not handle a response. Using base::Unretained is safe since |
707 // MediaStreamManager is deleted on the UI thread, after the IO thread has | 712 // MediaStreamManager is deleted on the UI thread, after the IO thread has |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 } | 794 } |
790 } | 795 } |
791 | 796 |
792 --active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT]; | 797 --active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT]; |
793 DCHECK_GE(active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT], 0); | 798 DCHECK_GE(active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT], 0); |
794 } | 799 } |
795 | 800 |
796 void MediaStreamManager::OpenDevice(MediaStreamRequester* requester, | 801 void MediaStreamManager::OpenDevice(MediaStreamRequester* requester, |
797 int render_process_id, | 802 int render_process_id, |
798 int render_frame_id, | 803 int render_frame_id, |
799 const std::string& salt, | 804 const ResourceContext::SaltCallback& sc, |
800 int page_request_id, | 805 int page_request_id, |
801 const std::string& device_id, | 806 const std::string& device_id, |
802 MediaStreamType type, | 807 MediaStreamType type, |
803 const url::Origin& security_origin) { | 808 const url::Origin& security_origin) { |
804 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 809 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
805 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 810 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
806 type == MEDIA_DEVICE_VIDEO_CAPTURE); | 811 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
807 DVLOG(1) << "OpenDevice ({page_request_id = " << page_request_id << "})"; | 812 DVLOG(1) << "OpenDevice ({page_request_id = " << page_request_id << "})"; |
808 StreamControls controls; | 813 StreamControls controls; |
809 if (IsAudioInputMediaType(type)) { | 814 if (IsAudioInputMediaType(type)) { |
810 controls.audio.requested = true; | 815 controls.audio.requested = true; |
811 controls.audio.device_ids.push_back(device_id); | 816 controls.audio.device_ids.push_back(device_id); |
812 } else if (IsVideoMediaType(type)) { | 817 } else if (IsVideoMediaType(type)) { |
813 controls.video.requested = true; | 818 controls.video.requested = true; |
814 controls.video.device_ids.push_back(device_id); | 819 controls.video.device_ids.push_back(device_id); |
815 } else { | 820 } else { |
816 NOTREACHED(); | 821 NOTREACHED(); |
817 } | 822 } |
818 DeviceRequest* request = | 823 DeviceRequest* request = |
819 new DeviceRequest(requester, render_process_id, render_frame_id, | 824 new DeviceRequest(requester, render_process_id, render_frame_id, |
820 page_request_id, security_origin, | 825 page_request_id, security_origin, |
821 false, // user gesture | 826 false, // user gesture |
822 MEDIA_OPEN_DEVICE_PEPPER_ONLY, controls, salt); | 827 MEDIA_OPEN_DEVICE_PEPPER_ONLY, controls, sc); |
823 | 828 |
824 const std::string& label = AddRequest(request); | 829 const std::string& label = AddRequest(request); |
825 // Post a task and handle the request asynchronously. The reason is that the | 830 // Post a task and handle the request asynchronously. The reason is that the |
826 // requester won't have a label for the request until this function returns | 831 // requester won't have a label for the request until this function returns |
827 // and thus can not handle a response. Using base::Unretained is safe since | 832 // and thus can not handle a response. Using base::Unretained is safe since |
828 // MediaStreamManager is deleted on the UI thread, after the IO thread has | 833 // MediaStreamManager is deleted on the UI thread, after the IO thread has |
829 // been stopped. | 834 // been stopped. |
830 BrowserThread::PostTask( | 835 BrowserThread::PostTask( |
831 BrowserThread::IO, FROM_HERE, | 836 BrowserThread::IO, FROM_HERE, |
832 base::Bind(&MediaStreamManager::SetupRequest, | 837 base::Bind(&MediaStreamManager::SetupRequest, |
833 base::Unretained(this), label)); | 838 base::Unretained(this), label)); |
834 } | 839 } |
835 | 840 |
836 bool MediaStreamManager::TranslateSourceIdToDeviceId( | 841 bool MediaStreamManager::TranslateSourceIdToDeviceId( |
837 MediaStreamType stream_type, | 842 MediaStreamType stream_type, |
838 const std::string& salt, | 843 const ResourceContext::SaltCallback& sc, |
839 const url::Origin& security_origin, | 844 const url::Origin& security_origin, |
840 const std::string& source_id, | 845 const std::string& source_id, |
841 std::string* device_id) const { | 846 std::string* device_id) const { |
842 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || | 847 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || |
843 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); | 848 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); |
844 // The source_id can be empty if the constraint is set but empty. | 849 // The source_id can be empty if the constraint is set but empty. |
845 if (source_id.empty()) | 850 if (source_id.empty()) |
846 return false; | 851 return false; |
847 | 852 |
848 const EnumerationCache* cache = | 853 const EnumerationCache* cache = |
849 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | 854 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? |
850 &audio_enumeration_cache_ : &video_enumeration_cache_; | 855 &audio_enumeration_cache_ : &video_enumeration_cache_; |
851 | 856 |
852 // If device monitoring hasn't started, the |device_guid| is not valid. | 857 // If device monitoring hasn't started, the |device_guid| is not valid. |
853 if (!cache->valid) | 858 if (!cache->valid) |
854 return false; | 859 return false; |
855 | 860 |
856 for (const StreamDeviceInfo& device_info : cache->devices) { | 861 for (const StreamDeviceInfo& device_info : cache->devices) { |
857 if (DoesMediaDeviceIDMatchHMAC(salt, security_origin, source_id, | 862 if (DoesMediaDeviceIDMatchHMAC(sc, security_origin, source_id, |
858 device_info.device.id)) { | 863 device_info.device.id)) { |
859 *device_id = device_info.device.id; | 864 *device_id = device_info.device.id; |
860 return true; | 865 return true; |
861 } | 866 } |
862 } | 867 } |
863 return false; | 868 return false; |
864 } | 869 } |
865 | 870 |
866 void MediaStreamManager::EnsureDeviceMonitorStarted() { | 871 void MediaStreamManager::EnsureDeviceMonitorStarted() { |
867 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 872 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
(...skipping 22 matching lines...) Expand all Loading... |
890 } | 895 } |
891 } | 896 } |
892 } | 897 } |
893 | 898 |
894 void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) { | 899 void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) { |
895 std::vector<int> session_ids; | 900 std::vector<int> session_ids; |
896 for (const LabeledDeviceRequest& labeled_request : requests_) { | 901 for (const LabeledDeviceRequest& labeled_request : requests_) { |
897 const DeviceRequest* request = labeled_request.second; | 902 const DeviceRequest* request = labeled_request.second; |
898 for (const StreamDeviceInfo& device_info : request->devices) { | 903 for (const StreamDeviceInfo& device_info : request->devices) { |
899 const std::string source_id = GetHMACForMediaDeviceID( | 904 const std::string source_id = GetHMACForMediaDeviceID( |
900 request->salt, request->security_origin, device.id); | 905 request->salt_callback, request->security_origin, device.id); |
901 if (device_info.device.id == source_id && | 906 if (device_info.device.id == source_id && |
902 device_info.device.type == device.type) { | 907 device_info.device.type == device.type) { |
903 session_ids.push_back(device_info.session_id); | 908 session_ids.push_back(device_info.session_id); |
904 if (labeled_request.second->requester) { | 909 if (labeled_request.second->requester) { |
905 labeled_request.second->requester->DeviceStopped( | 910 labeled_request.second->requester->DeviceStopped( |
906 labeled_request.second->requesting_frame_id, | 911 labeled_request.second->requesting_frame_id, |
907 labeled_request.first, device_info); | 912 labeled_request.first, device_info); |
908 } | 913 } |
909 } | 914 } |
910 } | 915 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 // fixed. | 984 // fixed. |
980 tracked_objects::ScopedTracker tracking_profile3( | 985 tracked_objects::ScopedTracker tracking_profile3( |
981 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 986 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
982 "458404 MediaStreamManager::DeviceMonitorMac::StartMonitoring")); | 987 "458404 MediaStreamManager::DeviceMonitorMac::StartMonitoring")); |
983 browser_main_loop->device_monitor_mac()->StartMonitoring(task_runner); | 988 browser_main_loop->device_monitor_mac()->StartMonitoring(task_runner); |
984 } | 989 } |
985 #endif | 990 #endif |
986 | 991 |
987 // Pick the first valid (translatable) device ID from lists of required | 992 // Pick the first valid (translatable) device ID from lists of required |
988 // and optional IDs. | 993 // and optional IDs. |
989 bool MediaStreamManager::PickDeviceId(MediaStreamType type, | 994 bool MediaStreamManager::PickDeviceId( |
990 const std::string& salt, | 995 MediaStreamType type, |
991 const url::Origin& security_origin, | 996 const ResourceContext::SaltCallback& salt_callback, |
992 const TrackControls& controls, | 997 const url::Origin& security_origin, |
993 std::string* device_id) const { | 998 const TrackControls& controls, |
| 999 std::string* device_id) const { |
994 if (!controls.device_ids.empty()) { | 1000 if (!controls.device_ids.empty()) { |
995 if (controls.device_ids.size() > 1) { | 1001 if (controls.device_ids.size() > 1) { |
996 LOG(ERROR) << "Only one required device ID is supported"; | 1002 LOG(ERROR) << "Only one required device ID is supported"; |
997 return false; | 1003 return false; |
998 } | 1004 } |
999 const std::string& candidate_id = controls.device_ids[0]; | 1005 const std::string& candidate_id = controls.device_ids[0]; |
1000 if (!TranslateSourceIdToDeviceId(type, salt, security_origin, candidate_id, | 1006 if (!TranslateSourceIdToDeviceId(type, salt_callback, security_origin, |
1001 device_id)) { | 1007 candidate_id, device_id)) { |
1002 LOG(WARNING) << "Invalid mandatory capture ID = " << candidate_id; | 1008 LOG(WARNING) << "Invalid mandatory capture ID = " << candidate_id; |
1003 return false; | 1009 return false; |
1004 } | 1010 } |
1005 return true; | 1011 return true; |
1006 } | 1012 } |
1007 // We don't have a required ID. Look at the alternates. | 1013 // We don't have a required ID. Look at the alternates. |
1008 for (const std::string& candidate_id : controls.alternate_device_ids) { | 1014 for (const std::string& candidate_id : controls.alternate_device_ids) { |
1009 if (TranslateSourceIdToDeviceId(type, salt, security_origin, candidate_id, | 1015 if (TranslateSourceIdToDeviceId(type, salt_callback, security_origin, |
1010 device_id)) { | 1016 candidate_id, device_id)) { |
1011 return true; | 1017 return true; |
1012 } else { | 1018 } else { |
1013 LOG(WARNING) << "Invalid optional capture ID = " << candidate_id; | 1019 LOG(WARNING) << "Invalid optional capture ID = " << candidate_id; |
1014 } | 1020 } |
1015 } | 1021 } |
1016 return true; // If we get here, device_id is empty. | 1022 return true; // If we get here, device_id is empty. |
1017 } | 1023 } |
1018 | 1024 |
1019 bool MediaStreamManager::GetRequestedDeviceCaptureId( | 1025 bool MediaStreamManager::GetRequestedDeviceCaptureId( |
1020 const DeviceRequest* request, | 1026 const DeviceRequest* request, |
1021 MediaStreamType type, | 1027 MediaStreamType type, |
1022 std::string* device_id) const { | 1028 std::string* device_id) const { |
1023 if (type == MEDIA_DEVICE_AUDIO_CAPTURE) { | 1029 if (type == MEDIA_DEVICE_AUDIO_CAPTURE) { |
1024 return PickDeviceId(type, request->salt, request->security_origin, | 1030 return PickDeviceId(type, request->salt_callback, request->security_origin, |
1025 request->controls.audio, device_id); | 1031 request->controls.audio, |
| 1032 device_id); |
1026 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { | 1033 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { |
1027 return PickDeviceId(type, request->salt, request->security_origin, | 1034 return PickDeviceId(type, request->salt_callback, request->security_origin, |
1028 request->controls.video, device_id); | 1035 request->controls.video, |
| 1036 device_id); |
1029 } else { | 1037 } else { |
1030 NOTREACHED(); | 1038 NOTREACHED(); |
1031 } | 1039 } |
1032 return false; | 1040 return false; |
1033 } | 1041 } |
1034 | 1042 |
1035 void MediaStreamManager::TranslateDeviceIdToSourceId( | 1043 void MediaStreamManager::TranslateDeviceIdToSourceId( |
1036 DeviceRequest* request, | 1044 DeviceRequest* request, |
1037 MediaStreamDevice* device) { | 1045 MediaStreamDevice* device) { |
1038 if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || | 1046 if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || |
1039 request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT || | 1047 request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT || |
1040 request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE) { | 1048 request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE) { |
1041 device->id = GetHMACForMediaDeviceID(request->salt, | 1049 device->id = GetHMACForMediaDeviceID(request->salt_callback, |
1042 request->security_origin, device->id); | 1050 request->security_origin, device->id); |
1043 } | 1051 } |
1044 } | 1052 } |
1045 | 1053 |
1046 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | 1054 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { |
1047 DCHECK(CalledOnIOThread()); | 1055 DCHECK(CalledOnIOThread()); |
1048 cache->valid = false; | 1056 cache->valid = false; |
1049 } | 1057 } |
1050 | 1058 |
1051 bool MediaStreamManager::EnumerationRequired(EnumerationCache* cache, | 1059 bool MediaStreamManager::EnumerationRequired(EnumerationCache* cache, |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 } | 1381 } |
1374 | 1382 |
1375 bool MediaStreamManager::FindExistingRequestedDeviceInfo( | 1383 bool MediaStreamManager::FindExistingRequestedDeviceInfo( |
1376 const DeviceRequest& new_request, | 1384 const DeviceRequest& new_request, |
1377 const MediaStreamDevice& new_device_info, | 1385 const MediaStreamDevice& new_device_info, |
1378 StreamDeviceInfo* existing_device_info, | 1386 StreamDeviceInfo* existing_device_info, |
1379 MediaRequestState* existing_request_state) const { | 1387 MediaRequestState* existing_request_state) const { |
1380 DCHECK(existing_device_info); | 1388 DCHECK(existing_device_info); |
1381 DCHECK(existing_request_state); | 1389 DCHECK(existing_request_state); |
1382 | 1390 |
1383 std::string source_id = GetHMACForMediaDeviceID( | 1391 std::string source_id = |
1384 new_request.salt, new_request.security_origin, new_device_info.id); | 1392 GetHMACForMediaDeviceID(new_request.salt_callback, |
| 1393 new_request.security_origin, new_device_info.id); |
1385 | 1394 |
1386 for (const LabeledDeviceRequest& labeled_request : requests_) { | 1395 for (const LabeledDeviceRequest& labeled_request : requests_) { |
1387 const DeviceRequest* request = labeled_request.second; | 1396 const DeviceRequest* request = labeled_request.second; |
1388 if (request->requesting_process_id == new_request.requesting_process_id && | 1397 if (request->requesting_process_id == new_request.requesting_process_id && |
1389 request->requesting_frame_id == new_request.requesting_frame_id && | 1398 request->requesting_frame_id == new_request.requesting_frame_id && |
1390 request->request_type == new_request.request_type) { | 1399 request->request_type == new_request.request_type) { |
1391 for (const StreamDeviceInfo& device_info : request->devices) { | 1400 for (const StreamDeviceInfo& device_info : request->devices) { |
1392 if (device_info.device.id == source_id && | 1401 if (device_info.device.id == source_id && |
1393 device_info.device.type == new_device_info.type) { | 1402 device_info.device.type == new_device_info.type) { |
1394 *existing_device_info = device_info; | 1403 *existing_device_info = device_info; |
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2117 } | 2126 } |
2118 | 2127 |
2119 void MediaStreamManager::NotifyDeviceChangeSubscribers(MediaStreamType type) { | 2128 void MediaStreamManager::NotifyDeviceChangeSubscribers(MediaStreamType type) { |
2120 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 2129 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
2121 for (auto* subscriber : device_change_subscribers_) | 2130 for (auto* subscriber : device_change_subscribers_) |
2122 subscriber->DevicesChanged(type); | 2131 subscriber->DevicesChanged(type); |
2123 } | 2132 } |
2124 | 2133 |
2125 // static | 2134 // static |
2126 std::string MediaStreamManager::GetHMACForMediaDeviceID( | 2135 std::string MediaStreamManager::GetHMACForMediaDeviceID( |
2127 const std::string& salt, | 2136 const ResourceContext::SaltCallback& sc, |
2128 const url::Origin& security_origin, | 2137 const url::Origin& security_origin, |
2129 const std::string& raw_unique_id) { | 2138 const std::string& raw_unique_id) { |
2130 DCHECK(!raw_unique_id.empty()); | 2139 DCHECK(!raw_unique_id.empty()); |
2131 if (raw_unique_id == media::AudioDeviceDescription::kDefaultDeviceId || | 2140 if (raw_unique_id == media::AudioDeviceDescription::kDefaultDeviceId || |
2132 raw_unique_id == media::AudioDeviceDescription::kCommunicationsDeviceId) { | 2141 raw_unique_id == media::AudioDeviceDescription::kCommunicationsDeviceId) { |
2133 return raw_unique_id; | 2142 return raw_unique_id; |
2134 } | 2143 } |
2135 | 2144 |
2136 crypto::HMAC hmac(crypto::HMAC::SHA256); | 2145 crypto::HMAC hmac(crypto::HMAC::SHA256); |
2137 const size_t digest_length = hmac.DigestLength(); | 2146 const size_t digest_length = hmac.DigestLength(); |
2138 std::vector<uint8_t> digest(digest_length); | 2147 std::vector<uint8_t> digest(digest_length); |
| 2148 std::string salt = sc.Run(); |
2139 bool result = hmac.Init(security_origin.Serialize()) && | 2149 bool result = hmac.Init(security_origin.Serialize()) && |
2140 hmac.Sign(raw_unique_id + salt, &digest[0], digest.size()); | 2150 hmac.Sign(raw_unique_id + salt, &digest[0], digest.size()); |
2141 DCHECK(result); | 2151 DCHECK(result); |
2142 return base::ToLowerASCII(base::HexEncode(&digest[0], digest.size())); | 2152 return base::ToLowerASCII(base::HexEncode(&digest[0], digest.size())); |
2143 } | 2153 } |
2144 | 2154 |
2145 // static | 2155 // static |
2146 bool MediaStreamManager::DoesMediaDeviceIDMatchHMAC( | 2156 bool MediaStreamManager::DoesMediaDeviceIDMatchHMAC( |
2147 const std::string& salt, | 2157 const ResourceContext::SaltCallback& sc, |
2148 const url::Origin& security_origin, | 2158 const url::Origin& security_origin, |
2149 const std::string& device_guid, | 2159 const std::string& device_guid, |
2150 const std::string& raw_unique_id) { | 2160 const std::string& raw_unique_id) { |
2151 DCHECK(!raw_unique_id.empty()); | 2161 DCHECK(!raw_unique_id.empty()); |
2152 std::string guid_from_raw_device_id = | 2162 std::string guid_from_raw_device_id = |
2153 GetHMACForMediaDeviceID(salt, security_origin, raw_unique_id); | 2163 GetHMACForMediaDeviceID(sc, security_origin, raw_unique_id); |
2154 return guid_from_raw_device_id == device_guid; | 2164 return guid_from_raw_device_id == device_guid; |
2155 } | 2165 } |
2156 | 2166 |
2157 // static | 2167 // static |
2158 bool MediaStreamManager::IsOriginAllowed(int render_process_id, | 2168 bool MediaStreamManager::IsOriginAllowed(int render_process_id, |
2159 const url::Origin& origin) { | 2169 const url::Origin& origin) { |
2160 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL( | 2170 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL( |
2161 render_process_id, ConvertToGURL(origin))) { | 2171 render_process_id, ConvertToGURL(origin))) { |
2162 LOG(ERROR) << "MSM: Renderer requested a URL it's not allowed to use."; | 2172 LOG(ERROR) << "MSM: Renderer requested a URL it's not allowed to use."; |
2163 return false; | 2173 return false; |
(...skipping 17 matching lines...) Expand all Loading... |
2181 if (device_info.session_id == session_id && | 2191 if (device_info.session_id == session_id && |
2182 device_info.device.type == type) { | 2192 device_info.device.type == type) { |
2183 request->SetCapturingLinkSecured(is_secure); | 2193 request->SetCapturingLinkSecured(is_secure); |
2184 return; | 2194 return; |
2185 } | 2195 } |
2186 } | 2196 } |
2187 } | 2197 } |
2188 } | 2198 } |
2189 | 2199 |
2190 } // namespace content | 2200 } // namespace content |
OLD | NEW |