1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/renderer_host/media/desktop_capture_device_aura.h"
6
7#include "base/synchronization/waitable_event.h"
8#include "content/browser/browser_thread_impl.h"
9#include "content/public/browser/desktop_media_id.h"
10#include "media/video/capture/video_capture_types.h"
11#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
13#include "ui/aura/client/window_tree_client.h"
14#include "ui/aura/test/aura_test_helper.h"
15#include "ui/aura/test/test_window_delegate.h"
16#include "ui/aura/window.h"
17
18using ::testing::_;
19using ::testing::AnyNumber;
20using ::testing::DoAll;
21using ::testing::Expectation;
22using ::testing::InvokeWithoutArgs;
23using ::testing::SaveArg;
24
25namespace content {
26namespace {
27
28const int kFrameRate = 30;
29
30class MockDeviceClient : public media::VideoCaptureDevice::Client {
31 public:
32  MOCK_METHOD2(ReserveOutputBuffer,
33               scoped_refptr<Buffer>(media::VideoFrame::Format format,
34                                     const gfx::Size& dimensions));
35  MOCK_METHOD0(OnError, void());
36  MOCK_METHOD5(OnIncomingCapturedFrame,
37               void(const uint8* data,
38                    int length,
39                    base::Time timestamp,
40                    int rotation,
41                    const media::VideoCaptureFormat& frame_format));
42  MOCK_METHOD5(OnIncomingCapturedBuffer,
43               void(const scoped_refptr<Buffer>& buffer,
44                    media::VideoFrame::Format format,
45                    const gfx::Size& dimensions,
46                    base::Time timestamp,
47                    int frame_rate));
48};
49
50// Test harness that sets up a minimal environment with necessary stubs.
51class DesktopCaptureDeviceAuraTest : public testing::Test {
52 public:
53  DesktopCaptureDeviceAuraTest()
54      : browser_thread_for_ui_(BrowserThread::UI, &message_loop_) {}
55  virtual ~DesktopCaptureDeviceAuraTest() {}
56
57 protected:
58  virtual void SetUp() OVERRIDE {
59    helper_.reset(new aura::test::AuraTestHelper(&message_loop_));
60    helper_->SetUp();
61
62    // We need a window to cover desktop area so that DesktopCaptureDeviceAura
63    // can use gfx::NativeWindow::GetWindowAtScreenPoint() to locate the
64    // root window associated with the primary display.
65    gfx::Rect desktop_bounds = root_window()->bounds();
66    window_delegate_.reset(new aura::test::TestWindowDelegate());
67    desktop_window_.reset(new aura::Window(window_delegate_.get()));
68    desktop_window_->Init(ui::LAYER_TEXTURED);
69    desktop_window_->SetBounds(desktop_bounds);
70    aura::client::ParentWindowWithContext(
71        desktop_window_.get(), root_window(), desktop_bounds);
72    desktop_window_->Show();
73  }
74
75  virtual void TearDown() OVERRIDE {
76    helper_->RunAllPendingInMessageLoop();
77    root_window()->RemoveChild(desktop_window_.get());
78    desktop_window_.reset();
79    window_delegate_.reset();
80    helper_->TearDown();
81  }
82
83  aura::Window* root_window() { return helper_->root_window(); }
84
85 private:
86  base::MessageLoopForUI message_loop_;
87  BrowserThreadImpl browser_thread_for_ui_;
88  scoped_ptr<aura::test::AuraTestHelper> helper_;
89  scoped_ptr<aura::Window> desktop_window_;
90  scoped_ptr<aura::test::TestWindowDelegate> window_delegate_;
91
92  DISALLOW_COPY_AND_ASSIGN(DesktopCaptureDeviceAuraTest);
93};
94
95TEST_F(DesktopCaptureDeviceAuraTest, StartAndStop) {
96  scoped_ptr<media::VideoCaptureDevice> capture_device(
97      DesktopCaptureDeviceAura::Create(
98          content::DesktopMediaID::RegisterAuraWindow(root_window())));
99
100  scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
101  EXPECT_CALL(*client, OnError()).Times(0);
102
103  media::VideoCaptureParams capture_params;
104  capture_params.requested_format.frame_size.SetSize(640, 480);
105  capture_params.requested_format.frame_rate = kFrameRate;
106  capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
107  capture_params.allow_resolution_change = false;
108  capture_device->AllocateAndStart(
109      capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
110  capture_device->StopAndDeAllocate();
111}
112
113}  // namespace
114}  // namespace content
115