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

Unified Diff: content/renderer/media/video_capture_impl_manager_unittest.cc

Issue 2365223002: Video Capture: Allow suspension of individual devices. (Closed)
Patch Set: Style tweaks, per mcasas's comments. Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/media/video_capture_impl_manager.cc ('k') | media/base/video_capturer_source.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/media/video_capture_impl_manager_unittest.cc
diff --git a/content/renderer/media/video_capture_impl_manager_unittest.cc b/content/renderer/media/video_capture_impl_manager_unittest.cc
index 349a32eca34dd43331fda673b53267c1fae1ed56..4f0d3dc6197df56c71a1e9c7448acc461a571656 100644
--- a/content/renderer/media/video_capture_impl_manager_unittest.cc
+++ b/content/renderer/media/video_capture_impl_manager_unittest.cc
@@ -2,13 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <array>
+
#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "content/child/child_process.h"
+#include "content/common/media/video_capture_messages.h"
#include "content/renderer/media/video_capture_impl.h"
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/media/video_capture_message_filter.h"
@@ -27,18 +31,55 @@ ACTION_P(RunClosure, closure) {
closure.Run();
}
+namespace {
+
+// Callback interface to be implemented by
+// VideoCaptureImplManagerTest. MockVideoCaptureImpl intercepts IPC messages and
+// calls these methods to simulate what the VideoCaptureHost would do.
+class PauseResumeCallback {
+ public:
+ PauseResumeCallback() {}
+ virtual ~PauseResumeCallback() {}
+
+ virtual void OnPaused(media::VideoCaptureSessionId session_id) = 0;
+ virtual void OnResumed(media::VideoCaptureSessionId session_id) = 0;
+};
+
class MockVideoCaptureImpl : public VideoCaptureImpl {
public:
MockVideoCaptureImpl(media::VideoCaptureSessionId session_id,
VideoCaptureMessageFilter* filter,
+ PauseResumeCallback* pause_callback,
base::Closure destruct_callback)
: VideoCaptureImpl(session_id, filter),
- destruct_callback_(destruct_callback) {
+ pause_callback_(pause_callback), destruct_callback_(destruct_callback) {
}
~MockVideoCaptureImpl() override { destruct_callback_.Run(); }
+ void Send(IPC::Message* message) override {
+ IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureImpl, *message)
+ IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, DevicePauseCapture)
+ IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Resume, DeviceResumeCapture)
+ default:
+ VideoCaptureImpl::Send(message);
+ return;
+ IPC_END_MESSAGE_MAP()
+ delete message;
+ }
+
private:
+ void DevicePauseCapture(int device_id) {
+ pause_callback_->OnPaused(session_id());
+ }
+
+ void DeviceResumeCapture(int device_id,
+ media::VideoCaptureSessionId session_id,
+ const media::VideoCaptureParams& params) {
+ pause_callback_->OnResumed(session_id);
+ }
+
+ PauseResumeCallback* const pause_callback_;
base::Closure destruct_callback_;
DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureImpl);
@@ -46,32 +87,36 @@ class MockVideoCaptureImpl : public VideoCaptureImpl {
class MockVideoCaptureImplManager : public VideoCaptureImplManager {
public:
- explicit MockVideoCaptureImplManager(
- base::Closure destruct_video_capture_callback)
- : destruct_video_capture_callback_(
+ MockVideoCaptureImplManager(PauseResumeCallback* pause_callback,
+ base::Closure destruct_video_capture_callback)
+ : pause_callback_(pause_callback),
+ destruct_video_capture_callback_(
destruct_video_capture_callback) {}
~MockVideoCaptureImplManager() override {}
protected:
- VideoCaptureImpl* CreateVideoCaptureImplForTesting(
+ std::unique_ptr<VideoCaptureImpl> CreateVideoCaptureImplForTesting(
media::VideoCaptureSessionId id,
VideoCaptureMessageFilter* filter) const override {
- return new MockVideoCaptureImpl(id,
- filter,
- destruct_video_capture_callback_);
+ return base::MakeUnique<MockVideoCaptureImpl>(
+ id, filter, pause_callback_, destruct_video_capture_callback_);
}
private:
+ PauseResumeCallback* const pause_callback_;
base::Closure destruct_video_capture_callback_;
DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureImplManager);
};
-class VideoCaptureImplManagerTest : public ::testing::Test {
+} // namespace
+
+class VideoCaptureImplManagerTest
+ : public ::testing::Test, public PauseResumeCallback {
public:
VideoCaptureImplManagerTest()
: manager_(new MockVideoCaptureImplManager(
- BindToCurrentLoop(cleanup_run_loop_.QuitClosure()))) {
+ this, BindToCurrentLoop(cleanup_run_loop_.QuitClosure()))) {
params_.requested_format = media::VideoCaptureFormat(
gfx::Size(176, 144), 30, media::PIXEL_FORMAT_I420);
child_process_.reset(new ChildProcess());
@@ -90,29 +135,65 @@ class VideoCaptureImplManagerTest : public ::testing::Test {
}
protected:
+ static constexpr size_t kNumClients = 3;
+
+ std::array<base::Closure, kNumClients> StartCaptureForAllClients(
+ bool same_session_id) {
+ base::RunLoop run_loop;
+ base::Closure quit_closure = BindToCurrentLoop(run_loop.QuitClosure());
+ EXPECT_CALL(*this, OnStarted(_)).Times(kNumClients - 1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*this, OnStarted(_)).WillOnce(RunClosure(quit_closure))
+ .RetiresOnSaturation();
+ std::array<base::Closure, kNumClients> stop_callbacks;
+ for (size_t i = 0; i < kNumClients; ++i)
+ stop_callbacks[i] = StartCapture(
+ same_session_id ? 0 : static_cast<media::VideoCaptureSessionId>(i),
+ params_);
+ FakeChannelSetup();
+ run_loop.Run();
+ return stop_callbacks;
+ }
+
+ void StopCaptureForAllClients(
+ std::array<base::Closure, kNumClients>* stop_callbacks) {
+ base::RunLoop run_loop;
+ base::Closure quit_closure = BindToCurrentLoop(run_loop.QuitClosure());
+ EXPECT_CALL(*this, OnStopped(_)).Times(kNumClients - 1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*this, OnStopped(_)).WillOnce(RunClosure(quit_closure))
+ .RetiresOnSaturation();
+ for (size_t i = 0; i < kNumClients; ++i)
+ (*stop_callbacks)[i].Run();
+ run_loop.Run();
+ }
+
MOCK_METHOD2(OnFrameReady,
void(const scoped_refptr<media::VideoFrame>&,
base::TimeTicks estimated_capture_time));
- MOCK_METHOD0(OnStarted, void());
- MOCK_METHOD0(OnStopped, void());
+ MOCK_METHOD1(OnStarted, void(media::VideoCaptureSessionId id));
+ MOCK_METHOD1(OnStopped, void(media::VideoCaptureSessionId id));
+ MOCK_METHOD1(OnPaused, void(media::VideoCaptureSessionId id));
+ MOCK_METHOD1(OnResumed, void(media::VideoCaptureSessionId id));
- void OnStateUpdate(VideoCaptureState state) {
+ void OnStateUpdate(media::VideoCaptureSessionId id, VideoCaptureState state) {
switch (state) {
case VIDEO_CAPTURE_STATE_STARTED:
- OnStarted();
+ OnStarted(id);
break;
case VIDEO_CAPTURE_STATE_STOPPED:
- OnStopped();
+ OnStopped(id);
break;
default:
NOTREACHED();
}
}
- base::Closure StartCapture(const media::VideoCaptureParams& params) {
+ base::Closure StartCapture(media::VideoCaptureSessionId id,
+ const media::VideoCaptureParams& params) {
return manager_->StartCapture(
- 0, params, base::Bind(&VideoCaptureImplManagerTest::OnStateUpdate,
- base::Unretained(this)),
+ id, params, base::Bind(&VideoCaptureImplManagerTest::OnStateUpdate,
+ base::Unretained(this), id),
base::Bind(&VideoCaptureImplManagerTest::OnFrameReady,
base::Unretained(this)));
}
@@ -130,38 +211,102 @@ class VideoCaptureImplManagerTest : public ::testing::Test {
// Multiple clients with the same session id. There is only one
// media::VideoCapture object.
TEST_F(VideoCaptureImplManagerTest, MultipleClients) {
- base::Closure release_cb1 = manager_->UseDevice(0);
- base::Closure release_cb2 = manager_->UseDevice(0);
- base::Closure stop_cb1, stop_cb2;
+ std::array<base::Closure, kNumClients> release_callbacks;
+ for (size_t i = 0; i < kNumClients; ++i)
+ release_callbacks[i] = manager_->UseDevice(0);
+ std::array<base::Closure, kNumClients> stop_callbacks =
+ StartCaptureForAllClients(true);
+ StopCaptureForAllClients(&stop_callbacks);
+ for (size_t i = 0; i < kNumClients; ++i)
+ release_callbacks[i].Run();
+ cleanup_run_loop_.Run();
+}
+
+TEST_F(VideoCaptureImplManagerTest, NoLeak) {
+ manager_->UseDevice(0).Reset();
+ manager_.reset();
+ cleanup_run_loop_.Run();
+}
+
+TEST_F(VideoCaptureImplManagerTest, SuspendAndResumeSessions) {
+ std::array<base::Closure, kNumClients> release_callbacks;
+ for (size_t i = 0; i < kNumClients; ++i) {
+ release_callbacks[i] =
+ manager_->UseDevice(static_cast<media::VideoCaptureSessionId>(i));
+ }
+ std::array<base::Closure, kNumClients> stop_callbacks =
+ StartCaptureForAllClients(false);
+
+ // Call SuspendDevices(true) to suspend all clients, and expect all to be
+ // paused.
{
base::RunLoop run_loop;
base::Closure quit_closure = BindToCurrentLoop(run_loop.QuitClosure());
- EXPECT_CALL(*this, OnStarted()).WillOnce(RunClosure(quit_closure));
- EXPECT_CALL(*this, OnStarted()).RetiresOnSaturation();
- stop_cb1 = StartCapture(params_);
- stop_cb2 = StartCapture(params_);
- FakeChannelSetup();
+ EXPECT_CALL(*this, OnPaused(0)).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*this, OnPaused(1)).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*this, OnPaused(2)).WillOnce(RunClosure(quit_closure))
+ .RetiresOnSaturation();
+ manager_->SuspendDevices(true);
run_loop.Run();
}
+ // Call SuspendDevices(false) and expect all to be resumed.
{
base::RunLoop run_loop;
base::Closure quit_closure = BindToCurrentLoop(run_loop.QuitClosure());
- EXPECT_CALL(*this, OnStopped()).WillOnce(RunClosure(quit_closure));
- EXPECT_CALL(*this, OnStopped()).RetiresOnSaturation();
- stop_cb1.Run();
- stop_cb2.Run();
+ EXPECT_CALL(*this, OnResumed(0)).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*this, OnResumed(1)).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*this, OnResumed(2)).WillOnce(RunClosure(quit_closure))
+ .RetiresOnSaturation();
+ manager_->SuspendDevices(false);
run_loop.Run();
}
- release_cb1.Run();
- release_cb2.Run();
- cleanup_run_loop_.Run();
-}
+ // Suspend just the first client and expect just the first client to be
+ // paused.
+ {
+ base::RunLoop run_loop;
+ base::Closure quit_closure = BindToCurrentLoop(run_loop.QuitClosure());
+ EXPECT_CALL(*this, OnPaused(0)).WillOnce(RunClosure(quit_closure))
+ .RetiresOnSaturation();
+ manager_->Suspend(0);
+ run_loop.Run();
+ }
-TEST_F(VideoCaptureImplManagerTest, NoLeak) {
- manager_->UseDevice(0).Reset();
- manager_.reset();
+ // Now call SuspendDevices(true) again, and expect just the second and third
+ // clients to be paused.
+ {
+ base::RunLoop run_loop;
+ base::Closure quit_closure = BindToCurrentLoop(run_loop.QuitClosure());
+ EXPECT_CALL(*this, OnPaused(1)).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*this, OnPaused(2)).WillOnce(RunClosure(quit_closure))
+ .RetiresOnSaturation();
+ manager_->SuspendDevices(true);
+ run_loop.Run();
+ }
+
+ // Resume just the first client, but it should not resume because all devices
+ // are supposed to be suspended.
+ {
+ manager_->Resume(0);
+ base::RunLoop().RunUntilIdle();
+ }
+
+ // Now, call SuspendDevices(false) and expect all to be resumed.
+ {
+ base::RunLoop run_loop;
+ base::Closure quit_closure = BindToCurrentLoop(run_loop.QuitClosure());
+ EXPECT_CALL(*this, OnResumed(0)).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*this, OnResumed(1)).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*this, OnResumed(2)).WillOnce(RunClosure(quit_closure))
+ .RetiresOnSaturation();
+ manager_->SuspendDevices(false);
+ run_loop.Run();
+ }
+
+ StopCaptureForAllClients(&stop_callbacks);
+ for (size_t i = 0; i < kNumClients; ++i)
+ release_callbacks[i].Run();
cleanup_run_loop_.Run();
}
« no previous file with comments | « content/renderer/media/video_capture_impl_manager.cc ('k') | media/base/video_capturer_source.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698