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

Side by Side Diff: content/browser/renderer_host/media/video_capture_manager_unittest.cc

Issue 2365223002: Video Capture: Allow suspension of individual devices. (Closed)
Patch Set: Style tweaks, per mcasas's comments. Created 4 years, 2 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Unit test for VideoCaptureManager. 5 // Unit test for VideoCaptureManager.
6 6
7 #include "content/browser/renderer_host/media/video_capture_manager.h" 7 #include "content/browser/renderer_host/media/video_capture_manager.h"
8 8
9 #include <stdint.h> 9 #include <stdint.h>
10 10
11 #include <algorithm>
11 #include <memory> 12 #include <memory>
12 #include <string> 13 #include <string>
14 #include <vector>
13 15
14 #include "base/bind.h" 16 #include "base/bind.h"
15 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/memory/ptr_util.h"
16 #include "base/memory/ref_counted.h" 19 #include "base/memory/ref_counted.h"
17 #include "base/run_loop.h" 20 #include "base/run_loop.h"
18 #include "content/browser/browser_thread_impl.h" 21 #include "content/browser/browser_thread_impl.h"
19 #include "content/browser/renderer_host/media/media_stream_provider.h" 22 #include "content/browser/renderer_host/media/media_stream_provider.h"
20 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h" 23 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h"
21 #include "content/common/media/media_stream_options.h" 24 #include "content/common/media/media_stream_options.h"
22 #include "media/capture/video/fake_video_capture_device_factory.h" 25 #include "media/capture/video/fake_video_capture_device_factory.h"
23 #include "testing/gmock/include/gmock/gmock.h" 26 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
25 28
26 using ::testing::_; 29 using ::testing::_;
27 using ::testing::AnyNumber; 30 using ::testing::AnyNumber;
28 using ::testing::DoAll; 31 using ::testing::DoAll;
29 using ::testing::InSequence; 32 using ::testing::InSequence;
30 using ::testing::InvokeWithoutArgs; 33 using ::testing::InvokeWithoutArgs;
31 using ::testing::Return; 34 using ::testing::Return;
32 using ::testing::SaveArg; 35 using ::testing::SaveArg;
33 36
34 namespace content { 37 namespace content {
35 38
39 namespace {
40
41 // Wraps FakeVideoCaptureDeviceFactory to allow mocking of the
42 // VideoCaptureDevice MaybeSuspend() and Resume() methods. This is used to check
43 // that devices are asked to suspend or resume at the correct times.
44 class WrappedDeviceFactory : public media::FakeVideoCaptureDeviceFactory {
45 public:
46 class WrappedDevice : public media::VideoCaptureDevice {
47 public:
48 WrappedDevice(std::unique_ptr<media::VideoCaptureDevice> device,
49 WrappedDeviceFactory* factory)
50 : device_(std::move(device)), factory_(factory) {
51 factory_->OnDeviceCreated(this);
52 }
53
54 ~WrappedDevice() final {
55 factory_->OnDeviceDestroyed(this);
56 }
57
58 void AllocateAndStart(const media::VideoCaptureParams& params,
59 std::unique_ptr<Client> client) final {
60 device_->AllocateAndStart(params, std::move(client));
61 }
62
63 void RequestRefreshFrame() final {
64 device_->RequestRefreshFrame();
65 }
66
67 void MaybeSuspend() final {
68 factory_->WillSuspendDevice();
69 device_->MaybeSuspend();
70 }
71
72 void Resume() final {
73 factory_->WillResumeDevice();
74 device_->Resume();
75 }
76
77 void StopAndDeAllocate() final {
78 device_->StopAndDeAllocate();
79 }
80
81 void GetPhotoCapabilities(GetPhotoCapabilitiesCallback callback) final {
82 device_->GetPhotoCapabilities(std::move(callback));
83 }
84
85 void TakePhoto(TakePhotoCallback callback) final {
86 device_->TakePhoto(std::move(callback));
87 }
88
89 private:
90 const std::unique_ptr<media::VideoCaptureDevice> device_;
91 WrappedDeviceFactory* const factory_;
92
93 DISALLOW_COPY_AND_ASSIGN(WrappedDevice);
94 };
95
96 WrappedDeviceFactory() : FakeVideoCaptureDeviceFactory() {}
97 ~WrappedDeviceFactory() final {}
98
99 std::unique_ptr<media::VideoCaptureDevice> CreateDevice(
100 const media::VideoCaptureDeviceDescriptor& device_descriptor) final {
101 return base::MakeUnique<WrappedDevice>(
102 FakeVideoCaptureDeviceFactory::CreateDevice(device_descriptor), this);
103 }
104
105 MOCK_METHOD0(WillSuspendDevice, void());
106 MOCK_METHOD0(WillResumeDevice, void());
107
108 private:
109 void OnDeviceCreated(WrappedDevice* device) {
110 devices_.push_back(device);
111 }
112
113 void OnDeviceDestroyed(WrappedDevice* device) {
114 const auto it = std::find(devices_.begin(), devices_.end(), device);
115 CHECK(it != devices_.end());
116 devices_.erase(it);
117 }
118
119 std::vector<WrappedDevice*> devices_;
120
121 DISALLOW_COPY_AND_ASSIGN(WrappedDeviceFactory);
122 };
123
36 // Listener class used to track progress of VideoCaptureManager test. 124 // Listener class used to track progress of VideoCaptureManager test.
37 class MockMediaStreamProviderListener : public MediaStreamProviderListener { 125 class MockMediaStreamProviderListener : public MediaStreamProviderListener {
38 public: 126 public:
39 MockMediaStreamProviderListener() {} 127 MockMediaStreamProviderListener() {}
40 ~MockMediaStreamProviderListener() {} 128 ~MockMediaStreamProviderListener() {}
41 129
42 MOCK_METHOD2(Opened, void(MediaStreamType, int)); 130 MOCK_METHOD2(Opened, void(MediaStreamType, int));
43 MOCK_METHOD2(Closed, void(MediaStreamType, int)); 131 MOCK_METHOD2(Closed, void(MediaStreamType, int));
44 MOCK_METHOD2(Aborted, void(MediaStreamType, int)); 132 MOCK_METHOD2(Aborted, void(MediaStreamType, int));
45 }; // class MockMediaStreamProviderListener 133 }; // class MockMediaStreamProviderListener
(...skipping 12 matching lines...) Expand all
58 int buffer_id) override {} 146 int buffer_id) override {}
59 void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override {} 147 void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override {}
60 void OnBufferReady(VideoCaptureControllerID id, 148 void OnBufferReady(VideoCaptureControllerID id,
61 int buffer_id, 149 int buffer_id,
62 const scoped_refptr<media::VideoFrame>& frame) override {} 150 const scoped_refptr<media::VideoFrame>& frame) override {}
63 void OnEnded(VideoCaptureControllerID id) override {} 151 void OnEnded(VideoCaptureControllerID id) override {}
64 152
65 void OnGotControllerCallback(VideoCaptureControllerID) {} 153 void OnGotControllerCallback(VideoCaptureControllerID) {}
66 }; 154 };
67 155
156 } // namespace
157
68 // Test class 158 // Test class
69 class VideoCaptureManagerTest : public testing::Test { 159 class VideoCaptureManagerTest : public testing::Test {
70 public: 160 public:
71 VideoCaptureManagerTest() : next_client_id_(1) {} 161 VideoCaptureManagerTest() : next_client_id_(1) {}
72 ~VideoCaptureManagerTest() override {} 162 ~VideoCaptureManagerTest() override {}
73 163
74 void HandleEnumerationResult( 164 void HandleEnumerationResult(
75 const base::Closure& quit_closure, 165 const base::Closure& quit_closure,
76 const media::VideoCaptureDeviceDescriptors& descriptors) { 166 const media::VideoCaptureDeviceDescriptors& descriptors) {
77 StreamDeviceInfoArray devices; 167 StreamDeviceInfoArray devices;
78 for (const auto& descriptor : descriptors) { 168 for (const auto& descriptor : descriptors) {
79 devices.emplace_back(MEDIA_DEVICE_VIDEO_CAPTURE, 169 devices.emplace_back(MEDIA_DEVICE_VIDEO_CAPTURE,
80 descriptor.GetNameAndModel(), descriptor.device_id); 170 descriptor.GetNameAndModel(), descriptor.device_id);
81 } 171 }
82 devices_ = std::move(devices); 172 devices_ = std::move(devices);
83 quit_closure.Run(); 173 quit_closure.Run();
84 } 174 }
85 175
86 protected: 176 protected:
87 void SetUp() override { 177 void SetUp() override {
88 listener_.reset(new MockMediaStreamProviderListener()); 178 listener_.reset(new MockMediaStreamProviderListener());
89 message_loop_.reset(new base::MessageLoopForIO); 179 message_loop_.reset(new base::MessageLoopForIO);
90 ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, 180 ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI,
91 message_loop_.get())); 181 message_loop_.get()));
92 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO, 182 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
93 message_loop_.get())); 183 message_loop_.get()));
94 vcm_ = new VideoCaptureManager( 184 vcm_ = new VideoCaptureManager(
95 std::unique_ptr<media::VideoCaptureDeviceFactory>( 185 std::unique_ptr<media::VideoCaptureDeviceFactory>(
96 new media::FakeVideoCaptureDeviceFactory())); 186 new WrappedDeviceFactory()));
97 video_capture_device_factory_ = 187 video_capture_device_factory_ = static_cast<WrappedDeviceFactory*>(
98 static_cast<media::FakeVideoCaptureDeviceFactory*>( 188 vcm_->video_capture_device_factory());
99 vcm_->video_capture_device_factory());
100 const int32_t kNumberOfFakeDevices = 2; 189 const int32_t kNumberOfFakeDevices = 2;
101 video_capture_device_factory_->set_number_of_devices(kNumberOfFakeDevices); 190 video_capture_device_factory_->set_number_of_devices(kNumberOfFakeDevices);
102 vcm_->Register(listener_.get(), message_loop_->task_runner().get()); 191 vcm_->Register(listener_.get(), message_loop_->task_runner().get());
103 frame_observer_.reset(new MockFrameObserver()); 192 frame_observer_.reset(new MockFrameObserver());
104 193
105 base::RunLoop run_loop; 194 base::RunLoop run_loop;
106 vcm_->EnumerateDevices( 195 vcm_->EnumerateDevices(
107 base::Bind(&VideoCaptureManagerTest::HandleEnumerationResult, 196 base::Bind(&VideoCaptureManagerTest::HandleEnumerationResult,
108 base::Unretained(this), run_loop.QuitClosure())); 197 base::Unretained(this), run_loop.QuitClosure()));
109 run_loop.Run(); 198 run_loop.Run();
110 ASSERT_GE(devices_.size(), 2u); 199 ASSERT_GE(devices_.size(), 2u);
111 } 200 }
112 201
113 void TearDown() override {} 202 void TearDown() override {}
114 203
115 void OnGotControllerCallback( 204 void OnGotControllerCallback(
116 VideoCaptureControllerID id, 205 VideoCaptureControllerID id,
117 base::Closure quit_closure,
118 bool expect_success, 206 bool expect_success,
119 const base::WeakPtr<VideoCaptureController>& controller) { 207 const base::WeakPtr<VideoCaptureController>& controller) {
120 if (expect_success) { 208 if (expect_success) {
121 ASSERT_TRUE(controller); 209 ASSERT_TRUE(controller);
122 ASSERT_TRUE(0 == controllers_.count(id)); 210 ASSERT_TRUE(0 == controllers_.count(id));
123 controllers_[id] = controller.get(); 211 controllers_[id] = controller.get();
124 } else { 212 } else {
125 ASSERT_FALSE(controller); 213 ASSERT_FALSE(controller);
126 } 214 }
127 quit_closure.Run();
128 } 215 }
129 216
130 VideoCaptureControllerID StartClient(int session_id, bool expect_success) { 217 VideoCaptureControllerID StartClient(int session_id, bool expect_success) {
131 media::VideoCaptureParams params; 218 media::VideoCaptureParams params;
132 params.requested_format = media::VideoCaptureFormat( 219 params.requested_format = media::VideoCaptureFormat(
133 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); 220 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
134 221
135 VideoCaptureControllerID client_id(next_client_id_++); 222 VideoCaptureControllerID client_id(next_client_id_++);
136 base::RunLoop run_loop;
137 vcm_->StartCaptureForClient( 223 vcm_->StartCaptureForClient(
138 session_id, 224 session_id,
139 params, 225 params,
140 base::kNullProcessHandle, 226 base::kNullProcessHandle,
141 client_id, 227 client_id,
142 frame_observer_.get(), 228 frame_observer_.get(),
143 base::Bind(&VideoCaptureManagerTest::OnGotControllerCallback, 229 base::Bind(&VideoCaptureManagerTest::OnGotControllerCallback,
144 base::Unretained(this), 230 base::Unretained(this),
145 client_id, 231 client_id,
146 run_loop.QuitClosure(),
147 expect_success)); 232 expect_success));
148 run_loop.Run(); 233 base::RunLoop().RunUntilIdle();
149 return client_id; 234 return client_id;
150 } 235 }
151 236
152 void StopClient(VideoCaptureControllerID client_id) { 237 void StopClient(VideoCaptureControllerID client_id) {
153 ASSERT_TRUE(1 == controllers_.count(client_id)); 238 ASSERT_TRUE(1 == controllers_.count(client_id));
154 vcm_->StopCaptureForClient(controllers_[client_id], client_id, 239 vcm_->StopCaptureForClient(controllers_[client_id], client_id,
155 frame_observer_.get(), false); 240 frame_observer_.get(), false);
156 controllers_.erase(client_id); 241 controllers_.erase(client_id);
157 } 242 }
158 243
159 void ResumeClient(int session_id, int client_id) { 244 void ResumeClient(int session_id, int client_id) {
160 ASSERT_EQ(1u, controllers_.count(client_id)); 245 ASSERT_EQ(1u, controllers_.count(client_id));
161 media::VideoCaptureParams params; 246 media::VideoCaptureParams params;
162 params.requested_format = media::VideoCaptureFormat( 247 params.requested_format = media::VideoCaptureFormat(
163 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); 248 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
164
165 vcm_->ResumeCaptureForClient( 249 vcm_->ResumeCaptureForClient(
166 session_id, 250 session_id,
167 params, 251 params,
168 controllers_[client_id], 252 controllers_[client_id],
169 client_id, 253 client_id,
170 frame_observer_.get()); 254 frame_observer_.get());
255 // Allow possible VideoCaptureDevice::Resume() task to run.
256 base::RunLoop().RunUntilIdle();
171 } 257 }
172 258
173 void PauseClient(VideoCaptureControllerID client_id) { 259 void PauseClient(VideoCaptureControllerID client_id) {
174 ASSERT_EQ(1u, controllers_.count(client_id)); 260 ASSERT_EQ(1u, controllers_.count(client_id));
175 vcm_->PauseCaptureForClient(controllers_[client_id], client_id, 261 vcm_->PauseCaptureForClient(controllers_[client_id], client_id,
176 frame_observer_.get()); 262 frame_observer_.get());
263 // Allow possible VideoCaptureDevice::MaybeSuspend() task to run.
264 base::RunLoop().RunUntilIdle();
177 } 265 }
178 266
179 #if defined(OS_ANDROID) 267 #if defined(OS_ANDROID)
180 void ApplicationStateChange(base::android::ApplicationState state) { 268 void ApplicationStateChange(base::android::ApplicationState state) {
181 vcm_->OnApplicationStateChange(state); 269 vcm_->OnApplicationStateChange(state);
182 } 270 }
183 #endif 271 #endif
184 272
185 int next_client_id_; 273 int next_client_id_;
186 std::map<VideoCaptureControllerID, VideoCaptureController*> controllers_; 274 std::map<VideoCaptureControllerID, VideoCaptureController*> controllers_;
187 scoped_refptr<VideoCaptureManager> vcm_; 275 scoped_refptr<VideoCaptureManager> vcm_;
188 std::unique_ptr<MockMediaStreamProviderListener> listener_; 276 std::unique_ptr<MockMediaStreamProviderListener> listener_;
189 std::unique_ptr<base::MessageLoop> message_loop_; 277 std::unique_ptr<base::MessageLoop> message_loop_;
190 std::unique_ptr<BrowserThreadImpl> ui_thread_; 278 std::unique_ptr<BrowserThreadImpl> ui_thread_;
191 std::unique_ptr<BrowserThreadImpl> io_thread_; 279 std::unique_ptr<BrowserThreadImpl> io_thread_;
192 std::unique_ptr<MockFrameObserver> frame_observer_; 280 std::unique_ptr<MockFrameObserver> frame_observer_;
193 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_; 281 WrappedDeviceFactory* video_capture_device_factory_;
194 StreamDeviceInfoArray devices_; 282 StreamDeviceInfoArray devices_;
195 283
196 private: 284 private:
197 DISALLOW_COPY_AND_ASSIGN(VideoCaptureManagerTest); 285 DISALLOW_COPY_AND_ASSIGN(VideoCaptureManagerTest);
198 }; 286 };
199 287
200 // Test cases 288 // Test cases
201 289
202 // Try to open, start, stop and close a device. 290 // Try to open, start, stop and close a device.
203 TEST_F(VideoCaptureManagerTest, CreateAndClose) { 291 TEST_F(VideoCaptureManagerTest, CreateAndClose) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 // Close will stop the running device, an assert will be triggered in 557 // Close will stop the running device, an assert will be triggered in
470 // VideoCaptureManager destructor otherwise. 558 // VideoCaptureManager destructor otherwise.
471 vcm_->Close(video_session_id); 559 vcm_->Close(video_session_id);
472 StopClient(client_id); 560 StopClient(client_id);
473 561
474 // Wait to check callbacks before removing the listener 562 // Wait to check callbacks before removing the listener
475 base::RunLoop().RunUntilIdle(); 563 base::RunLoop().RunUntilIdle();
476 vcm_->Unregister(); 564 vcm_->Unregister();
477 } 565 }
478 566
479 // Try to open, start, pause and resume a device. 567 // Try to open, start, pause and resume a device. Confirm the device is
568 // paused/resumed at the correct times in both single-client and multiple-client
569 // scenarios.
480 TEST_F(VideoCaptureManagerTest, PauseAndResumeClient) { 570 TEST_F(VideoCaptureManagerTest, PauseAndResumeClient) {
481 InSequence s;
482 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)); 571 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
483 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
484 572
485 int video_session_id = vcm_->Open(devices_.front()); 573 const int video_session_id = vcm_->Open(devices_.front());
486 VideoCaptureControllerID client_id = StartClient(video_session_id, true); 574 const VideoCaptureControllerID client_id =
575 StartClient(video_session_id, true);
487 576
488 // Resume client a second time should cause no problem. 577 // Test pause/resume when only one client is present.
578 EXPECT_CALL(*video_capture_device_factory_, WillSuspendDevice()).Times(1);
489 PauseClient(client_id); 579 PauseClient(client_id);
580 EXPECT_CALL(*video_capture_device_factory_, WillResumeDevice()).Times(1);
490 ResumeClient(video_session_id, client_id); 581 ResumeClient(video_session_id, client_id);
582
583 // Attempting to resume the client a second time should not cause any calls to
584 // VideoCaptureDevice::Resume().
585 ResumeClient(video_session_id, client_id);
586
587 // Add a second client that is never paused, then pause/resume the first
588 // client, and no calls to VideoCaptureDevice::MaybeSuspend() or Resume() are
589 // made.
590 const VideoCaptureControllerID client_id2 =
591 StartClient(video_session_id, true);
592 PauseClient(client_id);
491 ResumeClient(video_session_id, client_id); 593 ResumeClient(video_session_id, client_id);
492 594
493 StopClient(client_id); 595 StopClient(client_id);
596 StopClient(client_id2);
597
598 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
494 vcm_->Close(video_session_id); 599 vcm_->Close(video_session_id);
495 600
496 // Wait to check callbacks before removing the listener. 601 // Wait to check callbacks before removing the listener.
497 base::RunLoop().RunUntilIdle(); 602 base::RunLoop().RunUntilIdle();
498 vcm_->Unregister(); 603 vcm_->Unregister();
499 } 604 }
500 605
501 #if defined(OS_ANDROID) 606 #if defined(OS_ANDROID)
502 // Try to open, start, pause and resume a device. 607 // Try to open, start, pause and resume a device.
503 TEST_F(VideoCaptureManagerTest, PauseAndResumeDevice) { 608 TEST_F(VideoCaptureManagerTest, PauseAndResumeDevice) {
(...skipping 23 matching lines...) Expand all
527 // Wait to check callbacks before removing the listener. 632 // Wait to check callbacks before removing the listener.
528 base::RunLoop().RunUntilIdle(); 633 base::RunLoop().RunUntilIdle();
529 vcm_->Unregister(); 634 vcm_->Unregister();
530 } 635 }
531 #endif 636 #endif
532 637
533 // TODO(mcasas): Add a test to check consolidation of the supported formats 638 // TODO(mcasas): Add a test to check consolidation of the supported formats
534 // provided by the device when http://crbug.com/323913 is closed. 639 // provided by the device when http://crbug.com/323913 is closed.
535 640
536 } // namespace content 641 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/video_capture_manager.cc ('k') | content/common/media/video_capture.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698