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

Side by Side Diff: media/mojo/services/mojo_audio_output_stream_unittest.cc

Issue 2697793002: Add mojo interface+impl for audio stream control. (Closed)
Patch Set: Don't inline AudioOutputDelegate(EventHandler) dtor. Created 3 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
« no previous file with comments | « media/mojo/services/mojo_audio_output_stream_provider.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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 "media/mojo/services/mojo_audio_output_stream.h"
6
7 #include <utility>
8
9 #include "base/memory/shared_memory.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/sync_socket.h"
13 #include "media/audio/audio_output_controller.h"
14 #include "media/mojo/interfaces/audio_output_stream.mojom.h"
15 #include "mojo/public/cpp/system/platform_handle.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace media {
20
21 namespace {
22
23 const double kNewVolume = 0.618;
24 // Not actually used, but sent from the AudioOutputDelegate.
25 const int kStreamId = 0;
26 const int kShmemSize = 100;
27
28 using testing::_;
29 using testing::Mock;
30 using testing::NotNull;
31 using testing::Return;
32 using testing::SaveArg;
33 using testing::StrictMock;
34 using testing::Test;
35 using AudioOutputStream = mojom::AudioOutputStream;
36 using AudioOutputStreamPtr = mojo::InterfacePtr<AudioOutputStream>;
37
38 class MockDelegate : NON_EXPORTED_BASE(public AudioOutputDelegate) {
39 public:
40 MockDelegate() {}
41 ~MockDelegate() {}
42
43 MOCK_CONST_METHOD0(GetController, scoped_refptr<AudioOutputController>());
44 MOCK_CONST_METHOD0(GetStreamId, int());
45 MOCK_METHOD0(OnPlayStream, void());
46 MOCK_METHOD0(OnPauseStream, void());
47 MOCK_METHOD1(OnSetVolume, void(double));
48 };
49
50 class MockDelegateFactory {
51 public:
52 void PrepareDelegateForCreation(
53 std::unique_ptr<AudioOutputDelegate> delegate) {
54 ASSERT_EQ(nullptr, delegate_);
55 delegate_.swap(delegate);
56 }
57
58 std::unique_ptr<AudioOutputDelegate> CreateDelegate(
59 AudioOutputDelegate::EventHandler* handler) {
60 MockCreateDelegate(handler);
61 EXPECT_NE(nullptr, delegate_);
62 return std::move(delegate_);
63 }
64
65 MOCK_METHOD1(MockCreateDelegate, void(AudioOutputDelegate::EventHandler*));
66
67 private:
68 std::unique_ptr<AudioOutputDelegate> delegate_;
69 };
70
71 class MockDeleter {
72 public:
73 MOCK_METHOD0(Finished, void());
74 };
75
76 class MockClient {
77 public:
78 MockClient() {}
79
80 void Initialized(mojo::ScopedSharedBufferHandle shared_buffer,
81 mojo::ScopedHandle socket_handle) {
82 ASSERT_TRUE(shared_buffer.is_valid());
83 ASSERT_TRUE(socket_handle.is_valid());
84
85 base::PlatformFile fd;
86 mojo::UnwrapPlatformFile(std::move(socket_handle), &fd);
87 socket_ = base::MakeUnique<base::CancelableSyncSocket>(fd);
88 EXPECT_NE(socket_->handle(), base::CancelableSyncSocket::kInvalidHandle);
89
90 size_t memory_length;
91 base::SharedMemoryHandle shmem_handle;
92 bool read_only;
93 EXPECT_EQ(
94 mojo::UnwrapSharedMemoryHandle(std::move(shared_buffer), &shmem_handle,
95 &memory_length, &read_only),
96 MOJO_RESULT_OK);
97 EXPECT_FALSE(read_only);
98 buffer_ = base::MakeUnique<base::SharedMemory>(shmem_handle, read_only);
99
100 GotNotification();
101 }
102
103 MOCK_METHOD0(GotNotification, void());
104
105 private:
106 std::unique_ptr<base::SharedMemory> buffer_;
107 std::unique_ptr<base::CancelableSyncSocket> socket_;
108 };
109
110 } // namespace
111
112 class MojoAudioOutputStreamTest : public Test {
113 public:
114 MojoAudioOutputStreamTest() {}
115
116 AudioOutputStreamPtr CreateAudioOutput() {
117 AudioOutputStreamPtr p;
118 ExpectDelegateCreation();
119 impl_ = base::MakeUnique<MojoAudioOutputStream>(
120 mojo::MakeRequest(&p),
121 base::BindOnce(&MockDelegateFactory::CreateDelegate,
122 base::Unretained(&mock_delegate_factory_)),
123 base::Bind(&MockClient::Initialized, base::Unretained(&client_)),
124 base::BindOnce(&MockDeleter::Finished, base::Unretained(&deleter_)));
125 EXPECT_NE(nullptr, p);
126 return p;
127 }
128
129 protected:
130 void ExpectDelegateCreation() {
131 delegate_ = new StrictMock<MockDelegate>();
132 mock_delegate_factory_.PrepareDelegateForCreation(
133 base::WrapUnique(delegate_));
134 EXPECT_TRUE(
135 base::CancelableSyncSocket::CreatePair(&local_, &foreign_socket_));
136 EXPECT_TRUE(mem_.CreateAnonymous(kShmemSize));
137 EXPECT_CALL(mock_delegate_factory_, MockCreateDelegate(NotNull()))
138 .WillOnce(SaveArg<0>(&delegate_event_handler_));
139 }
140
141 base::MessageLoop loop_;
142 base::CancelableSyncSocket local_, foreign_socket_;
143 base::SharedMemory mem_;
144 StrictMock<MockDelegate>* delegate_ = nullptr;
145 AudioOutputDelegate::EventHandler* delegate_event_handler_ = nullptr;
146 StrictMock<MockDelegateFactory> mock_delegate_factory_;
147 StrictMock<MockDeleter> deleter_;
148 MockClient client_;
149 std::unique_ptr<MojoAudioOutputStream> impl_;
150 };
151
152 TEST_F(MojoAudioOutputStreamTest, Play_Plays) {
153 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput();
154 EXPECT_CALL(*delegate_, OnPlayStream());
155
156 audio_output_ptr->Play();
157 base::RunLoop().RunUntilIdle();
158 }
159
160 TEST_F(MojoAudioOutputStreamTest, Pause_Pauses) {
161 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput();
162 EXPECT_CALL(*delegate_, OnPauseStream());
163
164 audio_output_ptr->Pause();
165 base::RunLoop().RunUntilIdle();
166 }
167
168 TEST_F(MojoAudioOutputStreamTest, SetVolume_SetsVolume) {
169 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput();
170 EXPECT_CALL(*delegate_, OnSetVolume(kNewVolume));
171
172 audio_output_ptr->SetVolume(kNewVolume);
173 base::RunLoop().RunUntilIdle();
174 }
175
176 TEST_F(MojoAudioOutputStreamTest, DestructWithCallPending_Safe) {
177 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput();
178 base::RunLoop().RunUntilIdle();
179
180 ASSERT_NE(nullptr, delegate_event_handler_);
181 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
182 audio_output_ptr->Play();
183 impl_.reset();
184 base::RunLoop().RunUntilIdle();
185 }
186
187 TEST_F(MojoAudioOutputStreamTest, Created_NotifiesClient) {
188 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput();
189 base::RunLoop().RunUntilIdle();
190
191 EXPECT_CALL(client_, GotNotification());
192
193 ASSERT_NE(nullptr, delegate_event_handler_);
194 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
195
196 base::RunLoop().RunUntilIdle();
197 }
198
199 TEST_F(MojoAudioOutputStreamTest, SetVolumeTooLarge_Error) {
200 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput();
201 EXPECT_CALL(deleter_, Finished());
202
203 audio_output_ptr->SetVolume(15);
204 base::RunLoop().RunUntilIdle();
205 Mock::VerifyAndClear(&deleter_);
206 }
207
208 TEST_F(MojoAudioOutputStreamTest, SetVolumeNegative_Error) {
209 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput();
210 EXPECT_CALL(deleter_, Finished());
211
212 audio_output_ptr->SetVolume(-0.5);
213 base::RunLoop().RunUntilIdle();
214 Mock::VerifyAndClear(&deleter_);
215 }
216
217 TEST_F(MojoAudioOutputStreamTest, DelegateErrorBeforeCreated_PropagatesError) {
218 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput();
219 EXPECT_CALL(deleter_, Finished());
220
221 ASSERT_NE(nullptr, delegate_event_handler_);
222 delegate_event_handler_->OnStreamError(kStreamId);
223
224 base::RunLoop().RunUntilIdle();
225 Mock::VerifyAndClear(&deleter_);
226 }
227
228 TEST_F(MojoAudioOutputStreamTest, DelegateErrorAfterCreated_PropagatesError) {
229 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput();
230 EXPECT_CALL(deleter_, Finished());
231 base::RunLoop().RunUntilIdle();
232
233 ASSERT_NE(nullptr, delegate_event_handler_);
234 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
235 delegate_event_handler_->OnStreamError(kStreamId);
236
237 base::RunLoop().RunUntilIdle();
238 Mock::VerifyAndClear(&deleter_);
239 }
240
241 TEST_F(MojoAudioOutputStreamTest, RemoteEndGone_Error) {
242 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput();
243 EXPECT_CALL(deleter_, Finished());
244 audio_output_ptr.reset();
245 base::RunLoop().RunUntilIdle();
246 Mock::VerifyAndClear(&deleter_);
247 }
248
249 } // namespace media
OLDNEW
« no previous file with comments | « media/mojo/services/mojo_audio_output_stream_provider.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698