blob: 82219a6e8727fe989b2f8ed56e8485a47cc2ea74 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "base/message_loop/message_loop.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect.h"
using testing::_;
using testing::SaveArg;
namespace content {
namespace {
class MockRenderViewHostDelegate : public RenderViewHostDelegate {
public:
MOCK_METHOD2(RequestMediaAccessPermission,
void(const MediaStreamRequest& request,
const MediaResponseCallback& callback));
// Stubs for pure virtual methods we don't care about.
virtual gfx::Rect GetRootWindowResizerRect() const OVERRIDE {
NOTREACHED();
return gfx::Rect();
}
virtual RendererPreferences GetRendererPrefs(
BrowserContext* browser_context) const OVERRIDE {
NOTREACHED();
return RendererPreferences();
}
};
class MockResponseCallback {
public:
MOCK_METHOD1(OnAccessRequestResponse,
void(const MediaStreamDevices& devices));
};
class MockMediaStreamUI : public MediaStreamUI {
public:
MOCK_METHOD1(OnStarted, void(const base::Closure& stop));
};
class MockStopStreamHandler {
public:
MOCK_METHOD0(OnStop, void());
};
} // namespace
class MediaStreamUIProxyTest : public testing::Test {
public:
MediaStreamUIProxyTest()
: ui_thread_(BrowserThread::UI, &message_loop_),
io_thread_(BrowserThread::IO, &message_loop_) {
proxy_ = MediaStreamUIProxy::CreateForTests(&delegate_);
}
virtual ~MediaStreamUIProxyTest() {
proxy_.reset();
message_loop_.RunUntilIdle();
}
protected:
base::MessageLoop message_loop_;
TestBrowserThread ui_thread_;
TestBrowserThread io_thread_;
MockRenderViewHostDelegate delegate_;
MockResponseCallback response_callback_;
scoped_ptr<MediaStreamUIProxy> proxy_;
};
MATCHER_P(SameRequest, expected, "") {
return
expected.render_process_id == arg.render_process_id &&
expected.render_view_id == arg.render_view_id &&
expected.tab_capture_device_id == arg.tab_capture_device_id &&
expected.security_origin == arg.security_origin &&
expected.request_type == arg.request_type &&
expected.requested_audio_device_id == arg.requested_audio_device_id &&
expected.requested_video_device_id == arg.requested_video_device_id &&
expected.audio_type == arg.audio_type &&
expected.video_type == arg.video_type;
}
TEST_F(MediaStreamUIProxyTest, Deny) {
MediaStreamRequest request(0, 0, 0, std::string(), GURL("http://origin/"),
MEDIA_GENERATE_STREAM, std::string(),
std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE,
MEDIA_DEVICE_VIDEO_CAPTURE);
proxy_->RequestAccess(
request, base::Bind(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_)));
MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _))
.WillOnce(SaveArg<1>(&callback));
message_loop_.RunUntilIdle();
ASSERT_FALSE(callback.is_null());
MediaStreamDevices devices;
callback.Run(devices, scoped_ptr<MediaStreamUI>());
MediaStreamDevices response;
EXPECT_CALL(response_callback_, OnAccessRequestResponse(_))
.WillOnce(SaveArg<0>(&response));
message_loop_.RunUntilIdle();
EXPECT_TRUE(response.empty());
}
TEST_F(MediaStreamUIProxyTest, AcceptAndStart) {
MediaStreamRequest request(0, 0, 0, std::string(), GURL("http://origin/"),
MEDIA_GENERATE_STREAM, std::string(),
std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE,
MEDIA_DEVICE_VIDEO_CAPTURE);
proxy_->RequestAccess(
request, base::Bind(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_)));
MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _))
.WillOnce(SaveArg<1>(&callback));
message_loop_.RunUntilIdle();
ASSERT_FALSE(callback.is_null());
MediaStreamDevices devices;
devices.push_back(
MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "Mic", "Mic"));
scoped_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
EXPECT_CALL(*ui, OnStarted(_));
callback.Run(devices, ui.PassAs<MediaStreamUI>());
MediaStreamDevices response;
EXPECT_CALL(response_callback_, OnAccessRequestResponse(_))
.WillOnce(SaveArg<0>(&response));
message_loop_.RunUntilIdle();
EXPECT_FALSE(response.empty());
proxy_->OnStarted(base::Closure());
message_loop_.RunUntilIdle();
}
// Verify that the proxy can be deleted before the request is processed.
TEST_F(MediaStreamUIProxyTest, DeleteBeforeAccepted) {
MediaStreamRequest request(0, 0, 0, std::string(), GURL("http://origin/"),
MEDIA_GENERATE_STREAM, std::string(),
std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE,
MEDIA_DEVICE_VIDEO_CAPTURE);
proxy_->RequestAccess(
request, base::Bind(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_)));
MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _))
.WillOnce(SaveArg<1>(&callback));
message_loop_.RunUntilIdle();
ASSERT_FALSE(callback.is_null());
proxy_.reset();
MediaStreamDevices devices;
scoped_ptr<MediaStreamUI> ui;
callback.Run(devices, ui.Pass());
}
TEST_F(MediaStreamUIProxyTest, StopFromUI) {
MediaStreamRequest request(0, 0, 0, std::string(), GURL("http://origin/"),
MEDIA_GENERATE_STREAM, std::string(),
std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE,
MEDIA_DEVICE_VIDEO_CAPTURE);
proxy_->RequestAccess(
request, base::Bind(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_)));
MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _))
.WillOnce(SaveArg<1>(&callback));
message_loop_.RunUntilIdle();
ASSERT_FALSE(callback.is_null());
base::Closure stop_callback;
MediaStreamDevices devices;
devices.push_back(
MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "Mic", "Mic"));
scoped_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
EXPECT_CALL(*ui, OnStarted(_))
.WillOnce(SaveArg<0>(&stop_callback));
callback.Run(devices, ui.PassAs<MediaStreamUI>());
MediaStreamDevices response;
EXPECT_CALL(response_callback_, OnAccessRequestResponse(_))
.WillOnce(SaveArg<0>(&response));
message_loop_.RunUntilIdle();
EXPECT_FALSE(response.empty());
MockStopStreamHandler stop_handler;
proxy_->OnStarted(base::Bind(&MockStopStreamHandler::OnStop,
base::Unretained(&stop_handler)));
message_loop_.RunUntilIdle();
ASSERT_FALSE(stop_callback.is_null());
EXPECT_CALL(stop_handler, OnStop());
stop_callback.Run();
message_loop_.RunUntilIdle();
}
} // content