Fix DesktopAndCursorComposer not to crash
DesktopAndCursorComposer was crashing when screen/window
capturer returns a NULL frame due to an error.
BUG=crbug.com/344093
R=jiayl@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/8769004
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@5573 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/desktop_capture/desktop_and_cursor_composer.cc b/modules/desktop_capture/desktop_and_cursor_composer.cc
index 59d564e..05e2a9b 100644
--- a/modules/desktop_capture/desktop_and_cursor_composer.cc
+++ b/modules/desktop_capture/desktop_and_cursor_composer.cc
@@ -147,7 +147,7 @@
}
void DesktopAndCursorComposer::OnCaptureCompleted(DesktopFrame* frame) {
- if (cursor_.get() && cursor_state_ == MouseCursorMonitor::INSIDE) {
+ if (frame && cursor_.get() && cursor_state_ == MouseCursorMonitor::INSIDE) {
DesktopFrameWithCursor* frame_with_cursor =
new DesktopFrameWithCursor(frame, *cursor_, cursor_position_);
frame = frame_with_cursor;
diff --git a/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc b/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc
index 15d6f54..b482a29 100644
--- a/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc
+++ b/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc
@@ -58,6 +58,18 @@
return b + (g << 8) + (r << 16) + 0xff000000;
}
+DesktopFrame* CreateTestFrame() {
+ DesktopFrame* frame =
+ new BasicDesktopFrame(DesktopSize(kScreenWidth, kScreenHeight));
+ uint32_t* data = reinterpret_cast<uint32_t*>(frame->data());
+ for (int y = 0; y < kScreenHeight; ++y) {
+ for (int x = 0; x < kScreenWidth; ++x) {
+ *(data++) = GetFakeFramePixelValue(DesktopVector(x, y));
+ }
+ }
+ return frame;
+}
+
class FakeScreenCapturer : public DesktopCapturer {
public:
FakeScreenCapturer() {}
@@ -67,27 +79,17 @@
}
virtual void Capture(const DesktopRegion& region) OVERRIDE {
- DesktopFrame* frame =
- new BasicDesktopFrame(DesktopSize(kScreenWidth, kScreenHeight));
- uint32_t* data = reinterpret_cast<uint32_t*>(frame->data());
- for (int y = 0; y < kScreenHeight; ++y) {
- for (int x = 0; x < kScreenWidth; ++x) {
- *(data++) = GetFakeFramePixelValue(DesktopVector(x, y));
- }
- }
-
- last_frame_.reset(SharedDesktopFrame::Wrap(frame));
-
- callback_->OnCaptureCompleted(last_frame_->Share());
+ callback_->OnCaptureCompleted(next_frame_.release());
}
- // Returns last fake captured frame.
- SharedDesktopFrame* last_frame() { return last_frame_.get(); }
+ void SetNextFrame(DesktopFrame* next_frame) {
+ next_frame_.reset(next_frame);
+ }
private:
Callback* callback_;
- scoped_ptr<SharedDesktopFrame> last_frame_;
+ scoped_ptr<DesktopFrame> next_frame_;
};
class FakeMouseMonitor : public MouseCursorMonitor {
@@ -187,6 +189,20 @@
scoped_ptr<DesktopFrame> frame_;
};
+// Verify DesktopAndCursorComposer can handle the case when the screen capturer
+// fails.
+TEST_F(DesktopAndCursorComposerTest, Error) {
+ blender_.Start(this);
+
+ fake_cursor_->SetHotspot(DesktopVector());
+ fake_cursor_->SetState(MouseCursorMonitor::INSIDE, DesktopVector());
+ fake_screen_->SetNextFrame(NULL);
+
+ blender_.Capture(DesktopRegion());
+
+ EXPECT_EQ(frame_, static_cast<DesktopFrame*>(NULL));
+}
+
TEST_F(DesktopAndCursorComposerTest, Blend) {
struct {
int x, y;
@@ -222,6 +238,10 @@
DesktopVector pos(tests[i].x, tests[i].y);
fake_cursor_->SetState(state, pos);
+ scoped_ptr<SharedDesktopFrame> frame(
+ SharedDesktopFrame::Wrap(CreateTestFrame()));
+ fake_screen_->SetNextFrame(frame->Share());
+
blender_.Capture(DesktopRegion());
VerifyFrame(*frame_, state, pos);
@@ -229,9 +249,7 @@
// Verify that the cursor is erased before the frame buffer is returned to
// the screen capturer.
frame_.reset();
- VerifyFrame(*fake_screen_->last_frame(),
- MouseCursorMonitor::OUTSIDE,
- DesktopVector());
+ VerifyFrame(*frame, MouseCursorMonitor::OUTSIDE, DesktopVector());
}
}