| 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 |