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