| 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 12 matching lines...) Expand all Loading... |
| 23 #include "base/rand_util.h" | 23 #include "base/rand_util.h" |
| 24 #include "base/run_loop.h" | 24 #include "base/run_loop.h" |
| 25 #include "base/strings/string_number_conversions.h" | 25 #include "base/strings/string_number_conversions.h" |
| 26 #include "base/strings/string_util.h" | 26 #include "base/strings/string_util.h" |
| 27 #include "base/strings/stringprintf.h" | 27 #include "base/strings/stringprintf.h" |
| 28 #include "base/task_runner_util.h" | 28 #include "base/task_runner_util.h" |
| 29 #include "base/threading/thread.h" | 29 #include "base/threading/thread.h" |
| 30 #include "base/threading/thread_local.h" | 30 #include "base/threading/thread_local.h" |
| 31 #include "build/build_config.h" | 31 #include "build/build_config.h" |
| 32 #include "content/browser/browser_main_loop.h" | 32 #include "content/browser/browser_main_loop.h" |
| 33 #include "content/browser/child_process_security_policy_impl.h" |
| 33 #include "content/browser/renderer_host/media/audio_input_device_manager.h" | 34 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
| 34 #include "content/browser/renderer_host/media/audio_output_device_enumerator.h" | 35 #include "content/browser/renderer_host/media/audio_output_device_enumerator.h" |
| 35 #include "content/browser/renderer_host/media/media_capture_devices_impl.h" | 36 #include "content/browser/renderer_host/media/media_capture_devices_impl.h" |
| 36 #include "content/browser/renderer_host/media/media_stream_requester.h" | 37 #include "content/browser/renderer_host/media/media_stream_requester.h" |
| 37 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" | 38 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" |
| 38 #include "content/browser/renderer_host/media/video_capture_manager.h" | 39 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 39 #include "content/browser/renderer_host/render_process_host_impl.h" | 40 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 40 #include "content/public/browser/browser_thread.h" | 41 #include "content/public/browser/browser_thread.h" |
| 41 #include "content/public/browser/content_browser_client.h" | 42 #include "content/public/browser/content_browser_client.h" |
| 42 #include "content/public/browser/desktop_media_id.h" | 43 #include "content/public/browser/desktop_media_id.h" |
| 43 #include "content/public/browser/media_observer.h" | 44 #include "content/public/browser/media_observer.h" |
| 44 #include "content/public/browser/media_request_state.h" | 45 #include "content/public/browser/media_request_state.h" |
| 45 #include "content/public/browser/render_process_host.h" | 46 #include "content/public/browser/render_process_host.h" |
| 46 #include "content/public/browser/web_contents_media_capture_id.h" | 47 #include "content/public/browser/web_contents_media_capture_id.h" |
| 47 #include "content/public/common/content_client.h" | 48 #include "content/public/common/content_client.h" |
| 48 #include "content/public/common/content_switches.h" | 49 #include "content/public/common/content_switches.h" |
| 49 #include "content/public/common/media_stream_request.h" | 50 #include "content/public/common/media_stream_request.h" |
| 50 #include "crypto/hmac.h" | 51 #include "crypto/hmac.h" |
| 51 #include "media/audio/audio_device_description.h" | 52 #include "media/audio/audio_device_description.h" |
| 52 #include "media/audio/audio_manager.h" | 53 #include "media/audio/audio_manager.h" |
| 53 #include "media/base/audio_parameters.h" | 54 #include "media/base/audio_parameters.h" |
| 54 #include "media/base/channel_layout.h" | 55 #include "media/base/channel_layout.h" |
| 55 #include "media/base/media_switches.h" | 56 #include "media/base/media_switches.h" |
| 56 #include "media/capture/video/video_capture_device_factory.h" | 57 #include "media/capture/video/video_capture_device_factory.h" |
| 57 #include "url/gurl.h" | 58 #include "url/gurl.h" |
| 59 #include "url/origin.h" |
| 58 | 60 |
| 59 #if defined(OS_WIN) | 61 #if defined(OS_WIN) |
| 60 #include "base/win/scoped_com_initializer.h" | 62 #include "base/win/scoped_com_initializer.h" |
| 61 #endif | 63 #endif |
| 62 | 64 |
| 63 #if defined(OS_CHROMEOS) | 65 #if defined(OS_CHROMEOS) |
| 64 #include "chromeos/audio/cras_audio_handler.h" | 66 #include "chromeos/audio/cras_audio_handler.h" |
| 65 #endif | 67 #endif |
| 66 | 68 |
| 67 #if defined(OS_MACOSX) | 69 #if defined(OS_MACOSX) |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 device_info.device.name.clear(); | 188 device_info.device.name.clear(); |
| 187 } | 189 } |
| 188 | 190 |
| 189 bool CalledOnIOThread() { | 191 bool CalledOnIOThread() { |
| 190 // Check if this function call is on the IO thread, except for unittests where | 192 // Check if this function call is on the IO thread, except for unittests where |
| 191 // an IO thread might not have been created. | 193 // an IO thread might not have been created. |
| 192 return BrowserThread::CurrentlyOn(BrowserThread::IO) || | 194 return BrowserThread::CurrentlyOn(BrowserThread::IO) || |
| 193 !BrowserThread::IsMessageLoopValid(BrowserThread::IO); | 195 !BrowserThread::IsMessageLoopValid(BrowserThread::IO); |
| 194 } | 196 } |
| 195 | 197 |
| 198 GURL ConvertToGURL(const url::Origin& origin) { |
| 199 return origin.unique() ? GURL() : GURL(origin.Serialize()); |
| 200 } |
| 201 |
| 196 } // namespace | 202 } // namespace |
| 197 | 203 |
| 198 | 204 |
| 199 // MediaStreamManager::DeviceRequest represents a request to either enumerate | 205 // MediaStreamManager::DeviceRequest represents a request to either enumerate |
| 200 // available devices or open one or more devices. | 206 // available devices or open one or more devices. |
| 201 // TODO(perkj): MediaStreamManager still needs refactoring. I propose we create | 207 // TODO(perkj): MediaStreamManager still needs refactoring. I propose we create |
| 202 // several subclasses of DeviceRequest and move some of the responsibility of | 208 // several subclasses of DeviceRequest and move some of the responsibility of |
| 203 // the MediaStreamManager to the subclasses to get rid of the way too many if | 209 // the MediaStreamManager to the subclasses to get rid of the way too many if |
| 204 // statements in MediaStreamManager. | 210 // statements in MediaStreamManager. |
| 205 class MediaStreamManager::DeviceRequest { | 211 class MediaStreamManager::DeviceRequest { |
| 206 public: | 212 public: |
| 207 DeviceRequest(MediaStreamRequester* requester, | 213 DeviceRequest(MediaStreamRequester* requester, |
| 208 int requesting_process_id, | 214 int requesting_process_id, |
| 209 int requesting_frame_id, | 215 int requesting_frame_id, |
| 210 int page_request_id, | 216 int page_request_id, |
| 211 const GURL& security_origin, | 217 const url::Origin& security_origin, |
| 212 bool user_gesture, | 218 bool user_gesture, |
| 213 MediaStreamRequestType request_type, | 219 MediaStreamRequestType request_type, |
| 214 const StreamControls& controls, | 220 const StreamControls& controls, |
| 215 const ResourceContext::SaltCallback& salt_callback) | 221 const ResourceContext::SaltCallback& salt_callback) |
| 216 : requester(requester), | 222 : requester(requester), |
| 217 requesting_process_id(requesting_process_id), | 223 requesting_process_id(requesting_process_id), |
| 218 requesting_frame_id(requesting_frame_id), | 224 requesting_frame_id(requesting_frame_id), |
| 219 page_request_id(page_request_id), | 225 page_request_id(page_request_id), |
| 220 security_origin(security_origin), | 226 security_origin(security_origin), |
| 221 user_gesture(user_gesture), | 227 user_gesture(user_gesture), |
| (...skipping 24 matching lines...) Expand all Loading... |
| 246 | 252 |
| 247 MediaStreamType video_type() const { return video_type_; } | 253 MediaStreamType video_type() const { return video_type_; } |
| 248 | 254 |
| 249 // Creates a MediaStreamRequest object that is used by this request when UI | 255 // Creates a MediaStreamRequest object that is used by this request when UI |
| 250 // is asked for permission and device selection. | 256 // is asked for permission and device selection. |
| 251 void CreateUIRequest(const std::string& requested_audio_device_id, | 257 void CreateUIRequest(const std::string& requested_audio_device_id, |
| 252 const std::string& requested_video_device_id) { | 258 const std::string& requested_video_device_id) { |
| 253 DCHECK(!ui_request_); | 259 DCHECK(!ui_request_); |
| 254 target_process_id_ = requesting_process_id; | 260 target_process_id_ = requesting_process_id; |
| 255 target_frame_id_ = requesting_frame_id; | 261 target_frame_id_ = requesting_frame_id; |
| 256 ui_request_.reset(new MediaStreamRequest(requesting_process_id, | 262 ui_request_.reset(new MediaStreamRequest( |
| 257 requesting_frame_id, | 263 requesting_process_id, requesting_frame_id, page_request_id, |
| 258 page_request_id, | 264 ConvertToGURL(security_origin), user_gesture, request_type, |
| 259 security_origin, | 265 requested_audio_device_id, requested_video_device_id, audio_type_, |
| 260 user_gesture, | 266 video_type_)); |
| 261 request_type, | |
| 262 requested_audio_device_id, | |
| 263 requested_video_device_id, | |
| 264 audio_type_, | |
| 265 video_type_)); | |
| 266 } | 267 } |
| 267 | 268 |
| 268 // Creates a tab capture specific MediaStreamRequest object that is used by | 269 // Creates a tab capture specific MediaStreamRequest object that is used by |
| 269 // this request when UI is asked for permission and device selection. | 270 // this request when UI is asked for permission and device selection. |
| 270 void CreateTabCaptureUIRequest(int target_render_process_id, | 271 void CreateTabCaptureUIRequest(int target_render_process_id, |
| 271 int target_render_frame_id) { | 272 int target_render_frame_id) { |
| 272 DCHECK(!ui_request_); | 273 DCHECK(!ui_request_); |
| 273 target_process_id_ = target_render_process_id; | 274 target_process_id_ = target_render_process_id; |
| 274 target_frame_id_ = target_render_frame_id; | 275 target_frame_id_ = target_render_frame_id; |
| 275 ui_request_.reset(new MediaStreamRequest(target_render_process_id, | 276 ui_request_.reset(new MediaStreamRequest( |
| 276 target_render_frame_id, | 277 target_render_process_id, target_render_frame_id, page_request_id, |
| 277 page_request_id, | 278 ConvertToGURL(security_origin), user_gesture, request_type, "", "", |
| 278 security_origin, | 279 audio_type_, video_type_)); |
| 279 user_gesture, | |
| 280 request_type, | |
| 281 "", | |
| 282 "", | |
| 283 audio_type_, | |
| 284 video_type_)); | |
| 285 } | 280 } |
| 286 | 281 |
| 287 bool HasUIRequest() const { return ui_request_.get() != nullptr; } | 282 bool HasUIRequest() const { return ui_request_.get() != nullptr; } |
| 288 std::unique_ptr<MediaStreamRequest> DetachUIRequest() { | 283 std::unique_ptr<MediaStreamRequest> DetachUIRequest() { |
| 289 return std::move(ui_request_); | 284 return std::move(ui_request_); |
| 290 } | 285 } |
| 291 | 286 |
| 292 // Update the request state and notify observers. | 287 // Update the request state and notify observers. |
| 293 void SetState(MediaStreamType stream_type, MediaRequestState new_state) { | 288 void SetState(MediaStreamType stream_type, MediaRequestState new_state) { |
| 294 if (stream_type == NUM_MEDIA_TYPES) { | 289 if (stream_type == NUM_MEDIA_TYPES) { |
| 295 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) { | 290 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) { |
| 296 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); | 291 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
| 297 state_[stream_type] = new_state; | 292 state_[stream_type] = new_state; |
| 298 } | 293 } |
| 299 } else { | 294 } else { |
| 300 state_[stream_type] = new_state; | 295 state_[stream_type] = new_state; |
| 301 } | 296 } |
| 302 | 297 |
| 303 MediaObserver* media_observer = | 298 MediaObserver* media_observer = |
| 304 GetContentClient()->browser()->GetMediaObserver(); | 299 GetContentClient()->browser()->GetMediaObserver(); |
| 305 if (!media_observer) | 300 if (!media_observer) |
| 306 return; | 301 return; |
| 307 | 302 |
| 308 media_observer->OnMediaRequestStateChanged( | 303 media_observer->OnMediaRequestStateChanged( |
| 309 target_process_id_, target_frame_id_, page_request_id, security_origin, | 304 target_process_id_, target_frame_id_, page_request_id, |
| 310 stream_type, new_state); | 305 ConvertToGURL(security_origin), stream_type, new_state); |
| 311 } | 306 } |
| 312 | 307 |
| 313 MediaRequestState state(MediaStreamType stream_type) const { | 308 MediaRequestState state(MediaStreamType stream_type) const { |
| 314 return state_[stream_type]; | 309 return state_[stream_type]; |
| 315 } | 310 } |
| 316 | 311 |
| 317 MediaStreamRequester* const requester; // Can be NULL. | 312 MediaStreamRequester* const requester; // Can be NULL. |
| 318 | 313 |
| 319 | 314 |
| 320 // The render process id that requested this stream to be generated and that | 315 // The render process id that requested this stream to be generated and that |
| 321 // will receive a handle to the MediaStream. This may be different from | 316 // will receive a handle to the MediaStream. This may be different from |
| 322 // MediaStreamRequest::render_process_id which in the tab capture case | 317 // MediaStreamRequest::render_process_id which in the tab capture case |
| 323 // specifies the target renderer from which audio and video is captured. | 318 // specifies the target renderer from which audio and video is captured. |
| 324 const int requesting_process_id; | 319 const int requesting_process_id; |
| 325 | 320 |
| 326 // The render frame id that requested this stream to be generated and that | 321 // The render frame id that requested this stream to be generated and that |
| 327 // will receive a handle to the MediaStream. This may be different from | 322 // will receive a handle to the MediaStream. This may be different from |
| 328 // MediaStreamRequest::render_frame_id which in the tab capture case | 323 // MediaStreamRequest::render_frame_id which in the tab capture case |
| 329 // specifies the target renderer from which audio and video is captured. | 324 // specifies the target renderer from which audio and video is captured. |
| 330 const int requesting_frame_id; | 325 const int requesting_frame_id; |
| 331 | 326 |
| 332 // An ID the render frame provided to identify this request. | 327 // An ID the render frame provided to identify this request. |
| 333 const int page_request_id; | 328 const int page_request_id; |
| 334 | 329 |
| 335 const GURL security_origin; | 330 const url::Origin security_origin; |
| 336 | 331 |
| 337 const bool user_gesture; | 332 const bool user_gesture; |
| 338 | 333 |
| 339 const MediaStreamRequestType request_type; | 334 const MediaStreamRequestType request_type; |
| 340 | 335 |
| 341 const StreamControls controls; | 336 const StreamControls controls; |
| 342 | 337 |
| 343 ResourceContext::SaltCallback salt_callback; | 338 ResourceContext::SaltCallback salt_callback; |
| 344 | 339 |
| 345 StreamDeviceInfoArray devices; | 340 StreamDeviceInfoArray devices; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 442 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 448 DCHECK(audio_output_device_enumerator_.get()); | 443 DCHECK(audio_output_device_enumerator_.get()); |
| 449 return audio_output_device_enumerator_.get(); | 444 return audio_output_device_enumerator_.get(); |
| 450 } | 445 } |
| 451 | 446 |
| 452 std::string MediaStreamManager::MakeMediaAccessRequest( | 447 std::string MediaStreamManager::MakeMediaAccessRequest( |
| 453 int render_process_id, | 448 int render_process_id, |
| 454 int render_frame_id, | 449 int render_frame_id, |
| 455 int page_request_id, | 450 int page_request_id, |
| 456 const StreamControls& controls, | 451 const StreamControls& controls, |
| 457 const GURL& security_origin, | 452 const url::Origin& security_origin, |
| 458 const MediaRequestResponseCallback& callback) { | 453 const MediaRequestResponseCallback& callback) { |
| 459 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 454 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 460 | 455 |
| 461 // TODO(perkj): The argument list with NULL parameters to DeviceRequest | 456 // TODO(perkj): The argument list with NULL parameters to DeviceRequest |
| 462 // suggests that this is the wrong design. Can this be refactored? | 457 // suggests that this is the wrong design. Can this be refactored? |
| 463 DeviceRequest* request = new DeviceRequest( | 458 DeviceRequest* request = new DeviceRequest( |
| 464 NULL, render_process_id, render_frame_id, page_request_id, | 459 NULL, render_process_id, render_frame_id, page_request_id, |
| 465 security_origin, | 460 security_origin, |
| 466 false, // user gesture | 461 false, // user gesture |
| 467 MEDIA_DEVICE_ACCESS, controls, base::Bind(&ReturnEmptySalt)); | 462 MEDIA_DEVICE_ACCESS, controls, base::Bind(&ReturnEmptySalt)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 480 base::Unretained(this), label)); | 475 base::Unretained(this), label)); |
| 481 return label; | 476 return label; |
| 482 } | 477 } |
| 483 | 478 |
| 484 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, | 479 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, |
| 485 int render_process_id, | 480 int render_process_id, |
| 486 int render_frame_id, | 481 int render_frame_id, |
| 487 const ResourceContext::SaltCallback& sc, | 482 const ResourceContext::SaltCallback& sc, |
| 488 int page_request_id, | 483 int page_request_id, |
| 489 const StreamControls& controls, | 484 const StreamControls& controls, |
| 490 const GURL& security_origin, | 485 const url::Origin& security_origin, |
| 491 bool user_gesture) { | 486 bool user_gesture) { |
| 492 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 487 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 493 DVLOG(1) << "GenerateStream()"; | 488 DVLOG(1) << "GenerateStream()"; |
| 494 | 489 |
| 495 DeviceRequest* request = new DeviceRequest( | 490 DeviceRequest* request = new DeviceRequest( |
| 496 requester, render_process_id, render_frame_id, page_request_id, | 491 requester, render_process_id, render_frame_id, page_request_id, |
| 497 security_origin, user_gesture, MEDIA_GENERATE_STREAM, controls, sc); | 492 security_origin, user_gesture, MEDIA_GENERATE_STREAM, controls, sc); |
| 498 | 493 |
| 499 const std::string& label = AddRequest(request); | 494 const std::string& label = AddRequest(request); |
| 500 | 495 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 } | 655 } |
| 661 } | 656 } |
| 662 | 657 |
| 663 std::string MediaStreamManager::EnumerateDevices( | 658 std::string MediaStreamManager::EnumerateDevices( |
| 664 MediaStreamRequester* requester, | 659 MediaStreamRequester* requester, |
| 665 int render_process_id, | 660 int render_process_id, |
| 666 int render_frame_id, | 661 int render_frame_id, |
| 667 const ResourceContext::SaltCallback& sc, | 662 const ResourceContext::SaltCallback& sc, |
| 668 int page_request_id, | 663 int page_request_id, |
| 669 MediaStreamType type, | 664 MediaStreamType type, |
| 670 const GURL& security_origin) { | 665 const url::Origin& security_origin) { |
| 671 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 666 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 672 DCHECK(requester); | 667 DCHECK(requester); |
| 673 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 668 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
| 674 type == MEDIA_DEVICE_VIDEO_CAPTURE || | 669 type == MEDIA_DEVICE_VIDEO_CAPTURE || |
| 675 type == MEDIA_DEVICE_AUDIO_OUTPUT); | 670 type == MEDIA_DEVICE_AUDIO_OUTPUT); |
| 676 | 671 |
| 677 DeviceRequest* request = | 672 DeviceRequest* request = |
| 678 new DeviceRequest(requester, render_process_id, render_frame_id, | 673 new DeviceRequest(requester, render_process_id, render_frame_id, |
| 679 page_request_id, security_origin, | 674 page_request_id, security_origin, |
| 680 false, // user gesture | 675 false, // user gesture |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 DCHECK_GE(active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT], 0); | 772 DCHECK_GE(active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT], 0); |
| 778 } | 773 } |
| 779 | 774 |
| 780 void MediaStreamManager::OpenDevice(MediaStreamRequester* requester, | 775 void MediaStreamManager::OpenDevice(MediaStreamRequester* requester, |
| 781 int render_process_id, | 776 int render_process_id, |
| 782 int render_frame_id, | 777 int render_frame_id, |
| 783 const ResourceContext::SaltCallback& sc, | 778 const ResourceContext::SaltCallback& sc, |
| 784 int page_request_id, | 779 int page_request_id, |
| 785 const std::string& device_id, | 780 const std::string& device_id, |
| 786 MediaStreamType type, | 781 MediaStreamType type, |
| 787 const GURL& security_origin) { | 782 const url::Origin& security_origin) { |
| 788 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 783 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 789 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 784 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
| 790 type == MEDIA_DEVICE_VIDEO_CAPTURE); | 785 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
| 791 DVLOG(1) << "OpenDevice ({page_request_id = " << page_request_id << "})"; | 786 DVLOG(1) << "OpenDevice ({page_request_id = " << page_request_id << "})"; |
| 792 StreamControls controls; | 787 StreamControls controls; |
| 793 if (IsAudioInputMediaType(type)) { | 788 if (IsAudioInputMediaType(type)) { |
| 794 controls.audio.requested = true; | 789 controls.audio.requested = true; |
| 795 controls.audio.device_ids.push_back(device_id); | 790 controls.audio.device_ids.push_back(device_id); |
| 796 } else if (IsVideoMediaType(type)) { | 791 } else if (IsVideoMediaType(type)) { |
| 797 controls.video.requested = true; | 792 controls.video.requested = true; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 813 // been stopped. | 808 // been stopped. |
| 814 BrowserThread::PostTask( | 809 BrowserThread::PostTask( |
| 815 BrowserThread::IO, FROM_HERE, | 810 BrowserThread::IO, FROM_HERE, |
| 816 base::Bind(&MediaStreamManager::SetupRequest, | 811 base::Bind(&MediaStreamManager::SetupRequest, |
| 817 base::Unretained(this), label)); | 812 base::Unretained(this), label)); |
| 818 } | 813 } |
| 819 | 814 |
| 820 bool MediaStreamManager::TranslateSourceIdToDeviceId( | 815 bool MediaStreamManager::TranslateSourceIdToDeviceId( |
| 821 MediaStreamType stream_type, | 816 MediaStreamType stream_type, |
| 822 const ResourceContext::SaltCallback& sc, | 817 const ResourceContext::SaltCallback& sc, |
| 823 const GURL& security_origin, | 818 const url::Origin& security_origin, |
| 824 const std::string& source_id, | 819 const std::string& source_id, |
| 825 std::string* device_id) const { | 820 std::string* device_id) const { |
| 826 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || | 821 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || |
| 827 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); | 822 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); |
| 828 // The source_id can be empty if the constraint is set but empty. | 823 // The source_id can be empty if the constraint is set but empty. |
| 829 if (source_id.empty()) | 824 if (source_id.empty()) |
| 830 return false; | 825 return false; |
| 831 | 826 |
| 832 const EnumerationCache* cache = | 827 const EnumerationCache* cache = |
| 833 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | 828 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 "458404 MediaStreamManager::DeviceMonitorMac::StartMonitoring")); | 961 "458404 MediaStreamManager::DeviceMonitorMac::StartMonitoring")); |
| 967 browser_main_loop->device_monitor_mac()->StartMonitoring(task_runner); | 962 browser_main_loop->device_monitor_mac()->StartMonitoring(task_runner); |
| 968 } | 963 } |
| 969 #endif | 964 #endif |
| 970 | 965 |
| 971 // Pick the first valid (translatable) device ID from lists of required | 966 // Pick the first valid (translatable) device ID from lists of required |
| 972 // and optional IDs. | 967 // and optional IDs. |
| 973 bool MediaStreamManager::PickDeviceId( | 968 bool MediaStreamManager::PickDeviceId( |
| 974 MediaStreamType type, | 969 MediaStreamType type, |
| 975 const ResourceContext::SaltCallback& salt_callback, | 970 const ResourceContext::SaltCallback& salt_callback, |
| 976 const GURL& security_origin, | 971 const url::Origin& security_origin, |
| 977 const TrackControls& controls, | 972 const TrackControls& controls, |
| 978 std::string* device_id) const { | 973 std::string* device_id) const { |
| 979 if (!controls.device_ids.empty()) { | 974 if (!controls.device_ids.empty()) { |
| 980 if (controls.device_ids.size() > 1) { | 975 if (controls.device_ids.size() > 1) { |
| 981 LOG(ERROR) << "Only one required device ID is supported"; | 976 LOG(ERROR) << "Only one required device ID is supported"; |
| 982 return false; | 977 return false; |
| 983 } | 978 } |
| 984 const std::string& candidate_id = controls.device_ids[0]; | 979 const std::string& candidate_id = controls.device_ids[0]; |
| 985 if (!TranslateSourceIdToDeviceId(type, salt_callback, security_origin, | 980 if (!TranslateSourceIdToDeviceId(type, salt_callback, security_origin, |
| 986 candidate_id, device_id)) { | 981 candidate_id, device_id)) { |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 } | 1188 } |
| 1194 | 1189 |
| 1195 void MediaStreamManager::SetupRequest(const std::string& label) { | 1190 void MediaStreamManager::SetupRequest(const std::string& label) { |
| 1196 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1191 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1197 DeviceRequest* request = FindRequest(label); | 1192 DeviceRequest* request = FindRequest(label); |
| 1198 if (!request) { | 1193 if (!request) { |
| 1199 DVLOG(1) << "SetupRequest label " << label << " doesn't exist!!"; | 1194 DVLOG(1) << "SetupRequest label " << label << " doesn't exist!!"; |
| 1200 return; // This can happen if the request has been canceled. | 1195 return; // This can happen if the request has been canceled. |
| 1201 } | 1196 } |
| 1202 | 1197 |
| 1203 if (!request->security_origin.is_valid()) { | |
| 1204 LOG(ERROR) << "Invalid security origin. " << request->security_origin; | |
| 1205 FinalizeRequestFailed(label, | |
| 1206 request, | |
| 1207 MEDIA_DEVICE_INVALID_SECURITY_ORIGIN); | |
| 1208 return; | |
| 1209 } | |
| 1210 | |
| 1211 MediaStreamType audio_type = MEDIA_NO_SERVICE; | 1198 MediaStreamType audio_type = MEDIA_NO_SERVICE; |
| 1212 MediaStreamType video_type = MEDIA_NO_SERVICE; | 1199 MediaStreamType video_type = MEDIA_NO_SERVICE; |
| 1213 ParseStreamType(request->controls, &audio_type, &video_type); | 1200 ParseStreamType(request->controls, &audio_type, &video_type); |
| 1214 request->SetAudioType(audio_type); | 1201 request->SetAudioType(audio_type); |
| 1215 request->SetVideoType(video_type); | 1202 request->SetVideoType(video_type); |
| 1216 | 1203 |
| 1217 const bool is_web_contents_capture = audio_type == MEDIA_TAB_AUDIO_CAPTURE || | 1204 const bool is_web_contents_capture = audio_type == MEDIA_TAB_AUDIO_CAPTURE || |
| 1218 video_type == MEDIA_TAB_VIDEO_CAPTURE; | 1205 video_type == MEDIA_TAB_VIDEO_CAPTURE; |
| 1219 if (is_web_contents_capture && !SetupTabCaptureRequest(request)) { | 1206 if (is_web_contents_capture && !SetupTabCaptureRequest(request)) { |
| 1220 FinalizeRequestFailed(label, | 1207 FinalizeRequestFailed(label, |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1451 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label, | 1438 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label, |
| 1452 DeviceRequest* request) { | 1439 DeviceRequest* request) { |
| 1453 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1440 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1454 DCHECK_EQ(request->request_type, MEDIA_ENUMERATE_DEVICES); | 1441 DCHECK_EQ(request->request_type, MEDIA_ENUMERATE_DEVICES); |
| 1455 DCHECK(((request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || | 1442 DCHECK(((request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || |
| 1456 request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT) && | 1443 request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT) && |
| 1457 request->video_type() == MEDIA_NO_SERVICE) || | 1444 request->video_type() == MEDIA_NO_SERVICE) || |
| 1458 (request->audio_type() == MEDIA_NO_SERVICE && | 1445 (request->audio_type() == MEDIA_NO_SERVICE && |
| 1459 request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE)); | 1446 request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE)); |
| 1460 | 1447 |
| 1461 if (request->security_origin.is_valid()) { | 1448 for (StreamDeviceInfo& device_info : request->devices) |
| 1462 for (StreamDeviceInfo& device_info : request->devices) | 1449 TranslateDeviceIdToSourceId(request, &device_info.device); |
| 1463 TranslateDeviceIdToSourceId(request, &device_info.device); | |
| 1464 } else { | |
| 1465 request->devices.clear(); | |
| 1466 } | |
| 1467 | 1450 |
| 1468 if (use_fake_ui_) { | 1451 if (use_fake_ui_) { |
| 1469 if (!fake_ui_) | 1452 if (!fake_ui_) |
| 1470 fake_ui_.reset(new FakeMediaStreamUIProxy()); | 1453 fake_ui_.reset(new FakeMediaStreamUIProxy()); |
| 1471 request->ui_proxy = std::move(fake_ui_); | 1454 request->ui_proxy = std::move(fake_ui_); |
| 1472 } else { | 1455 } else { |
| 1473 request->ui_proxy = MediaStreamUIProxy::Create(); | 1456 request->ui_proxy = MediaStreamUIProxy::Create(); |
| 1474 } | 1457 } |
| 1475 | 1458 |
| 1476 // Output label permissions are based on input permission. | 1459 // Output label permissions are based on input permission. |
| (...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2118 | 2101 |
| 2119 void MediaStreamManager::NotifyDeviceChangeSubscribers(MediaStreamType type) { | 2102 void MediaStreamManager::NotifyDeviceChangeSubscribers(MediaStreamType type) { |
| 2120 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 2103 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 2121 for (auto* subscriber : device_change_subscribers_) | 2104 for (auto* subscriber : device_change_subscribers_) |
| 2122 subscriber->DevicesChanged(type); | 2105 subscriber->DevicesChanged(type); |
| 2123 } | 2106 } |
| 2124 | 2107 |
| 2125 // static | 2108 // static |
| 2126 std::string MediaStreamManager::GetHMACForMediaDeviceID( | 2109 std::string MediaStreamManager::GetHMACForMediaDeviceID( |
| 2127 const ResourceContext::SaltCallback& sc, | 2110 const ResourceContext::SaltCallback& sc, |
| 2128 const GURL& security_origin, | 2111 const url::Origin& security_origin, |
| 2129 const std::string& raw_unique_id) { | 2112 const std::string& raw_unique_id) { |
| 2130 DCHECK(security_origin.is_valid()); | |
| 2131 DCHECK(!raw_unique_id.empty()); | 2113 DCHECK(!raw_unique_id.empty()); |
| 2132 if (raw_unique_id == media::AudioDeviceDescription::kDefaultDeviceId || | 2114 if (raw_unique_id == media::AudioDeviceDescription::kDefaultDeviceId || |
| 2133 raw_unique_id == media::AudioDeviceDescription::kCommunicationsDeviceId) { | 2115 raw_unique_id == media::AudioDeviceDescription::kCommunicationsDeviceId) { |
| 2134 return raw_unique_id; | 2116 return raw_unique_id; |
| 2135 } | 2117 } |
| 2136 | 2118 |
| 2137 crypto::HMAC hmac(crypto::HMAC::SHA256); | 2119 crypto::HMAC hmac(crypto::HMAC::SHA256); |
| 2138 const size_t digest_length = hmac.DigestLength(); | 2120 const size_t digest_length = hmac.DigestLength(); |
| 2139 std::vector<uint8_t> digest(digest_length); | 2121 std::vector<uint8_t> digest(digest_length); |
| 2140 std::string salt = sc.Run(); | 2122 std::string salt = sc.Run(); |
| 2141 bool result = hmac.Init(security_origin.spec()) && | 2123 bool result = hmac.Init(security_origin.Serialize()) && |
| 2142 hmac.Sign(raw_unique_id + salt, &digest[0], digest.size()); | 2124 hmac.Sign(raw_unique_id + salt, &digest[0], digest.size()); |
| 2143 DCHECK(result); | 2125 DCHECK(result); |
| 2144 return base::ToLowerASCII(base::HexEncode(&digest[0], digest.size())); | 2126 return base::ToLowerASCII(base::HexEncode(&digest[0], digest.size())); |
| 2145 } | 2127 } |
| 2146 | 2128 |
| 2147 // static | 2129 // static |
| 2148 bool MediaStreamManager::DoesMediaDeviceIDMatchHMAC( | 2130 bool MediaStreamManager::DoesMediaDeviceIDMatchHMAC( |
| 2149 const ResourceContext::SaltCallback& sc, | 2131 const ResourceContext::SaltCallback& sc, |
| 2150 const GURL& security_origin, | 2132 const url::Origin& security_origin, |
| 2151 const std::string& device_guid, | 2133 const std::string& device_guid, |
| 2152 const std::string& raw_unique_id) { | 2134 const std::string& raw_unique_id) { |
| 2153 DCHECK(security_origin.is_valid()); | |
| 2154 DCHECK(!raw_unique_id.empty()); | 2135 DCHECK(!raw_unique_id.empty()); |
| 2155 std::string guid_from_raw_device_id = | 2136 std::string guid_from_raw_device_id = |
| 2156 GetHMACForMediaDeviceID(sc, security_origin, raw_unique_id); | 2137 GetHMACForMediaDeviceID(sc, security_origin, raw_unique_id); |
| 2157 return guid_from_raw_device_id == device_guid; | 2138 return guid_from_raw_device_id == device_guid; |
| 2158 } | 2139 } |
| 2159 | 2140 |
| 2141 // static |
| 2142 bool MediaStreamManager::IsOriginAllowed(int render_process_id, |
| 2143 const url::Origin& origin) { |
| 2144 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL( |
| 2145 render_process_id, ConvertToGURL(origin))) { |
| 2146 LOG(ERROR) << "MSM: Renderer requested a URL it's not allowed to use."; |
| 2147 return false; |
| 2148 } |
| 2149 |
| 2150 return true; |
| 2151 } |
| 2152 |
| 2160 } // namespace content | 2153 } // namespace content |
| OLD | NEW |