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 <cctype> | 7 #include <cctype> |
8 #include <list> | 8 #include <list> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/power_monitor/power_monitor.h" | 15 #include "base/power_monitor/power_monitor.h" |
16 #include "base/profiler/scoped_tracker.h" | 16 #include "base/profiler/scoped_tracker.h" |
17 #include "base/rand_util.h" | 17 #include "base/rand_util.h" |
18 #include "base/run_loop.h" | 18 #include "base/run_loop.h" |
| 19 #include "base/strings/string_number_conversions.h" |
19 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
20 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
21 #include "base/threading/thread.h" | 22 #include "base/threading/thread.h" |
22 #include "content/browser/browser_main_loop.h" | 23 #include "content/browser/browser_main_loop.h" |
23 #include "content/browser/media/capture/web_contents_capture_util.h" | 24 #include "content/browser/media/capture/web_contents_capture_util.h" |
24 #include "content/browser/renderer_host/media/audio_input_device_manager.h" | 25 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
25 #include "content/browser/renderer_host/media/audio_output_device_enumerator.h" | 26 #include "content/browser/renderer_host/media/audio_output_device_enumerator.h" |
26 #include "content/browser/renderer_host/media/media_capture_devices_impl.h" | 27 #include "content/browser/renderer_host/media/media_capture_devices_impl.h" |
27 #include "content/browser/renderer_host/media/media_stream_requester.h" | 28 #include "content/browser/renderer_host/media/media_stream_requester.h" |
28 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" | 29 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" |
29 #include "content/browser/renderer_host/media/video_capture_manager.h" | 30 #include "content/browser/renderer_host/media/video_capture_manager.h" |
30 #include "content/browser/renderer_host/render_process_host_impl.h" | 31 #include "content/browser/renderer_host/render_process_host_impl.h" |
31 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
32 #include "content/public/browser/content_browser_client.h" | 33 #include "content/public/browser/content_browser_client.h" |
33 #include "content/public/browser/media_device_id.h" | |
34 #include "content/public/browser/media_observer.h" | 34 #include "content/public/browser/media_observer.h" |
35 #include "content/public/browser/media_request_state.h" | 35 #include "content/public/browser/media_request_state.h" |
36 #include "content/public/browser/render_process_host.h" | 36 #include "content/public/browser/render_process_host.h" |
37 #include "content/public/common/content_client.h" | 37 #include "content/public/common/content_client.h" |
38 #include "content/public/common/content_switches.h" | 38 #include "content/public/common/content_switches.h" |
39 #include "content/public/common/media_stream_request.h" | 39 #include "content/public/common/media_stream_request.h" |
| 40 #include "crypto/hmac.h" |
40 #include "media/audio/audio_manager_base.h" | 41 #include "media/audio/audio_manager_base.h" |
41 #include "media/audio/audio_parameters.h" | 42 #include "media/audio/audio_parameters.h" |
42 #include "media/base/channel_layout.h" | 43 #include "media/base/channel_layout.h" |
43 #include "media/base/media_switches.h" | 44 #include "media/base/media_switches.h" |
44 #include "media/capture/video/video_capture_device_factory.h" | 45 #include "media/capture/video/video_capture_device_factory.h" |
45 #include "url/gurl.h" | 46 #include "url/gurl.h" |
46 | 47 |
47 #if defined(OS_WIN) | 48 #if defined(OS_WIN) |
48 #include "base/win/scoped_com_initializer.h" | 49 #include "base/win/scoped_com_initializer.h" |
49 #endif | 50 #endif |
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 | 878 |
878 const EnumerationCache* cache = | 879 const EnumerationCache* cache = |
879 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | 880 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? |
880 &audio_enumeration_cache_ : &video_enumeration_cache_; | 881 &audio_enumeration_cache_ : &video_enumeration_cache_; |
881 | 882 |
882 // If device monitoring hasn't started, the |device_guid| is not valid. | 883 // If device monitoring hasn't started, the |device_guid| is not valid. |
883 if (!cache->valid) | 884 if (!cache->valid) |
884 return false; | 885 return false; |
885 | 886 |
886 for (const StreamDeviceInfo& device_info : cache->devices) { | 887 for (const StreamDeviceInfo& device_info : cache->devices) { |
887 if (content::DoesMediaDeviceIDMatchHMAC(sc, security_origin, source_id, | 888 if (DoesMediaDeviceIDMatchHMAC(sc, security_origin, source_id, |
888 device_info.device.id)) { | 889 device_info.device.id)) { |
889 *device_id = device_info.device.id; | 890 *device_id = device_info.device.id; |
890 return true; | 891 return true; |
891 } | 892 } |
892 } | 893 } |
893 return false; | 894 return false; |
894 } | 895 } |
895 | 896 |
896 void MediaStreamManager::EnsureDeviceMonitorStarted() { | 897 void MediaStreamManager::EnsureDeviceMonitorStarted() { |
897 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 898 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
898 StartMonitoring(); | 899 StartMonitoring(); |
(...skipping 20 matching lines...) Expand all Loading... |
919 StopRemovedDevice(old_device_info.device); | 920 StopRemovedDevice(old_device_info.device); |
920 } | 921 } |
921 } | 922 } |
922 } | 923 } |
923 | 924 |
924 void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) { | 925 void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) { |
925 std::vector<int> session_ids; | 926 std::vector<int> session_ids; |
926 for (const LabeledDeviceRequest& labeled_request : requests_) { | 927 for (const LabeledDeviceRequest& labeled_request : requests_) { |
927 const DeviceRequest* request = labeled_request.second; | 928 const DeviceRequest* request = labeled_request.second; |
928 for (const StreamDeviceInfo& device_info : request->devices) { | 929 for (const StreamDeviceInfo& device_info : request->devices) { |
929 const std::string source_id = content::GetHMACForMediaDeviceID( | 930 const std::string source_id = GetHMACForMediaDeviceID( |
930 request->salt_callback, request->security_origin, device.id); | 931 request->salt_callback, request->security_origin, device.id); |
931 if (device_info.device.id == source_id && | 932 if (device_info.device.id == source_id && |
932 device_info.device.type == device.type) { | 933 device_info.device.type == device.type) { |
933 session_ids.push_back(device_info.session_id); | 934 session_ids.push_back(device_info.session_id); |
934 if (labeled_request.second->requester) { | 935 if (labeled_request.second->requester) { |
935 labeled_request.second->requester->DeviceStopped( | 936 labeled_request.second->requester->DeviceStopped( |
936 labeled_request.second->requesting_frame_id, | 937 labeled_request.second->requesting_frame_id, |
937 labeled_request.first, device_info); | 938 labeled_request.first, device_info); |
938 } | 939 } |
939 } | 940 } |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 } | 1073 } |
1073 return true; | 1074 return true; |
1074 } | 1075 } |
1075 | 1076 |
1076 void MediaStreamManager::TranslateDeviceIdToSourceId( | 1077 void MediaStreamManager::TranslateDeviceIdToSourceId( |
1077 DeviceRequest* request, | 1078 DeviceRequest* request, |
1078 MediaStreamDevice* device) { | 1079 MediaStreamDevice* device) { |
1079 if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || | 1080 if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || |
1080 request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT || | 1081 request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT || |
1081 request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE) { | 1082 request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE) { |
1082 device->id = content::GetHMACForMediaDeviceID( | 1083 device->id = GetHMACForMediaDeviceID(request->salt_callback, |
1083 request->salt_callback, | 1084 request->security_origin, device->id); |
1084 request->security_origin, | |
1085 device->id); | |
1086 } | 1085 } |
1087 } | 1086 } |
1088 | 1087 |
1089 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | 1088 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { |
1090 DCHECK(CalledOnIOThread()); | 1089 DCHECK(CalledOnIOThread()); |
1091 cache->valid = false; | 1090 cache->valid = false; |
1092 } | 1091 } |
1093 | 1092 |
1094 bool MediaStreamManager::EnumerationRequired(EnumerationCache* cache, | 1093 bool MediaStreamManager::EnumerationRequired(EnumerationCache* cache, |
1095 MediaStreamType stream_type) { | 1094 MediaStreamType stream_type) { |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1413 } | 1412 } |
1414 | 1413 |
1415 bool MediaStreamManager::FindExistingRequestedDeviceInfo( | 1414 bool MediaStreamManager::FindExistingRequestedDeviceInfo( |
1416 const DeviceRequest& new_request, | 1415 const DeviceRequest& new_request, |
1417 const MediaStreamDevice& new_device_info, | 1416 const MediaStreamDevice& new_device_info, |
1418 StreamDeviceInfo* existing_device_info, | 1417 StreamDeviceInfo* existing_device_info, |
1419 MediaRequestState* existing_request_state) const { | 1418 MediaRequestState* existing_request_state) const { |
1420 DCHECK(existing_device_info); | 1419 DCHECK(existing_device_info); |
1421 DCHECK(existing_request_state); | 1420 DCHECK(existing_request_state); |
1422 | 1421 |
1423 std::string source_id = content::GetHMACForMediaDeviceID( | 1422 std::string source_id = |
1424 new_request.salt_callback, | 1423 GetHMACForMediaDeviceID(new_request.salt_callback, |
1425 new_request.security_origin, | 1424 new_request.security_origin, new_device_info.id); |
1426 new_device_info.id); | |
1427 | 1425 |
1428 for (const LabeledDeviceRequest& labeled_request : requests_) { | 1426 for (const LabeledDeviceRequest& labeled_request : requests_) { |
1429 const DeviceRequest* request = labeled_request.second; | 1427 const DeviceRequest* request = labeled_request.second; |
1430 if (request->requesting_process_id == new_request.requesting_process_id && | 1428 if (request->requesting_process_id == new_request.requesting_process_id && |
1431 request->requesting_frame_id == new_request.requesting_frame_id && | 1429 request->requesting_frame_id == new_request.requesting_frame_id && |
1432 request->request_type == new_request.request_type) { | 1430 request->request_type == new_request.request_type) { |
1433 for (const StreamDeviceInfo& device_info : request->devices) { | 1431 for (const StreamDeviceInfo& device_info : request->devices) { |
1434 if (device_info.device.id == source_id && | 1432 if (device_info.device.id == source_id && |
1435 device_info.device.type == new_device_info.type) { | 1433 device_info.device.type == new_device_info.type) { |
1436 *existing_device_info = device_info; | 1434 *existing_device_info = device_info; |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2128 base::Unretained(this))); | 2126 base::Unretained(this))); |
2129 } | 2127 } |
2130 } | 2128 } |
2131 | 2129 |
2132 void MediaStreamManager::SetKeyboardMicOnDeviceThread() { | 2130 void MediaStreamManager::SetKeyboardMicOnDeviceThread() { |
2133 DCHECK(device_task_runner_->BelongsToCurrentThread()); | 2131 DCHECK(device_task_runner_->BelongsToCurrentThread()); |
2134 audio_manager_->SetHasKeyboardMic(); | 2132 audio_manager_->SetHasKeyboardMic(); |
2135 } | 2133 } |
2136 #endif | 2134 #endif |
2137 | 2135 |
| 2136 // static |
| 2137 std::string MediaStreamManager::GetHMACForMediaDeviceID( |
| 2138 const ResourceContext::SaltCallback& sc, |
| 2139 const GURL& security_origin, |
| 2140 const std::string& raw_unique_id) { |
| 2141 DCHECK(security_origin.is_valid()); |
| 2142 DCHECK(!raw_unique_id.empty()); |
| 2143 if (raw_unique_id == media::AudioManagerBase::kDefaultDeviceId || |
| 2144 raw_unique_id == media::AudioManagerBase::kCommunicationsDeviceId) { |
| 2145 return raw_unique_id; |
| 2146 } |
| 2147 |
| 2148 crypto::HMAC hmac(crypto::HMAC::SHA256); |
| 2149 const size_t digest_length = hmac.DigestLength(); |
| 2150 std::vector<uint8> digest(digest_length); |
| 2151 std::string salt = sc.Run(); |
| 2152 bool result = hmac.Init(security_origin.spec()) && |
| 2153 hmac.Sign(raw_unique_id + salt, &digest[0], digest.size()); |
| 2154 DCHECK(result); |
| 2155 return base::ToLowerASCII(base::HexEncode(&digest[0], digest.size())); |
| 2156 } |
| 2157 |
| 2158 // static |
| 2159 bool MediaStreamManager::DoesMediaDeviceIDMatchHMAC( |
| 2160 const ResourceContext::SaltCallback& sc, |
| 2161 const GURL& security_origin, |
| 2162 const std::string& device_guid, |
| 2163 const std::string& raw_unique_id) { |
| 2164 DCHECK(security_origin.is_valid()); |
| 2165 DCHECK(!raw_unique_id.empty()); |
| 2166 std::string guid_from_raw_device_id = |
| 2167 GetHMACForMediaDeviceID(sc, security_origin, raw_unique_id); |
| 2168 return guid_from_raw_device_id == device_guid; |
| 2169 } |
| 2170 |
2138 } // namespace content | 2171 } // namespace content |
OLD | NEW |