Commit ac8f9263 authored by perkj's avatar perkj Committed by Commit bot

Don't auto allow access to media devices unless a the security origin of the...

Don't auto allow access to media devices unless a the security origin of the requester is the same as its ancestors.

This adds a field in MediaStreamRequest to verify that the security origin of the requester is the same as its ancestors.
This field have to be set on the UI-thread and is therefore set just before sending the request to the UI.

BUG=448378
TEST= please see bug report

Review URL: https://codereview.chromium.org/795703003

Cr-Commit-Position: refs/heads/master@{#313904}
parent c27bd1f7
...@@ -498,6 +498,11 @@ void MediaStreamDevicesController::RequestFinished() { ...@@ -498,6 +498,11 @@ void MediaStreamDevicesController::RequestFinished() {
} }
bool MediaStreamDevicesController::IsRequestAllowedByDefault() const { bool MediaStreamDevicesController::IsRequestAllowedByDefault() const {
// If not all ancestors of the requesting frame have the same origin, do not
// allow the request per default.
if (!request_.all_ancestors_have_same_origin)
return false;
// The request from internal objects like chrome://URLs is always allowed. // The request from internal objects like chrome://URLs is always allowed.
if (CheckAllowAllMediaStreamContentForOrigin(profile_, if (CheckAllowAllMediaStreamContentForOrigin(profile_,
request_.security_origin)) { request_.security_origin)) {
......
...@@ -97,6 +97,10 @@ class CONTENT_EXPORT FrameTreeNode { ...@@ -97,6 +97,10 @@ class CONTENT_EXPORT FrameTreeNode {
replication_state_.sandbox_flags = sandbox_flags; replication_state_.sandbox_flags = sandbox_flags;
} }
bool HasSameOrigin(const FrameTreeNode& node) const {
return replication_state_.origin.IsSameAs(node.replication_state_.origin);
}
const FrameReplicationState& current_replication_state() const { const FrameReplicationState& current_replication_state() const {
return replication_state_; return replication_state_;
} }
......
...@@ -238,7 +238,9 @@ class MediaStreamManager::DeviceRequest { ...@@ -238,7 +238,9 @@ class MediaStreamManager::DeviceRequest {
salt_callback(salt_callback), salt_callback(salt_callback),
state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED),
audio_type_(MEDIA_NO_SERVICE), audio_type_(MEDIA_NO_SERVICE),
video_type_(MEDIA_NO_SERVICE) { video_type_(MEDIA_NO_SERVICE),
target_process_id_(-1),
target_frame_id_(-1) {
} }
~DeviceRequest() {} ~DeviceRequest() {}
...@@ -264,6 +266,8 @@ class MediaStreamManager::DeviceRequest { ...@@ -264,6 +266,8 @@ class MediaStreamManager::DeviceRequest {
void CreateUIRequest(const std::string& requested_audio_device_id, void CreateUIRequest(const std::string& requested_audio_device_id,
const std::string& requested_video_device_id) { const std::string& requested_video_device_id) {
DCHECK(!ui_request_); DCHECK(!ui_request_);
target_process_id_ = requesting_process_id;
target_frame_id_ = requesting_frame_id;
ui_request_.reset(new MediaStreamRequest(requesting_process_id, ui_request_.reset(new MediaStreamRequest(requesting_process_id,
requesting_frame_id, requesting_frame_id,
page_request_id, page_request_id,
...@@ -279,9 +283,10 @@ class MediaStreamManager::DeviceRequest { ...@@ -279,9 +283,10 @@ class MediaStreamManager::DeviceRequest {
// Creates a tab capture specific MediaStreamRequest object that is used by // Creates a tab capture specific MediaStreamRequest object that is used by
// this request when UI is asked for permission and device selection. // this request when UI is asked for permission and device selection.
void CreateTabCaptureUIRequest(int target_render_process_id, void CreateTabCaptureUIRequest(int target_render_process_id,
int target_render_frame_id, int target_render_frame_id) {
const std::string& tab_capture_id) {
DCHECK(!ui_request_); DCHECK(!ui_request_);
target_process_id_ = target_render_process_id;
target_frame_id_ = target_render_frame_id;
ui_request_.reset(new MediaStreamRequest(target_render_process_id, ui_request_.reset(new MediaStreamRequest(target_render_process_id,
target_render_frame_id, target_render_frame_id,
page_request_id, page_request_id,
...@@ -292,10 +297,12 @@ class MediaStreamManager::DeviceRequest { ...@@ -292,10 +297,12 @@ class MediaStreamManager::DeviceRequest {
"", "",
audio_type_, audio_type_,
video_type_)); video_type_));
ui_request_->tab_capture_device_id = tab_capture_id;
} }
const MediaStreamRequest* UIRequest() const { return ui_request_.get(); } bool HasUIRequest() const { return ui_request_.get() != nullptr; }
scoped_ptr<MediaStreamRequest> DetachUIRequest() {
return ui_request_.Pass();
}
// Update the request state and notify observers. // Update the request state and notify observers.
void SetState(MediaStreamType stream_type, MediaRequestState new_state) { void SetState(MediaStreamType stream_type, MediaRequestState new_state) {
...@@ -313,14 +320,8 @@ class MediaStreamManager::DeviceRequest { ...@@ -313,14 +320,8 @@ class MediaStreamManager::DeviceRequest {
if (!media_observer) if (!media_observer)
return; return;
// If |ui_request_| doesn't exist, it means that the request has not yet
// been setup fully and there are no valid observers.
if (!ui_request_)
return;
media_observer->OnMediaRequestStateChanged( media_observer->OnMediaRequestStateChanged(
ui_request_->render_process_id, ui_request_->render_frame_id, target_process_id_, target_frame_id_, page_request_id, security_origin,
ui_request_->page_request_id, ui_request_->security_origin,
stream_type, new_state); stream_type, new_state);
} }
...@@ -365,11 +366,15 @@ class MediaStreamManager::DeviceRequest { ...@@ -365,11 +366,15 @@ class MediaStreamManager::DeviceRequest {
scoped_ptr<MediaStreamUIProxy> ui_proxy; scoped_ptr<MediaStreamUIProxy> ui_proxy;
std::string tab_capture_device_id;
private: private:
std::vector<MediaRequestState> state_; std::vector<MediaRequestState> state_;
scoped_ptr<MediaStreamRequest> ui_request_; scoped_ptr<MediaStreamRequest> ui_request_;
MediaStreamType audio_type_; MediaStreamType audio_type_;
MediaStreamType video_type_; MediaStreamType video_type_;
int target_process_id_;
int target_frame_id_;
}; };
MediaStreamManager::EnumerationCache::EnumerationCache() MediaStreamManager::EnumerationCache::EnumerationCache()
...@@ -1163,7 +1168,7 @@ void MediaStreamManager::DeleteRequest(const std::string& label) { ...@@ -1163,7 +1168,7 @@ void MediaStreamManager::DeleteRequest(const std::string& label) {
void MediaStreamManager::PostRequestToUI(const std::string& label, void MediaStreamManager::PostRequestToUI(const std::string& label,
DeviceRequest* request) { DeviceRequest* request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(request->UIRequest()); DCHECK(request->HasUIRequest());
DVLOG(1) << "PostRequestToUI({label= " << label << "})"; DVLOG(1) << "PostRequestToUI({label= " << label << "})";
const MediaStreamType audio_type = request->audio_type(); const MediaStreamType audio_type = request->audio_type();
...@@ -1203,7 +1208,7 @@ void MediaStreamManager::PostRequestToUI(const std::string& label, ...@@ -1203,7 +1208,7 @@ void MediaStreamManager::PostRequestToUI(const std::string& label,
} }
request->ui_proxy->RequestAccess( request->ui_proxy->RequestAccess(
*request->UIRequest(), request->DetachUIRequest(),
base::Bind(&MediaStreamManager::HandleAccessRequestResponse, base::Bind(&MediaStreamManager::HandleAccessRequestResponse,
base::Unretained(this), label)); base::Unretained(this), label));
} }
...@@ -1340,10 +1345,10 @@ bool MediaStreamManager::SetupTabCaptureRequest(DeviceRequest* request) { ...@@ -1340,10 +1345,10 @@ bool MediaStreamManager::SetupTabCaptureRequest(DeviceRequest* request) {
request->video_type() != MEDIA_NO_SERVICE)) { request->video_type() != MEDIA_NO_SERVICE)) {
return false; return false;
} }
request->tab_capture_device_id = capture_device_id;
request->CreateTabCaptureUIRequest(target_render_process_id, request->CreateTabCaptureUIRequest(target_render_process_id,
target_render_frame_id, target_render_frame_id);
capture_device_id);
DVLOG(3) << "SetupTabCaptureRequest " DVLOG(3) << "SetupTabCaptureRequest "
<< ", {capture_device_id = " << capture_device_id << "}" << ", {capture_device_id = " << capture_device_id << "}"
...@@ -1913,7 +1918,7 @@ void MediaStreamManager::HandleAccessRequestResponse( ...@@ -1913,7 +1918,7 @@ void MediaStreamManager::HandleAccessRequestResponse(
if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE || if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE ||
device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) { device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) {
device_info.device.id = request->UIRequest()->tab_capture_device_id; device_info.device.id = request->tab_capture_device_id;
// Initialize the sample_rate and channel_layout here since for audio // Initialize the sample_rate and channel_layout here since for audio
// mirroring, we don't go through EnumerateDevices where these are usually // mirroring, we don't go through EnumerateDevices where these are usually
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h" #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_delegate.h" #include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
...@@ -13,13 +14,35 @@ ...@@ -13,13 +14,35 @@
namespace content { namespace content {
void SetAndCheckAncestorFlag(MediaStreamRequest* request) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
RenderFrameHostImpl* rfh =
RenderFrameHostImpl::FromID(request->render_process_id,
request->render_frame_id);
if (rfh == NULL) {
// RenderFrame destroyed before the request is handled?
return;
}
FrameTreeNode* node = rfh->frame_tree_node();
while (node->parent() != NULL) {
if (!node->HasSameOrigin(*node->parent())) {
request->all_ancestors_have_same_origin = false;
return;
}
node = node->parent();
}
request->all_ancestors_have_same_origin = true;
}
class MediaStreamUIProxy::Core { class MediaStreamUIProxy::Core {
public: public:
explicit Core(const base::WeakPtr<MediaStreamUIProxy>& proxy, explicit Core(const base::WeakPtr<MediaStreamUIProxy>& proxy,
RenderFrameHostDelegate* test_render_delegate); RenderFrameHostDelegate* test_render_delegate);
~Core(); ~Core();
void RequestAccess(const MediaStreamRequest& request); void RequestAccess(scoped_ptr<MediaStreamRequest> request);
bool CheckAccess(const GURL& security_origin, bool CheckAccess(const GURL& security_origin,
MediaStreamType type, MediaStreamType type,
int process_id, int process_id,
...@@ -58,11 +81,11 @@ MediaStreamUIProxy::Core::~Core() { ...@@ -58,11 +81,11 @@ MediaStreamUIProxy::Core::~Core() {
} }
void MediaStreamUIProxy::Core::RequestAccess( void MediaStreamUIProxy::Core::RequestAccess(
const MediaStreamRequest& request) { scoped_ptr<MediaStreamRequest> request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderFrameHostDelegate* render_delegate = GetRenderFrameHostDelegate( RenderFrameHostDelegate* render_delegate = GetRenderFrameHostDelegate(
request.render_process_id, request.render_frame_id); request->render_process_id, request->render_frame_id);
// Tab may have gone away, or has no delegate from which to request access. // Tab may have gone away, or has no delegate from which to request access.
if (!render_delegate) { if (!render_delegate) {
...@@ -71,10 +94,11 @@ void MediaStreamUIProxy::Core::RequestAccess( ...@@ -71,10 +94,11 @@ void MediaStreamUIProxy::Core::RequestAccess(
scoped_ptr<MediaStreamUI>()); scoped_ptr<MediaStreamUI>());
return; return;
} }
SetAndCheckAncestorFlag(request.get());
render_delegate->RequestMediaAccessPermission( render_delegate->RequestMediaAccessPermission(
request, base::Bind(&Core::ProcessAccessRequestResponse, *request, base::Bind(&Core::ProcessAccessRequestResponse,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
} }
bool MediaStreamUIProxy::Core::CheckAccess(const GURL& security_origin, bool MediaStreamUIProxy::Core::CheckAccess(const GURL& security_origin,
...@@ -154,14 +178,15 @@ MediaStreamUIProxy::~MediaStreamUIProxy() { ...@@ -154,14 +178,15 @@ MediaStreamUIProxy::~MediaStreamUIProxy() {
} }
void MediaStreamUIProxy::RequestAccess( void MediaStreamUIProxy::RequestAccess(
const MediaStreamRequest& request, scoped_ptr<MediaStreamRequest> request,
const ResponseCallback& response_callback) { const ResponseCallback& response_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
response_callback_ = response_callback; response_callback_ = response_callback;
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, BrowserThread::UI, FROM_HERE,
base::Bind(&Core::RequestAccess, base::Unretained(core_.get()), request)); base::Bind(&Core::RequestAccess, base::Unretained(core_.get()),
base::Passed(&request)));
} }
void MediaStreamUIProxy::CheckAccess( void MediaStreamUIProxy::CheckAccess(
...@@ -262,7 +287,7 @@ void FakeMediaStreamUIProxy::SetCameraAccess(bool access) { ...@@ -262,7 +287,7 @@ void FakeMediaStreamUIProxy::SetCameraAccess(bool access) {
} }
void FakeMediaStreamUIProxy::RequestAccess( void FakeMediaStreamUIProxy::RequestAccess(
const MediaStreamRequest& request, scoped_ptr<MediaStreamRequest> request,
const ResponseCallback& response_callback) { const ResponseCallback& response_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
...@@ -289,25 +314,25 @@ void FakeMediaStreamUIProxy::RequestAccess( ...@@ -289,25 +314,25 @@ void FakeMediaStreamUIProxy::RequestAccess(
for (MediaStreamDevices::const_iterator it = devices_.begin(); for (MediaStreamDevices::const_iterator it = devices_.begin();
it != devices_.end(); ++it) { it != devices_.end(); ++it) {
if (!accepted_audio && if (!accepted_audio &&
IsAudioInputMediaType(request.audio_type) && IsAudioInputMediaType(request->audio_type) &&
IsAudioInputMediaType(it->type) && IsAudioInputMediaType(it->type) &&
(request.requested_audio_device_id.empty() || (request->requested_audio_device_id.empty() ||
request.requested_audio_device_id == it->id)) { request->requested_audio_device_id == it->id)) {
devices_to_use.push_back(*it); devices_to_use.push_back(*it);
accepted_audio = true; accepted_audio = true;
} else if (!accepted_video && } else if (!accepted_video &&
IsVideoMediaType(request.video_type) && IsVideoMediaType(request->video_type) &&
IsVideoMediaType(it->type) && IsVideoMediaType(it->type) &&
(request.requested_video_device_id.empty() || (request->requested_video_device_id.empty() ||
request.requested_video_device_id == it->id)) { request->requested_video_device_id == it->id)) {
devices_to_use.push_back(*it); devices_to_use.push_back(*it);
accepted_video = true; accepted_video = true;
} }
} }
// Fail the request if a device doesn't exist for the requested type. // Fail the request if a device doesn't exist for the requested type.
if ((request.audio_type != MEDIA_NO_SERVICE && !accepted_audio) || if ((request->audio_type != MEDIA_NO_SERVICE && !accepted_audio) ||
(request.video_type != MEDIA_NO_SERVICE && !accepted_video)) { (request->video_type != MEDIA_NO_SERVICE && !accepted_video)) {
devices_to_use.clear(); devices_to_use.clear();
} }
......
...@@ -38,7 +38,7 @@ class CONTENT_EXPORT MediaStreamUIProxy { ...@@ -38,7 +38,7 @@ class CONTENT_EXPORT MediaStreamUIProxy {
// WebContentsDelegate::RequestMediaAccessPermission(). The specified // WebContentsDelegate::RequestMediaAccessPermission(). The specified
// |response_callback| is called when the WebContentsDelegate approves or // |response_callback| is called when the WebContentsDelegate approves or
// denies request. // denies request.
virtual void RequestAccess(const MediaStreamRequest& request, virtual void RequestAccess(scoped_ptr<MediaStreamRequest> request,
const ResponseCallback& response_callback); const ResponseCallback& response_callback);
// Checks if we have permission to access the microphone or camera. Note that // Checks if we have permission to access the microphone or camera. Note that
...@@ -97,7 +97,7 @@ class CONTENT_EXPORT FakeMediaStreamUIProxy : public MediaStreamUIProxy { ...@@ -97,7 +97,7 @@ class CONTENT_EXPORT FakeMediaStreamUIProxy : public MediaStreamUIProxy {
void SetCameraAccess(bool access); void SetCameraAccess(bool access);
// MediaStreamUIProxy overrides. // MediaStreamUIProxy overrides.
void RequestAccess(const MediaStreamRequest& request, void RequestAccess(scoped_ptr<MediaStreamRequest> request,
const ResponseCallback& response_callback) override; const ResponseCallback& response_callback) override;
void CheckAccess(const GURL& security_origin, void CheckAccess(const GURL& security_origin,
MediaStreamType type, MediaStreamType type,
......
...@@ -17,8 +17,8 @@ using testing::Return; ...@@ -17,8 +17,8 @@ using testing::Return;
using testing::SaveArg; using testing::SaveArg;
namespace content { namespace content {
namespace {
namespace {
class MockRenderFrameHostDelegate : public RenderFrameHostDelegate { class MockRenderFrameHostDelegate : public RenderFrameHostDelegate {
public: public:
MOCK_METHOD2(RequestMediaAccessPermission, MOCK_METHOD2(RequestMediaAccessPermission,
...@@ -76,28 +76,31 @@ class MediaStreamUIProxyTest : public testing::Test { ...@@ -76,28 +76,31 @@ class MediaStreamUIProxyTest : public testing::Test {
MATCHER_P(SameRequest, expected, "") { MATCHER_P(SameRequest, expected, "") {
return return
expected.render_process_id == arg.render_process_id && expected->render_process_id == arg.render_process_id &&
expected.render_frame_id == arg.render_frame_id && expected->render_frame_id == arg.render_frame_id &&
expected.tab_capture_device_id == arg.tab_capture_device_id && expected->security_origin == arg.security_origin &&
expected.security_origin == arg.security_origin && expected->request_type == arg.request_type &&
expected.request_type == arg.request_type && expected->requested_audio_device_id == arg.requested_audio_device_id &&
expected.requested_audio_device_id == arg.requested_audio_device_id && expected->requested_video_device_id == arg.requested_video_device_id &&
expected.requested_video_device_id == arg.requested_video_device_id && expected->audio_type == arg.audio_type &&
expected.audio_type == arg.audio_type && expected->video_type == arg.video_type;
expected.video_type == arg.video_type;
} }
TEST_F(MediaStreamUIProxyTest, Deny) { TEST_F(MediaStreamUIProxyTest, Deny) {
MediaStreamRequest request(0, 0, 0, GURL("http://origin/"), false, scoped_ptr<MediaStreamRequest> request (
new MediaStreamRequest(0, 0, 0, GURL("http://origin/"),
false,
MEDIA_GENERATE_STREAM, std::string(), MEDIA_GENERATE_STREAM, std::string(),
std::string(), std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE, MEDIA_DEVICE_AUDIO_CAPTURE,
MEDIA_DEVICE_VIDEO_CAPTURE); MEDIA_DEVICE_VIDEO_CAPTURE));
MediaStreamRequest* request_ptr = request.get();
proxy_->RequestAccess( proxy_->RequestAccess(
request, base::Bind(&MockResponseCallback::OnAccessRequestResponse, request.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_))); base::Unretained(&response_callback_)));
MediaResponseCallback callback; MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _)) EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr),
_))
.WillOnce(SaveArg<1>(&callback)); .WillOnce(SaveArg<1>(&callback));
message_loop_.RunUntilIdle(); message_loop_.RunUntilIdle();
ASSERT_FALSE(callback.is_null()); ASSERT_FALSE(callback.is_null());
...@@ -114,16 +117,20 @@ TEST_F(MediaStreamUIProxyTest, Deny) { ...@@ -114,16 +117,20 @@ TEST_F(MediaStreamUIProxyTest, Deny) {
} }
TEST_F(MediaStreamUIProxyTest, AcceptAndStart) { TEST_F(MediaStreamUIProxyTest, AcceptAndStart) {
MediaStreamRequest request(0, 0, 0, GURL("http://origin/"), false, scoped_ptr<MediaStreamRequest> request (
new MediaStreamRequest(0, 0, 0,
GURL("http://origin/"), false,
MEDIA_GENERATE_STREAM, std::string(), MEDIA_GENERATE_STREAM, std::string(),
std::string(), std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE, MEDIA_DEVICE_AUDIO_CAPTURE,
MEDIA_DEVICE_VIDEO_CAPTURE); MEDIA_DEVICE_VIDEO_CAPTURE));
MediaStreamRequest* request_ptr = request.get();
proxy_->RequestAccess( proxy_->RequestAccess(
request, base::Bind(&MockResponseCallback::OnAccessRequestResponse, request.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_))); base::Unretained(&response_callback_)));
MediaResponseCallback callback; MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _)) EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr),
_))
.WillOnce(SaveArg<1>(&callback)); .WillOnce(SaveArg<1>(&callback));
message_loop_.RunUntilIdle(); message_loop_.RunUntilIdle();
ASSERT_FALSE(callback.is_null()); ASSERT_FALSE(callback.is_null());
...@@ -148,16 +155,20 @@ TEST_F(MediaStreamUIProxyTest, AcceptAndStart) { ...@@ -148,16 +155,20 @@ TEST_F(MediaStreamUIProxyTest, AcceptAndStart) {
// Verify that the proxy can be deleted before the request is processed. // Verify that the proxy can be deleted before the request is processed.
TEST_F(MediaStreamUIProxyTest, DeleteBeforeAccepted) { TEST_F(MediaStreamUIProxyTest, DeleteBeforeAccepted) {
MediaStreamRequest request(0, 0, 0, GURL("http://origin/"), false, scoped_ptr<MediaStreamRequest> request (
new MediaStreamRequest(0, 0, 0,
GURL("http://origin/"), false,
MEDIA_GENERATE_STREAM, std::string(), MEDIA_GENERATE_STREAM, std::string(),
std::string(), std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE, MEDIA_DEVICE_AUDIO_CAPTURE,
MEDIA_DEVICE_VIDEO_CAPTURE); MEDIA_DEVICE_VIDEO_CAPTURE));
MediaStreamRequest* request_ptr = request.get();
proxy_->RequestAccess( proxy_->RequestAccess(
request, base::Bind(&MockResponseCallback::OnAccessRequestResponse, request.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_))); base::Unretained(&response_callback_)));
MediaResponseCallback callback; MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _)) EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr)
, _))
.WillOnce(SaveArg<1>(&callback)); .WillOnce(SaveArg<1>(&callback));
message_loop_.RunUntilIdle(); message_loop_.RunUntilIdle();
ASSERT_FALSE(callback.is_null()); ASSERT_FALSE(callback.is_null());
...@@ -170,16 +181,20 @@ TEST_F(MediaStreamUIProxyTest, DeleteBeforeAccepted) { ...@@ -170,16 +181,20 @@ TEST_F(MediaStreamUIProxyTest, DeleteBeforeAccepted) {
} }
TEST_F(MediaStreamUIProxyTest, StopFromUI) { TEST_F(MediaStreamUIProxyTest, StopFromUI) {
MediaStreamRequest request(0, 0, 0, GURL("http://origin/"), false, scoped_ptr<MediaStreamRequest> request (
new MediaStreamRequest(0, 0, 0,
GURL("http://origin/"), false,
MEDIA_GENERATE_STREAM, std::string(), MEDIA_GENERATE_STREAM, std::string(),
std::string(), std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE, MEDIA_DEVICE_AUDIO_CAPTURE,
MEDIA_DEVICE_VIDEO_CAPTURE); MEDIA_DEVICE_VIDEO_CAPTURE));
MediaStreamRequest* request_ptr = request.get();
proxy_->RequestAccess( proxy_->RequestAccess(
request, base::Bind(&MockResponseCallback::OnAccessRequestResponse, request.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_))); base::Unretained(&response_callback_)));
MediaResponseCallback callback; MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _)) EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr)
, _))
.WillOnce(SaveArg<1>(&callback)); .WillOnce(SaveArg<1>(&callback));
message_loop_.RunUntilIdle(); message_loop_.RunUntilIdle();
ASSERT_FALSE(callback.is_null()); ASSERT_FALSE(callback.is_null());
...@@ -214,22 +229,22 @@ TEST_F(MediaStreamUIProxyTest, StopFromUI) { ...@@ -214,22 +229,22 @@ TEST_F(MediaStreamUIProxyTest, StopFromUI) {
} }
TEST_F(MediaStreamUIProxyTest, WindowIdCallbackCalled) { TEST_F(MediaStreamUIProxyTest, WindowIdCallbackCalled) {
MediaStreamRequest request(0, scoped_ptr<MediaStreamRequest> request (
0, new MediaStreamRequest(0, 0, 0,
0, GURL("http://origin/"), false,
GURL("http://origin/"), MEDIA_GENERATE_STREAM, std::string(),
false,
MEDIA_GENERATE_STREAM,
std::string(),
std::string(), std::string(),
MEDIA_NO_SERVICE, MEDIA_NO_SERVICE,
MEDIA_DESKTOP_VIDEO_CAPTURE); MEDIA_DESKTOP_VIDEO_CAPTURE));
MediaStreamRequest* request_ptr = request.get();
proxy_->RequestAccess( proxy_->RequestAccess(
request, request.Pass(),
base::Bind(&MockResponseCallback::OnAccessRequestResponse, base::Bind(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_))); base::Unretained(&response_callback_)));
MediaResponseCallback callback; MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _)) EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr),
_))
.WillOnce(SaveArg<1>(&callback)); .WillOnce(SaveArg<1>(&callback));
message_loop_.RunUntilIdle(); message_loop_.RunUntilIdle();
......
...@@ -103,7 +103,8 @@ MediaStreamRequest::MediaStreamRequest( ...@@ -103,7 +103,8 @@ MediaStreamRequest::MediaStreamRequest(
requested_audio_device_id(requested_audio_device_id), requested_audio_device_id(requested_audio_device_id),
requested_video_device_id(requested_video_device_id), requested_video_device_id(requested_video_device_id),
audio_type(audio_type), audio_type(audio_type),
video_type(video_type) { video_type(video_type),
all_ancestors_have_same_origin(false) {
} }
MediaStreamRequest::~MediaStreamRequest() {} MediaStreamRequest::~MediaStreamRequest() {}
......
...@@ -218,9 +218,6 @@ struct CONTENT_EXPORT MediaStreamRequest { ...@@ -218,9 +218,6 @@ struct CONTENT_EXPORT MediaStreamRequest {
// identifying this request. This is used for cancelling request. // identifying this request. This is used for cancelling request.
int page_request_id; int page_request_id;
// Used by tab capture.
std::string tab_capture_device_id;
// The WebKit security origin for the current request (e.g. "html5rocks.com"). // The WebKit security origin for the current request (e.g. "html5rocks.com").
GURL security_origin; GURL security_origin;
...@@ -242,6 +239,9 @@ struct CONTENT_EXPORT MediaStreamRequest { ...@@ -242,6 +239,9 @@ struct CONTENT_EXPORT MediaStreamRequest {
// Flag to indicate if the request contains video. // Flag to indicate if the request contains video.
MediaStreamType video_type; MediaStreamType video_type;
// True if all ancestors of the requesting frame have the same origin.
bool all_ancestors_have_same_origin;
}; };
// Interface used by the content layer to notify chrome about changes in the // Interface used by the content layer to notify chrome about changes in the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment