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

Side by Side Diff: content/browser/speech/speech_recognition_audio_receiver_unittest.cc

Issue 549373003: Binding media stream audio track to speech recognition [browser] Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Wait with no timeout Created 6 years, 1 month 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 2014 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/bind.h"
6 #include "base/memory/shared_memory.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/process/process_handle.h"
9 #include "base/test/test_timeouts.h"
10 #include "base/threading/thread.h"
11 #include "base/threading/thread_checker.h"
12 #include "base/threading/thread_restrictions.h"
13 #include "base/time/time.h"
14 #include "content/browser/browser_thread_impl.h"
15 #include "content/browser/speech/speech_recognition_audio_receiver.h"
16 #include "media/audio/audio_parameters.h"
17 #include "media/base/audio_bus.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 using testing::_;
22
23 namespace content {
24
25 namespace {
26
27 // Used to terminate a loop from a different thread than the loop belongs to.
28 // |loop| should be a MessageLoopProxy.
29 ACTION_P(QuitLoop, loop) {
30 loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
31 }
32
33 void SendIndexViaSocket(base::SyncSocket* socket, uint32 index) {
34 size_t bytes_sent = socket->Send(&index, sizeof(index));
35 EXPECT_EQ(bytes_sent, sizeof(index));
36 }
37
38 class MockEventHandler : public media::AudioInputController::EventHandler {
39 public:
40 MockEventHandler() {}
41 virtual ~MockEventHandler() {}
42
43 MOCK_METHOD1(OnCreated, void(media::AudioInputController* controller));
44 MOCK_METHOD1(OnRecording, void(media::AudioInputController* controller));
45 MOCK_METHOD2(OnLog, void(media::AudioInputController* controller,
46 const std::string& message));
47 MOCK_METHOD2(OnError, void(media::AudioInputController* controller,
48 media::AudioInputController::ErrorCode error));
49 MOCK_METHOD2(OnData, void(media::AudioInputController* controller,
50 const media::AudioBus* data));
51 };
52
53 } // namespace
54
55 class SpeechRecognitionAudioReceiverTest : public testing::Test {
56 public:
57 SpeechRecognitionAudioReceiverTest()
58 : io_thread_(BrowserThread::IO, &io_loop_),
59 audio_thread_("AudioReceiverThread") {
60 audio_thread_.Start();
61
62 media::AudioParameters audio_params(
63 media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
64 media::CHANNEL_LAYOUT_STEREO,
65 16000, 16, 1600);
66 base::SharedMemoryHandle foreign_memory_handle;
67 base::SyncSocket::TransitDescriptor foreign_socket_descriptor;
68 receiver_ = SpeechRecognitionAudioReceiver::Create(
69 audio_params, base::GetCurrentProcessHandle(), &event_handler_,
70 audio_thread_.task_runner().get(),
71 &foreign_memory_handle, &foreign_socket_descriptor);
72 DCHECK(receiver_.get());
73
74 // Create a send socket.
75 send_socket_.reset(new base::CancelableSyncSocket(
76 base::SyncSocket::UnwrapHandle(foreign_socket_descriptor)));
77
78 // Get the shared memory.
79 shared_memory_.reset(new base::SharedMemory(foreign_memory_handle, false));
80 const size_t memory_length =
81 media::AudioBus::CalculateMemorySize(audio_params) +
82 sizeof(media::AudioInputBufferParameters);
83 DCHECK(shared_memory_->Map(memory_length));
84
85 // Peer's buffer index is accessed via |params.size| in shared memory.
86 uint8* ptr = static_cast<uint8*>(shared_memory_->memory());
87 media::AudioInputBuffer* buffer =
88 reinterpret_cast<media::AudioInputBuffer*>(ptr);
89 peer_buffer_index_ = &(buffer->params.size);
90
91 // The peer must manage their own counter and reset it.
92 //ASSERT_EQ(0U, *peer_buffer_index_);
93 output_bus_ = media::AudioBus::WrapMemory(audio_params, buffer->audio);
94
95 // Start the receiver.
96 EXPECT_CALL(event_handler_, OnRecording(NULL))
97 .WillOnce(QuitLoop(io_loop()));
98 receiver_->StartListening();
99 WaitUntilCallback();
100 }
101
102 virtual ~SpeechRecognitionAudioReceiverTest() {
103 }
104
105 protected:
106 // Each test case needs to Stop() before quiting.
107 void Stop() {
108 ASSERT_EQ(io_loop(), base::MessageLoop::current());
109 receiver_->Stop();
110 const bool previous_io_allowed =
111 base::ThreadRestrictions::SetIOAllowed(true);
112 audio_thread_.Stop();
113 base::ThreadRestrictions::SetIOAllowed(previous_io_allowed);
114 }
115
116 void WaitUntilCallback() {
117 // Don't hang the test if we never get the Render() callback.
118 io_loop()->PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
119 TestTimeouts::action_timeout());
120 io_loop()->Run();
121 }
122
123 base::MessageLoopForIO* io_loop() { return &io_loop_; }
124 base::MessageLoop* audio_loop() { return audio_thread_.message_loop(); }
125
126 base::MessageLoopForIO io_loop_;
127 BrowserThreadImpl io_thread_;
128 MockEventHandler event_handler_;
129 scoped_ptr<base::CancelableSyncSocket> send_socket_;
130
131 private:
132 uint32 peer_buffer_index() { return *peer_buffer_index_; }
133
134 base::Thread audio_thread_;
135 scoped_ptr<SpeechRecognitionAudioReceiver> receiver_;
136 scoped_ptr<base::SharedMemory> shared_memory_;
137 scoped_ptr<media::AudioBus> output_bus_;
138 uint32* peer_buffer_index_;
139
140 DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionAudioReceiverTest);
141 };
142
143 TEST_F(SpeechRecognitionAudioReceiverTest, CreateAndStop) {
144 // Objects are created, initialized, and stopped.
145 Stop();
146 };
147
148 TEST_F(SpeechRecognitionAudioReceiverTest, VerifyDataFlow) {
149 int index = 1;
150 EXPECT_CALL(event_handler_, OnData(NULL, _))
151 .WillOnce(QuitLoop(io_loop()));
152 SendIndexViaSocket(send_socket_.get(), index);
153 WaitUntilCallback();
154 Stop();
155 };
156
157 TEST_F(SpeechRecognitionAudioReceiverTest, SocketClosingTriggersError) {
158 EXPECT_CALL(event_handler_, OnData(NULL, _))
159 .Times(testing::AtMost(1));
160 EXPECT_CALL(event_handler_, OnError(NULL, _))
161 .WillOnce(QuitLoop(io_loop()));
162 SendIndexViaSocket(send_socket_.get(), 0U);
163 send_socket_->Shutdown();
164 WaitUntilCallback();
165 Stop();
166 };
167
168 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698