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