Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: media/capture/service/video_capture_unittest.cc

Issue 1699553002: Mojo Video Capture service in media/capture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rockot@s comments Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "base/command_line.h"
6 #include "base/run_loop.h"
7 #include "media/base/media_switches.h"
8 #include "media/capture/interfaces/video_capture.mojom.h"
9 #include "media/capture/service/mock_stream_client.h"
10 #include "media/capture/service/stream_impl.h"
11 #include "media/capture/service/video_capture_handler_impl.h"
12 #include "media/capture/video/fake_video_capture_device_factory.h"
13 #include "mojo/converters/geometry/geometry_type_converters.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 #if defined(OS_MACOSX)
18 #include "media/base/mac/avfoundation_glue.h"
19 #endif
20
21 using ::testing::_;
22 using ::testing::AnyNumber;
23 using ::testing::InSequence;
24 using ::testing::Field;
25
26 namespace media {
27
28 namespace {
29
30 ACTION_P(RunClosure, closure) {
31 closure.Run();
32 }
33
34 void UseFakeFactory() {
35 base::CommandLine::ForCurrentProcess()->AppendSwitch(
36 switches::kUseFakeDeviceForMediaStream);
37 }
38
39 void UseRealFactory() {
40 #if defined(OS_MACOSX)
41 AVFoundationGlue::InitializeAVFoundation();
42 #endif
43 }
44
45 } // anonymous namespace
46
47 // This test coalesces all the classes and objects that conform a video capture
48 // component from the outside. It then exercises the .mojom interfaces.
49 // TODO(mcasas): This test is an integration test of sorts, but we use
50 // a VideoCaptureHandlerImpl class directly and not via a Mojo pipe. Remove this
51 // test when an VideoCapture Mojo App (i.e. a truly black box) test is landed.
52 class VideoCaptureTest : public ::testing::Test {
53 public:
54 VideoCaptureTest() {}
55
56 void InitializeVideoCaptureHandlerImpl() {
57 video_capture_handler_impl_.reset(
58 new VideoCaptureHandlerImpl(nullptr /* app */));
59 base::RunLoop().RunUntilIdle();
60 }
61
62 void RequestMediaDevices(
63 const VideoCaptureHandlerImpl::RequestMediaDevicesCallback& callback) {
64 video_capture_handler_impl_->RequestMediaDevices(callback);
65 }
66
67 MOCK_METHOD0(DoOnRequestMediaDevicesReply, void(void));
68 void OnRequestMediaDevicesReply(mojo::Array<mojom::WebSourceInfoPtr> reply) {
69 DoOnRequestMediaDevicesReply();
70 media_devices_info_ = std::move(reply);
71 }
72
73 MOCK_METHOD1(DoOnRequestStreamReply, void(const mojom::Stream&));
74 void OnRequestStreamReply(mojom::StreamPtr stream) {
75 EXPECT_TRUE(stream.is_bound());
76 DoOnRequestStreamReply(*stream);
77 stream_ = std::move(stream);
78 }
79
80 // Enumerate devices to get a valid |id| for the first one.
81 void EnumerateDevices() {
82 VideoCaptureHandlerImpl::RequestMediaDevicesCallback callback = base::Bind(
83 &VideoCaptureTest::OnRequestMediaDevicesReply, base::Unretained(this));
84
85 base::RunLoop run_loop;
86 base::Closure quit_closure = run_loop.QuitClosure();
87 EXPECT_CALL(*this, DoOnRequestMediaDevicesReply())
88 .Times(1)
89 .WillOnce(RunClosure(quit_closure));
90 RequestMediaDevices(std::move(callback));
91
92 run_loop.Run();
93 }
94
95 // This block runs a RequestStream() --> get a Stream().
96 void RequestStream() {
97 mojom::StreamOptionsPtr options = mojom::StreamOptions::New();
98 options->device_id = media_devices_info_[0]->device_id;
99 options->capture_size = mojo::Size::From(gfx::Size(320, 240));
100 options->frame_rate = 30.0;
101
102 VideoCaptureHandlerImpl::RequestStreamCallback callback = base::Bind(
103 &VideoCaptureTest::OnRequestStreamReply, base::Unretained(this));
104 base::RunLoop run_loop;
105 base::Closure quit_closure = run_loop.QuitClosure();
106
107 EXPECT_CALL(*this, DoOnRequestStreamReply(_))
108 .Times(1)
109 .WillOnce(RunClosure(quit_closure));
110
111 video_capture_handler_impl_->RequestStream(
112 std::move(options), "https://localhost", std::move(callback));
113 run_loop.Run();
114 ASSERT_TRUE(!!stream_.get());
115 }
116
117 // Call Stream::Start() and expect some frames.
118 void StartAndExpectFrames() {
119 base::RunLoop run_loop;
120 base::Closure quit_closure = run_loop.QuitClosure();
121
122 EXPECT_CALL(stream_client_impl_, DoFrameAvailable(_, _)).Times(3);
123 EXPECT_CALL(stream_client_impl_, DoFrameAvailable(_, _))
124 .Times(1)
125 .WillOnce(RunClosure(quit_closure));
126 stream_->Start(stream_client_impl_.CreateProxy());
127
128 run_loop.Run();
129 }
130
131 void StartAndExpectFramesAndError() {
132 base::RunLoop run_loop;
133 base::Closure quit_closure = run_loop.QuitClosure();
134
135 EXPECT_CALL(stream_client_impl_, DoFrameAvailable(_, _)).Times(AnyNumber());
136 stream_->Start(stream_client_impl_.CreateProxy());
137
138 EXPECT_CALL(stream_client_impl_, Error(_))
139 .Times(1)
140 .WillOnce(RunClosure(quit_closure));
141
142 // Access the first and only StreamImpl and ping its OnError() callback.
143 ASSERT_EQ(1u, video_capture_handler_impl_->device_and_streams_.size());
144 video_capture_handler_impl_->device_and_streams_.begin()
145 ->second.second->OnError("Terrible error");
146 run_loop.Run();
147 }
148
149 void FakeOnErrorFromDevice() {}
150
151 protected:
152 // Needed for the mojo::ApplicationImpl inside VideoCaptureHandlerImpl.
153 const base::MessageLoop loop_;
154
155 // Need a SystemMonitor for VideoCaptureHandlerImpl to register to.
156 base::SystemMonitor system_monitor_;
157
158 // The component's entry point. Needs to be a scoped_ptr to be initialized
159 // after adding command line flag for the appropriate Device Factory.
160 scoped_ptr<VideoCaptureHandlerImpl> video_capture_handler_impl_;
161
162 // The mock of the (remote) video capture client.
163 MockStreamClient stream_client_impl_;
164
165 // Local pointer to the generated Stream spitting VideoFrames.
166 mojom::StreamPtr stream_;
167
168 // Variable to hold on to the returned list of enumerated devices.
169 mojo::Array<mojom::WebSourceInfoPtr> media_devices_info_;
170
171 private:
172 DISALLOW_COPY_AND_ASSIGN(VideoCaptureTest);
173 };
174
175 TEST_F(VideoCaptureTest, CreateAndDestroy) {}
176
177 // Tests a full cycle RequestMediaDevices() -> RequestMediaDevicesReply ->
178 // RequestStream()-> RequestStreamReply -> Start() -> get frames.
179 // This test uses a FakeVideoCaptureDeviceFactory and succeeds all right.
180 TEST_F(VideoCaptureTest, RequestStreamAndStartAndCapture) {
181 InSequence s;
182 UseFakeFactory();
183 InitializeVideoCaptureHandlerImpl();
184 EnumerateDevices();
185 RequestStream();
186
187 StartAndExpectFrames();
188 stream_->Stop();
189 }
190
191 // Tests a full cycle RequestMediaDevices() -> RequestMediaDevicesReply ->
192 // RequestStream()-> RequestStreamReply -> Start() -> Error !!!.
193 TEST_F(VideoCaptureTest, RequestStreamAndStartAndError) {
194 InSequence s;
195 UseFakeFactory();
196 InitializeVideoCaptureHandlerImpl();
197 EnumerateDevices();
198 RequestStream();
199
200 StartAndExpectFramesAndError();
201 stream_->Stop();
202 }
203
204 // Same as RequestStreamAndStartAndCapture, with a real capture device.
205 TEST_F(VideoCaptureTest, RequestStreamAndStartAndCaptureWithRealDevice) {
206 InSequence s;
207
208 UseRealFactory();
209 InitializeVideoCaptureHandlerImpl();
210 EnumerateDevices();
211 if (media_devices_info_.size() == 0u) // No real devices.
212 return;
213 RequestStream();
214
215 StartAndExpectFrames();
216 stream_->Stop();
217 }
218
219 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698