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 "chrome/browser/media/media_capture_devices_dispatcher.h" | 5 #include "chrome/browser/media/media_capture_devices_dispatcher.h" |
6 | 6 |
7 #include "apps/app_window.h" | 7 #include "apps/app_window.h" |
8 #include "apps/app_window_registry.h" | 8 #include "apps/app_window_registry.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 ui = ScreenCaptureNotificationUI::Create(l10n_util::GetStringFUTF16( | 185 ui = ScreenCaptureNotificationUI::Create(l10n_util::GetStringFUTF16( |
186 IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_TEXT_DELEGATED, | 186 IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_TEXT_DELEGATED, |
187 registered_extension_name, | 187 registered_extension_name, |
188 application_title)); | 188 application_title)); |
189 } | 189 } |
190 } | 190 } |
191 | 191 |
192 return ui.Pass(); | 192 return ui.Pass(); |
193 } | 193 } |
194 | 194 |
| 195 // Returns the WebContents instance that contains the RenderFrameHost referenced |
| 196 // by the given |request|. |
| 197 content::WebContents* TargetWebContentsFromRequest( |
| 198 const content::MediaStreamRequest& request) { |
| 199 return content::WebContents::FromRenderFrameHost( |
| 200 content::RenderFrameHost::FromID(request.render_process_id, |
| 201 request.render_frame_id)); |
| 202 } |
| 203 |
195 #if defined(AUDIO_STREAM_MONITORING) | 204 #if defined(AUDIO_STREAM_MONITORING) |
196 | 205 |
197 AudioStreamMonitor* AudioStreamMonitorFromRenderFrame( | 206 AudioStreamMonitor* AudioStreamMonitorFromRenderFrame( |
198 int render_process_id, | 207 int render_process_id, |
199 int render_frame_id) { | 208 int render_frame_id) { |
200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
201 content::WebContents* const web_contents = | 210 content::WebContents* const web_contents = |
202 content::WebContents::FromRenderFrameHost( | 211 content::WebContents::FromRenderFrameHost( |
203 content::RenderFrameHost::FromID(render_process_id, render_frame_id)); | 212 content::RenderFrameHost::FromID(render_process_id, render_frame_id)); |
204 if (!web_contents) | 213 if (!web_contents) |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 ProcessScreenCaptureAccessRequest( | 398 ProcessScreenCaptureAccessRequest( |
390 web_contents, request, callback, extension); | 399 web_contents, request, callback, extension); |
391 return; | 400 return; |
392 } | 401 } |
393 | 402 |
394 // The extension name that the stream is registered with. | 403 // The extension name that the stream is registered with. |
395 std::string original_extension_name; | 404 std::string original_extension_name; |
396 // Resolve DesktopMediaID for the specified device id. | 405 // Resolve DesktopMediaID for the specified device id. |
397 content::DesktopMediaID media_id = | 406 content::DesktopMediaID media_id = |
398 GetDesktopStreamsRegistry()->RequestMediaForStreamId( | 407 GetDesktopStreamsRegistry()->RequestMediaForStreamId( |
399 request.requested_video_device_id, request.render_process_id, | 408 request.requested_video_device_id, |
400 request.render_view_id, request.security_origin, | 409 TargetWebContentsFromRequest(request), |
| 410 request.security_origin, |
401 &original_extension_name); | 411 &original_extension_name); |
402 | 412 |
403 // Received invalid device id. | 413 // Received invalid device id. |
404 if (media_id.type == content::DesktopMediaID::TYPE_NONE) { | 414 if (media_id.type == content::DesktopMediaID::TYPE_NONE) { |
405 callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, ui.Pass()); | 415 callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, ui.Pass()); |
406 return; | 416 return; |
407 } | 417 } |
408 | 418 |
409 bool loopback_audio_supported = false; | 419 bool loopback_audio_supported = false; |
410 #if defined(USE_CRAS) || defined(OS_WIN) | 420 #if defined(USE_CRAS) || defined(OS_WIN) |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 #if defined(ENABLE_EXTENSIONS) | 548 #if defined(ENABLE_EXTENSIONS) |
539 Profile* profile = | 549 Profile* profile = |
540 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 550 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
541 extensions::TabCaptureRegistry* tab_capture_registry = | 551 extensions::TabCaptureRegistry* tab_capture_registry = |
542 extensions::TabCaptureRegistry::Get(profile); | 552 extensions::TabCaptureRegistry::Get(profile); |
543 if (!tab_capture_registry) { | 553 if (!tab_capture_registry) { |
544 NOTREACHED(); | 554 NOTREACHED(); |
545 callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, ui.Pass()); | 555 callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, ui.Pass()); |
546 return; | 556 return; |
547 } | 557 } |
548 bool tab_capture_allowed = | 558 const bool tab_capture_allowed = tab_capture_registry->VerifyRequest( |
549 tab_capture_registry->VerifyRequest(request.render_process_id, | 559 TargetWebContentsFromRequest(request), extension->id()); |
550 request.render_view_id); | |
551 | 560 |
552 if (request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE && | 561 if (request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE && |
553 tab_capture_allowed && | 562 tab_capture_allowed && |
554 extension->permissions_data()->HasAPIPermission( | 563 extension->permissions_data()->HasAPIPermission( |
555 extensions::APIPermission::kTabCapture)) { | 564 extensions::APIPermission::kTabCapture)) { |
556 devices.push_back(content::MediaStreamDevice( | 565 devices.push_back(content::MediaStreamDevice( |
557 content::MEDIA_TAB_AUDIO_CAPTURE, std::string(), std::string())); | 566 content::MEDIA_TAB_AUDIO_CAPTURE, std::string(), std::string())); |
558 } | 567 } |
559 | 568 |
560 if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE && | 569 if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE && |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 806 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
798 BrowserThread::PostTask( | 807 BrowserThread::PostTask( |
799 BrowserThread::UI, FROM_HERE, | 808 BrowserThread::UI, FROM_HERE, |
800 base::Bind( | 809 base::Bind( |
801 &MediaCaptureDevicesDispatcher::NotifyVideoDevicesChangedOnUIThread, | 810 &MediaCaptureDevicesDispatcher::NotifyVideoDevicesChangedOnUIThread, |
802 base::Unretained(this))); | 811 base::Unretained(this))); |
803 } | 812 } |
804 | 813 |
805 void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged( | 814 void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged( |
806 int render_process_id, | 815 int render_process_id, |
807 int render_view_id, | 816 int render_frame_id, |
808 int page_request_id, | 817 int page_request_id, |
809 const GURL& security_origin, | 818 const GURL& security_origin, |
810 const content::MediaStreamDevice& device, | 819 content::MediaStreamType stream_type, |
811 content::MediaRequestState state) { | 820 content::MediaRequestState state) { |
812 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 821 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
813 BrowserThread::PostTask( | 822 BrowserThread::PostTask( |
814 BrowserThread::UI, FROM_HERE, | 823 BrowserThread::UI, FROM_HERE, |
815 base::Bind( | 824 base::Bind( |
816 &MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread, | 825 &MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread, |
817 base::Unretained(this), render_process_id, render_view_id, | 826 base::Unretained(this), render_process_id, render_frame_id, |
818 page_request_id, security_origin, device, state)); | 827 page_request_id, security_origin, stream_type, state)); |
819 } | 828 } |
820 | 829 |
821 void MediaCaptureDevicesDispatcher::OnAudioStreamPlaying( | 830 void MediaCaptureDevicesDispatcher::OnAudioStreamPlaying( |
822 int render_process_id, | 831 int render_process_id, |
823 int render_frame_id, | 832 int render_frame_id, |
824 int stream_id, | 833 int stream_id, |
825 const ReadPowerAndClipCallback& read_power_callback) { | 834 const ReadPowerAndClipCallback& read_power_callback) { |
826 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 835 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
827 #if defined(AUDIO_STREAM_MONITORING) | 836 #if defined(AUDIO_STREAM_MONITORING) |
828 BrowserThread::PostTask( | 837 BrowserThread::PostTask( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 } | 879 } |
871 | 880 |
872 void MediaCaptureDevicesDispatcher::NotifyVideoDevicesChangedOnUIThread() { | 881 void MediaCaptureDevicesDispatcher::NotifyVideoDevicesChangedOnUIThread() { |
873 MediaStreamDevices devices = GetVideoCaptureDevices(); | 882 MediaStreamDevices devices = GetVideoCaptureDevices(); |
874 FOR_EACH_OBSERVER(Observer, observers_, | 883 FOR_EACH_OBSERVER(Observer, observers_, |
875 OnUpdateVideoDevices(devices)); | 884 OnUpdateVideoDevices(devices)); |
876 } | 885 } |
877 | 886 |
878 void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread( | 887 void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread( |
879 int render_process_id, | 888 int render_process_id, |
880 int render_view_id, | 889 int render_frame_id, |
881 int page_request_id, | 890 int page_request_id, |
882 const GURL& security_origin, | 891 const GURL& security_origin, |
883 const content::MediaStreamDevice& device, | 892 content::MediaStreamType stream_type, |
884 content::MediaRequestState state) { | 893 content::MediaRequestState state) { |
885 // Track desktop capture sessions. Tracking is necessary to avoid unbalanced | 894 // Track desktop capture sessions. Tracking is necessary to avoid unbalanced |
886 // session counts since not all requests will reach MEDIA_REQUEST_STATE_DONE, | 895 // session counts since not all requests will reach MEDIA_REQUEST_STATE_DONE, |
887 // but they will all reach MEDIA_REQUEST_STATE_CLOSING. | 896 // but they will all reach MEDIA_REQUEST_STATE_CLOSING. |
888 if (device.type == content::MEDIA_DESKTOP_VIDEO_CAPTURE) { | 897 if (stream_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE) { |
889 if (state == content::MEDIA_REQUEST_STATE_DONE) { | 898 if (state == content::MEDIA_REQUEST_STATE_DONE) { |
890 DesktopCaptureSession session = { render_process_id, render_view_id, | 899 DesktopCaptureSession session = { render_process_id, render_frame_id, |
891 page_request_id }; | 900 page_request_id }; |
892 desktop_capture_sessions_.push_back(session); | 901 desktop_capture_sessions_.push_back(session); |
893 } else if (state == content::MEDIA_REQUEST_STATE_CLOSING) { | 902 } else if (state == content::MEDIA_REQUEST_STATE_CLOSING) { |
894 for (DesktopCaptureSessions::iterator it = | 903 for (DesktopCaptureSessions::iterator it = |
895 desktop_capture_sessions_.begin(); | 904 desktop_capture_sessions_.begin(); |
896 it != desktop_capture_sessions_.end(); | 905 it != desktop_capture_sessions_.end(); |
897 ++it) { | 906 ++it) { |
898 if (it->render_process_id == render_process_id && | 907 if (it->render_process_id == render_process_id && |
899 it->render_view_id == render_view_id && | 908 it->render_frame_id == render_frame_id && |
900 it->page_request_id == page_request_id) { | 909 it->page_request_id == page_request_id) { |
901 desktop_capture_sessions_.erase(it); | 910 desktop_capture_sessions_.erase(it); |
902 break; | 911 break; |
903 } | 912 } |
904 } | 913 } |
905 } | 914 } |
906 } | 915 } |
907 | 916 |
908 // Cancel the request. | 917 // Cancel the request. |
909 if (state == content::MEDIA_REQUEST_STATE_CLOSING) { | 918 if (state == content::MEDIA_REQUEST_STATE_CLOSING) { |
910 bool found = false; | 919 bool found = false; |
911 for (RequestsQueues::iterator rqs_it = pending_requests_.begin(); | 920 for (RequestsQueues::iterator rqs_it = pending_requests_.begin(); |
912 rqs_it != pending_requests_.end(); ++rqs_it) { | 921 rqs_it != pending_requests_.end(); ++rqs_it) { |
913 RequestsQueue& queue = rqs_it->second; | 922 RequestsQueue& queue = rqs_it->second; |
914 for (RequestsQueue::iterator it = queue.begin(); | 923 for (RequestsQueue::iterator it = queue.begin(); |
915 it != queue.end(); ++it) { | 924 it != queue.end(); ++it) { |
916 if (it->request.render_process_id == render_process_id && | 925 if (it->request.render_process_id == render_process_id && |
917 it->request.render_view_id == render_view_id && | 926 it->request.render_frame_id == render_frame_id && |
918 it->request.page_request_id == page_request_id) { | 927 it->request.page_request_id == page_request_id) { |
919 queue.erase(it); | 928 queue.erase(it); |
920 found = true; | 929 found = true; |
921 break; | 930 break; |
922 } | 931 } |
923 } | 932 } |
924 if (found) | 933 if (found) |
925 break; | 934 break; |
926 } | 935 } |
927 } | 936 } |
928 | 937 |
929 #if defined(OS_CHROMEOS) | 938 #if defined(OS_CHROMEOS) |
930 if (IsOriginForCasting(security_origin) && IsVideoMediaType(device.type)) { | 939 if (IsOriginForCasting(security_origin) && IsVideoMediaType(stream_type)) { |
931 // Notify ash that casting state has changed. | 940 // Notify ash that casting state has changed. |
932 if (state == content::MEDIA_REQUEST_STATE_DONE) { | 941 if (state == content::MEDIA_REQUEST_STATE_DONE) { |
933 ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(true); | 942 ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(true); |
934 } else if (state == content::MEDIA_REQUEST_STATE_CLOSING) { | 943 } else if (state == content::MEDIA_REQUEST_STATE_CLOSING) { |
935 ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(false); | 944 ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(false); |
936 } | 945 } |
937 } | 946 } |
938 #endif | 947 #endif |
939 | 948 |
940 FOR_EACH_OBSERVER(Observer, observers_, | 949 FOR_EACH_OBSERVER(Observer, observers_, |
941 OnRequestUpdate(render_process_id, | 950 OnRequestUpdate(render_process_id, |
942 render_view_id, | 951 render_frame_id, |
943 device, | 952 stream_type, |
944 state)); | 953 state)); |
945 } | 954 } |
946 | 955 |
947 void MediaCaptureDevicesDispatcher::OnCreatingAudioStreamOnUIThread( | 956 void MediaCaptureDevicesDispatcher::OnCreatingAudioStreamOnUIThread( |
948 int render_process_id, | 957 int render_process_id, |
949 int render_frame_id) { | 958 int render_frame_id) { |
950 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 959 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
951 FOR_EACH_OBSERVER(Observer, observers_, | 960 FOR_EACH_OBSERVER(Observer, observers_, |
952 OnCreatingAudioStream(render_process_id, render_frame_id)); | 961 OnCreatingAudioStream(render_process_id, render_frame_id)); |
953 #if defined(AUDIO_STREAM_MONITORING) | 962 #if defined(AUDIO_STREAM_MONITORING) |
(...skipping 16 matching lines...) Expand all Loading... |
970 | 979 |
971 void MediaCaptureDevicesDispatcher::SetTestAudioCaptureDevices( | 980 void MediaCaptureDevicesDispatcher::SetTestAudioCaptureDevices( |
972 const MediaStreamDevices& devices) { | 981 const MediaStreamDevices& devices) { |
973 test_audio_devices_ = devices; | 982 test_audio_devices_ = devices; |
974 } | 983 } |
975 | 984 |
976 void MediaCaptureDevicesDispatcher::SetTestVideoCaptureDevices( | 985 void MediaCaptureDevicesDispatcher::SetTestVideoCaptureDevices( |
977 const MediaStreamDevices& devices) { | 986 const MediaStreamDevices& devices) { |
978 test_video_devices_ = devices; | 987 test_video_devices_ = devices; |
979 } | 988 } |
OLD | NEW |