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 "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
10 #include "base/prefs/scoped_user_pref_update.h" | 10 #include "base/prefs/scoped_user_pref_update.h" |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 bool IsOriginWhitelistedForScreenCapture(const GURL& origin) { | 82 bool IsOriginWhitelistedForScreenCapture(const GURL& origin) { |
83 #if defined(OFFICIAL_BUILD) | 83 #if defined(OFFICIAL_BUILD) |
84 if (// Google Hangouts. | 84 if (// Google Hangouts. |
85 (origin.SchemeIs("https") && | 85 (origin.SchemeIs("https") && |
86 EndsWith(origin.spec(), ".talkgadget.google.com/", true)) || | 86 EndsWith(origin.spec(), ".talkgadget.google.com/", true)) || |
87 origin.spec() == "https://talkgadget.google.com/" || | 87 origin.spec() == "https://talkgadget.google.com/" || |
88 origin.spec() == "https://plus.google.com/" || | 88 origin.spec() == "https://plus.google.com/" || |
89 origin.spec() == "chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/" || | 89 origin.spec() == "chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/" || |
90 origin.spec() == "chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/" || | 90 origin.spec() == "chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/" || |
91 origin.spec() == "chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/" || | 91 origin.spec() == "chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/" || |
| 92 origin.spec() == "chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/" || |
92 origin.spec() == "chrome-extension://gfdkimpbcpahaombhbimeihdjnejgicl/") { | 93 origin.spec() == "chrome-extension://gfdkimpbcpahaombhbimeihdjnejgicl/") { |
93 return true; | 94 return true; |
94 } | 95 } |
95 // Check against hashed origins. | 96 // Check against hashed origins. |
| 97 // TODO(hshi): remove this when trusted tester becomes public. |
96 const std::string origin_hash = base::SHA1HashString(origin.spec()); | 98 const std::string origin_hash = base::SHA1HashString(origin.spec()); |
97 DCHECK_EQ(origin_hash.length(), base::kSHA1Length); | 99 DCHECK_EQ(origin_hash.length(), base::kSHA1Length); |
98 const std::string hexencoded_origin_hash = | 100 const std::string hexencoded_origin_hash = |
99 base::HexEncode(origin_hash.data(), origin_hash.length()); | 101 base::HexEncode(origin_hash.data(), origin_hash.length()); |
100 return | 102 return |
101 hexencoded_origin_hash == "3C2705BC432E7C51CA8553FDC5BEE873FF2468EE" || | 103 hexencoded_origin_hash == "3C2705BC432E7C51CA8553FDC5BEE873FF2468EE"; |
102 hexencoded_origin_hash == "50F02B8A668CAB274527D58356F07C2143080FCC"; | |
103 #else | 104 #else |
104 return false; | 105 return false; |
105 #endif | 106 #endif |
106 } | 107 } |
107 | 108 |
| 109 #if defined(OS_CHROMEOS) |
| 110 // Returns true of the security origin is associated with casting. |
| 111 bool IsOriginForCasting(const GURL& origin) { |
| 112 #if defined(OFFICIAL_BUILD) |
| 113 // Whitelisted tab casting extensions. |
| 114 if (origin.spec() == "chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/" || |
| 115 origin.spec() == "chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/" || |
| 116 origin.spec() == "chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/" || |
| 117 origin.spec() == "chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/") { |
| 118 return true; |
| 119 } |
| 120 // Check against hashed origins. |
| 121 // TODO(hshi): remove this when trusted tester becomes public. |
| 122 const std::string origin_hash = base::SHA1HashString(origin.spec()); |
| 123 DCHECK_EQ(origin_hash.length(), base::kSHA1Length); |
| 124 const std::string hexencoded_origin_hash = |
| 125 base::HexEncode(origin_hash.data(), origin_hash.length()); |
| 126 return |
| 127 hexencoded_origin_hash == "3C2705BC432E7C51CA8553FDC5BEE873FF2468EE"; |
| 128 #else |
| 129 return false; |
| 130 #endif |
| 131 } |
| 132 #endif |
| 133 |
108 // Helper to get title of the calling application shown in the screen capture | 134 // Helper to get title of the calling application shown in the screen capture |
109 // notification. | 135 // notification. |
110 base::string16 GetApplicationTitle(content::WebContents* web_contents, | 136 base::string16 GetApplicationTitle(content::WebContents* web_contents, |
111 const extensions::Extension* extension) { | 137 const extensions::Extension* extension) { |
112 // Use extension name as title for extensions and origin for drive-by web. | 138 // Use extension name as title for extensions and origin for drive-by web. |
113 std::string title; | 139 std::string title; |
114 if (extension) { | 140 if (extension) { |
115 title = extension->name(); | 141 title = extension->name(); |
116 } else { | 142 } else { |
117 title = web_contents->GetURL().GetOrigin().spec(); | 143 title = web_contents->GetURL().GetOrigin().spec(); |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 #endif // !defined(OS_CHROMEOS) | 414 #endif // !defined(OS_CHROMEOS) |
389 | 415 |
390 bool capture_audio = | 416 bool capture_audio = |
391 (request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && | 417 (request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && |
392 loopback_audio_supported); | 418 loopback_audio_supported); |
393 | 419 |
394 // Unless we're being invoked from a component extension, register to | 420 // Unless we're being invoked from a component extension, register to |
395 // display the notification for stream capture. | 421 // display the notification for stream capture. |
396 bool display_notification = !component_extension; | 422 bool display_notification = !component_extension; |
397 | 423 |
398 ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio, | 424 ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio, |
399 display_notification, application_title); | 425 display_notification, application_title); |
400 } | 426 } |
401 } | 427 } |
402 | 428 |
403 callback.Run(devices, ui.Pass()); | 429 callback.Run(devices, ui.Pass()); |
404 } | 430 } |
405 | 431 |
406 void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest( | 432 void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest( |
407 content::WebContents* web_contents, | 433 content::WebContents* web_contents, |
408 const content::MediaStreamRequest& request, | 434 const content::MediaStreamRequest& request, |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 BrowserThread::PostTask( | 676 BrowserThread::PostTask( |
651 BrowserThread::UI, FROM_HERE, | 677 BrowserThread::UI, FROM_HERE, |
652 base::Bind(&MediaCaptureDevicesDispatcher::UpdateVideoDevicesOnUIThread, | 678 base::Bind(&MediaCaptureDevicesDispatcher::UpdateVideoDevicesOnUIThread, |
653 base::Unretained(this), devices)); | 679 base::Unretained(this), devices)); |
654 } | 680 } |
655 | 681 |
656 void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged( | 682 void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged( |
657 int render_process_id, | 683 int render_process_id, |
658 int render_view_id, | 684 int render_view_id, |
659 int page_request_id, | 685 int page_request_id, |
| 686 const GURL& security_origin, |
660 const content::MediaStreamDevice& device, | 687 const content::MediaStreamDevice& device, |
661 content::MediaRequestState state) { | 688 content::MediaRequestState state) { |
662 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 689 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
663 BrowserThread::PostTask( | 690 BrowserThread::PostTask( |
664 BrowserThread::UI, FROM_HERE, | 691 BrowserThread::UI, FROM_HERE, |
665 base::Bind( | 692 base::Bind( |
666 &MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread, | 693 &MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread, |
667 base::Unretained(this), render_process_id, render_view_id, | 694 base::Unretained(this), render_process_id, render_view_id, |
668 page_request_id, device, state)); | 695 page_request_id, security_origin, device, state)); |
669 } | 696 } |
670 | 697 |
671 void MediaCaptureDevicesDispatcher::OnAudioStreamPlayingChanged( | 698 void MediaCaptureDevicesDispatcher::OnAudioStreamPlayingChanged( |
672 int render_process_id, int render_view_id, int stream_id, | 699 int render_process_id, int render_view_id, int stream_id, |
673 bool is_playing, float power_dbfs, bool clipped) { | 700 bool is_playing, float power_dbfs, bool clipped) { |
674 audio_stream_indicator_->UpdateWebContentsStatus( | 701 audio_stream_indicator_->UpdateWebContentsStatus( |
675 render_process_id, render_view_id, stream_id, | 702 render_process_id, render_view_id, stream_id, |
676 is_playing, power_dbfs, clipped); | 703 is_playing, power_dbfs, clipped); |
677 } | 704 } |
678 | 705 |
(...skipping 23 matching lines...) Expand all Loading... |
702 devices_enumerated_ = true; | 729 devices_enumerated_ = true; |
703 video_devices_ = devices; | 730 video_devices_ = devices; |
704 FOR_EACH_OBSERVER(Observer, observers_, | 731 FOR_EACH_OBSERVER(Observer, observers_, |
705 OnUpdateVideoDevices(video_devices_)); | 732 OnUpdateVideoDevices(video_devices_)); |
706 } | 733 } |
707 | 734 |
708 void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread( | 735 void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread( |
709 int render_process_id, | 736 int render_process_id, |
710 int render_view_id, | 737 int render_view_id, |
711 int page_request_id, | 738 int page_request_id, |
| 739 const GURL& security_origin, |
712 const content::MediaStreamDevice& device, | 740 const content::MediaStreamDevice& device, |
713 content::MediaRequestState state) { | 741 content::MediaRequestState state) { |
714 // Track desktop capture sessions. Tracking is necessary to avoid unbalanced | 742 // Track desktop capture sessions. Tracking is necessary to avoid unbalanced |
715 // session counts since not all requests will reach MEDIA_REQUEST_STATE_DONE, | 743 // session counts since not all requests will reach MEDIA_REQUEST_STATE_DONE, |
716 // but they will all reach MEDIA_REQUEST_STATE_CLOSING. | 744 // but they will all reach MEDIA_REQUEST_STATE_CLOSING. |
717 if (device.type == content::MEDIA_DESKTOP_VIDEO_CAPTURE) { | 745 if (device.type == content::MEDIA_DESKTOP_VIDEO_CAPTURE) { |
718 if (state == content::MEDIA_REQUEST_STATE_DONE) { | 746 if (state == content::MEDIA_REQUEST_STATE_DONE) { |
719 DesktopCaptureSession session = { render_process_id, render_view_id, | 747 DesktopCaptureSession session = { render_process_id, render_view_id, |
720 page_request_id }; | 748 page_request_id }; |
721 desktop_capture_sessions_.push_back(session); | 749 desktop_capture_sessions_.push_back(session); |
(...skipping 26 matching lines...) Expand all Loading... |
748 queue.erase(it); | 776 queue.erase(it); |
749 found = true; | 777 found = true; |
750 break; | 778 break; |
751 } | 779 } |
752 } | 780 } |
753 if (found) | 781 if (found) |
754 break; | 782 break; |
755 } | 783 } |
756 } | 784 } |
757 | 785 |
| 786 #if defined(OS_CHROMEOS) |
| 787 if (IsOriginForCasting(security_origin) && IsVideoMediaType(device.type)) { |
| 788 // Notify ash that casting state has changed. |
| 789 if (state == content::MEDIA_REQUEST_STATE_DONE) { |
| 790 ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(true); |
| 791 } else if (state == content::MEDIA_REQUEST_STATE_CLOSING) { |
| 792 ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(false); |
| 793 } |
| 794 } |
| 795 #endif |
| 796 |
758 FOR_EACH_OBSERVER(Observer, observers_, | 797 FOR_EACH_OBSERVER(Observer, observers_, |
759 OnRequestUpdate(render_process_id, | 798 OnRequestUpdate(render_process_id, |
760 render_view_id, | 799 render_view_id, |
761 device, | 800 device, |
762 state)); | 801 state)); |
763 } | 802 } |
764 | 803 |
765 void MediaCaptureDevicesDispatcher::OnCreatingAudioStreamOnUIThread( | 804 void MediaCaptureDevicesDispatcher::OnCreatingAudioStreamOnUIThread( |
766 int render_process_id, | 805 int render_process_id, |
767 int render_view_id) { | 806 int render_view_id) { |
768 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 807 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
769 FOR_EACH_OBSERVER(Observer, observers_, | 808 FOR_EACH_OBSERVER(Observer, observers_, |
770 OnCreatingAudioStream(render_process_id, render_view_id)); | 809 OnCreatingAudioStream(render_process_id, render_view_id)); |
771 } | 810 } |
772 | 811 |
773 bool MediaCaptureDevicesDispatcher::IsDesktopCaptureInProgress() { | 812 bool MediaCaptureDevicesDispatcher::IsDesktopCaptureInProgress() { |
774 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 813 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
775 return desktop_capture_sessions_.size() > 0; | 814 return desktop_capture_sessions_.size() > 0; |
776 } | 815 } |
OLD | NEW |