Index: remoting/host/video_scheduler_unittest.cc |
diff --git a/remoting/host/video_scheduler_unittest.cc b/remoting/host/video_scheduler_unittest.cc |
index 3d7375e811dc3b2ffab8d45b1f6beb7fa9d47ab9..adf19231649f766d0e614cf447ce4308f4350741 100644 |
--- a/remoting/host/video_scheduler_unittest.cc |
+++ b/remoting/host/video_scheduler_unittest.cc |
@@ -10,13 +10,18 @@ |
#include "base/single_thread_task_runner.h" |
#include "remoting/base/auto_thread.h" |
#include "remoting/base/auto_thread_task_runner.h" |
+#include "remoting/codec/video_encoder.h" |
#include "remoting/codec/video_encoder_verbatim.h" |
+#include "remoting/host/fake_mouse_cursor_monitor.h" |
#include "remoting/host/fake_screen_capturer.h" |
+#include "remoting/host/host_mock_objects.h" |
+#include "remoting/proto/control.pb.h" |
#include "remoting/proto/video.pb.h" |
#include "remoting/protocol/protocol_mock_objects.h" |
#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
+#include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h" |
#include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h" |
using ::remoting::protocol::MockClientStub; |
@@ -51,6 +56,10 @@ ACTION(FinishSend) { |
static const int kWidth = 640; |
static const int kHeight = 480; |
+static const int kCursorWidth = 64; |
+static const int kCursorHeight = 32; |
+static const int kHotspotX = 11; |
+static const int kHotspotY = 12; |
class MockVideoEncoder : public VideoEncoder { |
public: |
@@ -99,6 +108,22 @@ class ThreadCheckScreenCapturer : public FakeScreenCapturer { |
DISALLOW_COPY_AND_ASSIGN(ThreadCheckScreenCapturer); |
}; |
+class ThreadCheckMouseCursorMonitor : public FakeMouseCursorMonitor { |
+ public: |
+ ThreadCheckMouseCursorMonitor( |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
+ : task_runner_(task_runner) { |
+ } |
+ virtual ~ThreadCheckMouseCursorMonitor() { |
+ EXPECT_TRUE(task_runner_->BelongsToCurrentThread()); |
+ } |
+ |
+ private: |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ThreadCheckMouseCursorMonitor); |
+}; |
+ |
class VideoSchedulerTest : public testing::Test { |
public: |
VideoSchedulerTest(); |
@@ -108,12 +133,18 @@ class VideoSchedulerTest : public testing::Test { |
void StartVideoScheduler( |
scoped_ptr<webrtc::ScreenCapturer> capturer, |
- scoped_ptr<VideoEncoder> encoder); |
+ scoped_ptr<VideoEncoder> encoder, |
+ scoped_ptr<webrtc::MouseCursorMonitor> mouse_monitor); |
void StopVideoScheduler(); |
// webrtc::ScreenCapturer mocks. |
void OnCapturerStart(webrtc::ScreenCapturer::Callback* callback); |
void OnCaptureFrame(const webrtc::DesktopRegion& region); |
+ void OnMouseCursorMonitorInit( |
+ webrtc::MouseCursorMonitor::Callback* callback, |
+ webrtc::MouseCursorMonitor::Mode mode); |
+ void OnCaptureMouse(); |
+ void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape); |
protected: |
base::MessageLoop message_loop_; |
@@ -126,17 +157,19 @@ class VideoSchedulerTest : public testing::Test { |
MockClientStub client_stub_; |
MockVideoStub video_stub_; |
- scoped_ptr<webrtc::DesktopFrame> frame_; |
- |
// Points to the callback passed to webrtc::ScreenCapturer::Start(). |
webrtc::ScreenCapturer::Callback* capturer_callback_; |
+ // Points to the callback passed to webrtc::MouseCursor::Init(). |
+ webrtc::MouseCursorMonitor::Callback* mouse_monitor_callback_; |
+ |
private: |
DISALLOW_COPY_AND_ASSIGN(VideoSchedulerTest); |
}; |
VideoSchedulerTest::VideoSchedulerTest() |
- : capturer_callback_(NULL) { |
+ : capturer_callback_(NULL), |
+ mouse_monitor_callback_(NULL) { |
} |
void VideoSchedulerTest::SetUp() { |
@@ -158,12 +191,14 @@ void VideoSchedulerTest::TearDown() { |
void VideoSchedulerTest::StartVideoScheduler( |
scoped_ptr<webrtc::ScreenCapturer> capturer, |
- scoped_ptr<VideoEncoder> encoder) { |
+ scoped_ptr<VideoEncoder> encoder, |
+ scoped_ptr<webrtc::MouseCursorMonitor> mouse_monitor) { |
scheduler_ = new VideoScheduler( |
capture_task_runner_, |
encode_task_runner_, |
main_task_runner_, |
capturer.Pass(), |
+ mouse_monitor.Pass(), |
encoder.Pass(), |
&client_stub_, |
&video_stub_); |
@@ -184,9 +219,47 @@ void VideoSchedulerTest::OnCapturerStart( |
} |
void VideoSchedulerTest::OnCaptureFrame(const webrtc::DesktopRegion& region) { |
- frame_->mutable_updated_region()->SetRect( |
+ scoped_ptr<webrtc::DesktopFrame> frame( |
+ new webrtc::BasicDesktopFrame(webrtc::DesktopSize(kWidth, kHeight))); |
+ frame->mutable_updated_region()->SetRect( |
webrtc::DesktopRect::MakeXYWH(0, 0, 10, 10)); |
- capturer_callback_->OnCaptureCompleted(frame_.release()); |
+ capturer_callback_->OnCaptureCompleted(frame.release()); |
+} |
+ |
+void VideoSchedulerTest::OnCaptureMouse() { |
+ EXPECT_TRUE(mouse_monitor_callback_); |
+ |
+ scoped_ptr<webrtc::MouseCursor> mouse_cursor( |
+ new webrtc::MouseCursor( |
+ new webrtc::BasicDesktopFrame( |
+ webrtc::DesktopSize(kCursorWidth, kCursorHeight)), |
+ webrtc::DesktopVector(kHotspotX, kHotspotY))); |
+ |
+ mouse_monitor_callback_->OnMouseCursor(mouse_cursor.release()); |
+} |
+ |
+void VideoSchedulerTest::OnMouseCursorMonitorInit( |
+ webrtc::MouseCursorMonitor::Callback* callback, |
+ webrtc::MouseCursorMonitor::Mode mode) { |
+ EXPECT_FALSE(mouse_monitor_callback_); |
+ EXPECT_TRUE(callback); |
+ |
+ mouse_monitor_callback_ = callback; |
+} |
+ |
+void VideoSchedulerTest::SetCursorShape( |
+ const protocol::CursorShapeInfo& cursor_shape) { |
+ EXPECT_TRUE(cursor_shape.has_width()); |
+ EXPECT_EQ(kCursorWidth, cursor_shape.width()); |
+ EXPECT_TRUE(cursor_shape.has_height()); |
+ EXPECT_EQ(kCursorHeight, cursor_shape.height()); |
+ EXPECT_TRUE(cursor_shape.has_hotspot_x()); |
+ EXPECT_EQ(kHotspotX, cursor_shape.hotspot_x()); |
+ EXPECT_TRUE(cursor_shape.has_hotspot_y()); |
+ EXPECT_EQ(kHotspotY, cursor_shape.hotspot_y()); |
+ EXPECT_TRUE(cursor_shape.has_data()); |
+ EXPECT_EQ(kCursorWidth * kCursorHeight * webrtc::DesktopFrame::kBytesPerPixel, |
+ static_cast<int>(cursor_shape.data().size())); |
} |
// This test mocks capturer, encoder and network layer to simulate one capture |
@@ -196,13 +269,24 @@ void VideoSchedulerTest::OnCaptureFrame(const webrtc::DesktopRegion& region) { |
TEST_F(VideoSchedulerTest, StartAndStop) { |
scoped_ptr<webrtc::MockScreenCapturer> capturer( |
new webrtc::MockScreenCapturer()); |
+ scoped_ptr<MockMouseCursorMonitor> cursor_monitor( |
+ new MockMouseCursorMonitor()); |
+ |
+ { |
+ InSequence s; |
+ |
+ EXPECT_CALL(*cursor_monitor, Init(_, _)) |
+ .WillOnce( |
+ Invoke(this, &VideoSchedulerTest::OnMouseCursorMonitorInit)); |
+ |
+ EXPECT_CALL(*cursor_monitor, Capture()) |
+ .WillRepeatedly(Invoke(this, &VideoSchedulerTest::OnCaptureMouse)); |
+ } |
+ |
Expectation capturer_start = |
EXPECT_CALL(*capturer, Start(_)) |
.WillOnce(Invoke(this, &VideoSchedulerTest::OnCapturerStart)); |
- frame_.reset(new webrtc::BasicDesktopFrame( |
- webrtc::DesktopSize(kWidth, kHeight))); |
- |
// First the capturer is called. |
Expectation capturer_capture = EXPECT_CALL(*capturer, Capture(_)) |
.After(capturer_start) |
@@ -225,24 +309,39 @@ TEST_F(VideoSchedulerTest, StartAndStop) { |
InvokeWithoutArgs(this, &VideoSchedulerTest::StopVideoScheduler))) |
.RetiresOnSaturation(); |
+ EXPECT_CALL(client_stub_, SetCursorShape(_)) |
+ .WillOnce(Invoke(this, &VideoSchedulerTest::SetCursorShape)); |
+ |
// Start video frame capture. |
+ scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor( |
+ new FakeMouseCursorMonitor()); |
StartVideoScheduler(capturer.PassAs<webrtc::ScreenCapturer>(), |
- encoder.PassAs<VideoEncoder>()); |
+ encoder.PassAs<VideoEncoder>(), |
+ cursor_monitor.PassAs<webrtc::MouseCursorMonitor>()); |
+ |
+ // Run until there are no more pending tasks from the VideoScheduler. |
+ // Otherwise, a lingering frame capture might attempt to trigger a capturer |
+ // expectation action and crash. |
+ base::RunLoop().RunUntilIdle(); |
} |
-// Verify that the capturer and encoder are torn down on the correct threads. |
+// Verify that the capturer, encoder and mouse monitor are torn down on the |
+// correct threads. |
TEST_F(VideoSchedulerTest, DeleteOnThreads) { |
-capture_task_runner_ = AutoThread::Create("capture", main_task_runner_); |
-encode_task_runner_ = AutoThread::Create("encode", main_task_runner_); |
+ capture_task_runner_ = AutoThread::Create("capture", main_task_runner_); |
+ encode_task_runner_ = AutoThread::Create("encode", main_task_runner_); |
scoped_ptr<webrtc::ScreenCapturer> capturer( |
new ThreadCheckScreenCapturer(capture_task_runner_)); |
scoped_ptr<VideoEncoder> encoder( |
new ThreadCheckVideoEncoder(encode_task_runner_)); |
+ scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor( |
+ new ThreadCheckMouseCursorMonitor(capture_task_runner_)); |
- // Start and stop the scheduler, so it will tear down the screen capturer and |
- // video encoder. |
- StartVideoScheduler(capturer.Pass(), encoder.Pass()); |
+ // Start and stop the scheduler, so it will tear down the screen capturer, |
+ // video encoder and mouse monitor. |
+ StartVideoScheduler(capturer.Pass(), encoder.Pass(), |
+ mouse_cursor_monitor.Pass()); |
StopVideoScheduler(); |
} |