Index: content/browser/renderer_host/media/audio_renderer_host_unittest.cc |
diff --git a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc |
index ac837c20dc3e238fd4c656ffc1876f88b872e823..0f8a5e99e43ba7a4b4aa716a4bf235ac376b0e6e 100644 |
--- a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc |
+++ b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc |
@@ -3,23 +3,19 @@ |
// found in the LICENSE file. |
#include "base/bind.h" |
-#include "base/environment.h" |
#include "base/memory/scoped_ptr.h" |
-#include "base/message_loop/message_loop.h" |
+#include "base/run_loop.h" |
#include "base/sync_socket.h" |
-#include "content/browser/browser_thread_impl.h" |
+#include "content/browser/media/media_internals.h" |
#include "content/browser/renderer_host/media/audio_input_device_manager.h" |
#include "content/browser/renderer_host/media/audio_mirroring_manager.h" |
#include "content/browser/renderer_host/media/audio_renderer_host.h" |
#include "content/browser/renderer_host/media/media_stream_manager.h" |
-#include "content/browser/renderer_host/media/mock_media_observer.h" |
#include "content/common/media/audio_messages.h" |
-#include "content/common/media/media_stream_options.h" |
+#include "content/public/test/test_browser_thread_bundle.h" |
#include "ipc/ipc_message_utils.h" |
#include "media/audio/audio_manager.h" |
-#include "media/audio/audio_manager_base.h" |
-#include "media/audio/fake_audio_output_stream.h" |
-#include "net/url_request/url_request_context.h" |
+#include "media/base/bind_to_loop.h" |
#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -28,11 +24,13 @@ using ::testing::Assign; |
using ::testing::DoAll; |
using ::testing::NotNull; |
-namespace content { |
+namespace { |
+const int kRenderProcessId = 1; |
+const int kRenderViewId = 4; |
+const int kStreamId = 50; |
+} // namespace |
-static const int kRenderProcessId = 1; |
-static const int kRenderViewId = 4; |
-static const int kStreamId = 50; |
+namespace content { |
class MockAudioMirroringManager : public AudioMirroringManager { |
public: |
@@ -40,10 +38,12 @@ class MockAudioMirroringManager : public AudioMirroringManager { |
virtual ~MockAudioMirroringManager() {} |
MOCK_METHOD3(AddDiverter, |
- void(int render_process_id, int render_view_id, |
+ void(int render_process_id, |
+ int render_view_id, |
Diverter* diverter)); |
MOCK_METHOD3(RemoveDiverter, |
- void(int render_process_id, int render_view_id, |
+ void(int render_process_id, |
+ int render_view_id, |
Diverter* diverter)); |
private: |
@@ -52,22 +52,19 @@ class MockAudioMirroringManager : public AudioMirroringManager { |
class MockAudioRendererHost : public AudioRendererHost { |
public: |
- explicit MockAudioRendererHost( |
- media::AudioManager* audio_manager, |
- AudioMirroringManager* mirroring_manager, |
- MediaInternals* media_internals, |
- MediaStreamManager* media_stream_manager) |
+ MockAudioRendererHost(media::AudioManager* audio_manager, |
+ AudioMirroringManager* mirroring_manager, |
+ MediaInternals* media_internals, |
+ MediaStreamManager* media_stream_manager) |
: AudioRendererHost(kRenderProcessId, |
audio_manager, |
mirroring_manager, |
media_internals, |
media_stream_manager), |
- shared_memory_length_(0) { |
- } |
+ shared_memory_length_(0) {} |
// A list of mock methods. |
- MOCK_METHOD2(OnStreamCreated, |
- void(int stream_id, int length)); |
+ MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length)); |
MOCK_METHOD1(OnStreamPlaying, void(int stream_id)); |
MOCK_METHOD1(OnStreamPaused, void(int stream_id)); |
MOCK_METHOD1(OnStreamError, void(int stream_id)); |
@@ -100,7 +97,8 @@ class MockAudioRendererHost : public AudioRendererHost { |
return true; |
} |
- void OnStreamCreated(const IPC::Message& msg, int stream_id, |
+ void OnStreamCreated(const IPC::Message& msg, |
+ int stream_id, |
base::SharedMemoryHandle handle, |
#if defined(OS_WIN) |
base::SyncSocket::Handle socket_handle, |
@@ -127,7 +125,8 @@ class MockAudioRendererHost : public AudioRendererHost { |
OnStreamCreated(stream_id, length); |
} |
- void OnStreamStateChanged(const IPC::Message& msg, int stream_id, |
+ void OnStreamStateChanged(const IPC::Message& msg, |
+ int stream_id, |
media::AudioOutputIPCDelegate::State state) { |
switch (state) { |
case media::AudioOutputIPCDelegate::kPlaying: |
@@ -152,64 +151,36 @@ class MockAudioRendererHost : public AudioRendererHost { |
DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost); |
}; |
-ACTION_P(QuitMessageLoop, message_loop) { |
- message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); |
-} |
- |
class AudioRendererHostTest : public testing::Test { |
public: |
- AudioRendererHostTest() : is_stream_active_(false) {} |
- |
- protected: |
- virtual void SetUp() { |
- // Create a message loop so AudioRendererHost can use it. |
- message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO)); |
- |
- // Claim to be on both the UI and IO threads to pass all the DCHECKS. |
- io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO, |
- message_loop_.get())); |
- ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, |
- message_loop_.get())); |
+ AudioRendererHostTest() { |
audio_manager_.reset(media::AudioManager::Create()); |
media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); |
media_stream_manager_->UseFakeDevice(); |
- observer_.reset(new MockMediaInternals()); |
- host_ = new MockAudioRendererHost( |
- audio_manager_.get(), &mirroring_manager_, observer_.get(), |
- media_stream_manager_.get()); |
+ host_ = new MockAudioRendererHost(audio_manager_.get(), |
+ &mirroring_manager_, |
+ MediaInternals::GetInstance(), |
+ media_stream_manager_.get()); |
// Simulate IPC channel connected. |
host_->set_peer_pid_for_testing(base::GetCurrentProcId()); |
} |
- virtual void TearDown() { |
- // Simulate closing the IPC channel. |
+ virtual ~AudioRendererHostTest() { |
+ // Simulate closing the IPC channel and give the audio thread time to close |
+ // the underlying streams. |
host_->OnChannelClosing(); |
+ SyncWithAudioThread(); |
// Release the reference to the mock object. The object will be destructed |
// on message_loop_. |
host_ = NULL; |
- |
- // We need to continue running message_loop_ to complete all destructions. |
- SyncWithAudioThread(); |
- audio_manager_.reset(); |
- |
- // Make sure the stream has been deleted before continuing. |
- while (is_stream_active_) |
- message_loop_->Run(); |
- |
- io_thread_.reset(); |
- ui_thread_.reset(); |
- |
- // Delete the IO message loop. This will cause the MediaStreamManager to be |
- // notified so it will stop its device thread and device managers. |
- message_loop_.reset(); |
} |
+ protected: |
void Create(bool unified_stream) { |
- EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _)) |
- .WillOnce(DoAll(Assign(&is_stream_active_, true), |
- QuitMessageLoop(message_loop_.get()))); |
+ EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _)); |
+ |
EXPECT_CALL(mirroring_manager_, |
AddDiverter(kRenderProcessId, kRenderViewId, NotNull())) |
.RetiresOnSaturation(); |
@@ -237,65 +208,40 @@ class AudioRendererHostTest : public testing::Test { |
media::AudioParameters::kAudioCDSampleRate / 10); |
} |
host_->OnCreateStream(kStreamId, kRenderViewId, session_id, params); |
- message_loop_->Run(); |
// At some point in the future, a corresponding RemoveDiverter() call must |
// be made. |
EXPECT_CALL(mirroring_manager_, |
RemoveDiverter(kRenderProcessId, kRenderViewId, NotNull())) |
.RetiresOnSaturation(); |
- |
- // All created streams should ultimately be closed. |
- EXPECT_CALL(*observer_, |
- OnSetAudioStreamStatus(_, kStreamId, "closed")); |
- |
- // Expect the audio stream will be deleted at some later point. |
- EXPECT_CALL(*observer_, OnDeleteAudioStream(_, kStreamId)) |
- .WillOnce(DoAll(Assign(&is_stream_active_, false), |
- QuitMessageLoop(message_loop_.get()))); |
+ SyncWithAudioThread(); |
} |
void Close() { |
// Send a message to AudioRendererHost to tell it we want to close the |
// stream. |
host_->OnCloseStream(kStreamId); |
- if (is_stream_active_) |
- message_loop_->Run(); |
- else |
- message_loop_->RunUntilIdle(); |
+ SyncWithAudioThread(); |
} |
void Play() { |
- EXPECT_CALL(*observer_, |
- OnSetAudioStreamPlaying(_, kStreamId, true)); |
- EXPECT_CALL(*host_.get(), OnStreamPlaying(kStreamId)) |
- .WillOnce(QuitMessageLoop(message_loop_.get())); |
- |
+ EXPECT_CALL(*host_.get(), OnStreamPlaying(kStreamId)); |
host_->OnPlayStream(kStreamId); |
- message_loop_->Run(); |
+ SyncWithAudioThread(); |
} |
void Pause() { |
- EXPECT_CALL(*observer_, |
- OnSetAudioStreamPlaying(_, kStreamId, false)); |
- EXPECT_CALL(*host_.get(), OnStreamPaused(kStreamId)) |
- .WillOnce(QuitMessageLoop(message_loop_.get())); |
- |
+ EXPECT_CALL(*host_.get(), OnStreamPaused(kStreamId)); |
host_->OnPauseStream(kStreamId); |
- message_loop_->Run(); |
+ SyncWithAudioThread(); |
} |
void SetVolume(double volume) { |
- EXPECT_CALL(*observer_, |
- OnSetAudioStreamVolume(_, kStreamId, volume)); |
- |
host_->OnSetVolume(kStreamId, volume); |
- message_loop_->RunUntilIdle(); |
+ SyncWithAudioThread(); |
} |
void SimulateError() { |
- EXPECT_CALL(*observer_, |
- OnSetAudioStreamStatus(_, kStreamId, "error")); |
EXPECT_EQ(1u, host_->audio_entries_.size()) |
<< "Calls Create() before calling this method"; |
@@ -310,43 +256,27 @@ class AudioRendererHostTest : public testing::Test { |
EXPECT_EQ(0u, host_->audio_entries_.size()); |
} |
- // Called on the audio thread. |
- static void PostQuitMessageLoop(base::MessageLoop* message_loop) { |
- message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); |
- } |
- |
- // Called on the main thread. |
- static void PostQuitOnAudioThread(media::AudioManager* audio_manager, |
- base::MessageLoop* message_loop) { |
- audio_manager->GetMessageLoop()->PostTask(FROM_HERE, |
- base::Bind(&PostQuitMessageLoop, message_loop)); |
- } |
- |
// SyncWithAudioThread() waits until all pending tasks on the audio thread |
// are executed while also processing pending task in message_loop_ on the |
// current thread. It is used to synchronize with the audio thread when we are |
// closing an audio stream. |
void SyncWithAudioThread() { |
- // Don't use scoped_refptr to addref the media::AudioManager when posting |
- // to the thread that itself owns. |
- message_loop_->PostTask( |
- FROM_HERE, base::Bind(&PostQuitOnAudioThread, |
- base::Unretained(audio_manager_.get()), |
- message_loop_.get())); |
- message_loop_->Run(); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ base::RunLoop run_loop; |
+ audio_manager_->GetMessageLoop()->PostTask( |
+ FROM_HERE, media::BindToCurrentLoop(run_loop.QuitClosure())); |
+ run_loop.Run(); |
} |
private: |
- scoped_ptr<MockMediaInternals> observer_; |
+ // MediaStreamManager uses a DestructionObserver, so it must outlive the |
+ // TestBrowserThreadBundle. |
+ scoped_ptr<MediaStreamManager> media_stream_manager_; |
+ TestBrowserThreadBundle thread_bundle_; |
+ scoped_ptr<media::AudioManager> audio_manager_; |
MockAudioMirroringManager mirroring_manager_; |
scoped_refptr<MockAudioRendererHost> host_; |
- scoped_ptr<base::MessageLoop> message_loop_; |
- scoped_ptr<BrowserThreadImpl> io_thread_; |
- scoped_ptr<BrowserThreadImpl> ui_thread_; |
- scoped_ptr<media::AudioManager> audio_manager_; |
- scoped_ptr<MediaStreamManager> media_stream_manager_; |
- |
- bool is_stream_active_; |
DISALLOW_COPY_AND_ASSIGN(AudioRendererHostTest); |
}; |