1 /*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18 #include <oboe/Oboe.h>
19
20 using namespace oboe;
21
22 class MyCallback : public AudioStreamCallback {
23 public:
onAudioReady(AudioStream * oboeStream,void * audioData,int32_t numFrames)24 DataCallbackResult onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override {
25 return DataCallbackResult::Continue;
26 }
27 };
28
29
30
31 class StreamClosedReturnValues : public ::testing::Test {
32
33 protected:
34
SetUp()35 void SetUp(){
36
37 }
38
openStream()39 bool openStream(){
40 Result r = mBuilder.openStream(&mStream);
41 EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r);
42 return (r == Result::OK);
43 }
44
closeStream()45 void closeStream(){
46 if (mStream != nullptr){
47 Result r = mStream->close();
48 if (r != Result::OK){
49 FAIL() << "Failed to close stream. " << convertToText(r);
50 }
51 }
52 }
53
openAndCloseStream()54 void openAndCloseStream(){
55 openStream();
56 closeStream();
57 ASSERT_EQ(mStream->getState(), StreamState::Closed) << "Stream state " << convertToText(mStream->getState());
58 }
59
60 AudioStreamBuilder mBuilder;
61 AudioStream *mStream = nullptr;
62
63 };
64
TEST_F(StreamClosedReturnValues,GetChannelCountReturnsLastKnownValue)65 TEST_F(StreamClosedReturnValues, GetChannelCountReturnsLastKnownValue){
66
67 mBuilder.setChannelCount(2);
68 openAndCloseStream();
69 ASSERT_EQ(mStream->getChannelCount(), 2);
70 }
71
TEST_F(StreamClosedReturnValues,GetDirectionReturnsLastKnownValue)72 TEST_F(StreamClosedReturnValues, GetDirectionReturnsLastKnownValue){
73
74 // Note that when testing on the emulator setting the direction to Input will result in ErrorInternal when
75 // opening the stream
76 mBuilder.setDirection(Direction::Input);
77 openAndCloseStream();
78 ASSERT_EQ(mStream->getDirection(), Direction::Input);
79 }
80
TEST_F(StreamClosedReturnValues,GetSampleRateReturnsLastKnownValue)81 TEST_F(StreamClosedReturnValues, GetSampleRateReturnsLastKnownValue){
82
83 mBuilder.setSampleRate(8000);
84 openAndCloseStream();
85 ASSERT_EQ(mStream->getSampleRate(), 8000);
86 }
87
TEST_F(StreamClosedReturnValues,GetFramesPerCallbackReturnsLastKnownValue)88 TEST_F(StreamClosedReturnValues, GetFramesPerCallbackReturnsLastKnownValue) {
89
90 mBuilder.setFramesPerCallback(192);
91 openAndCloseStream();
92 ASSERT_EQ(mStream->getFramesPerCallback(), 192);
93 }
94
TEST_F(StreamClosedReturnValues,GetFormatReturnsLastKnownValue)95 TEST_F(StreamClosedReturnValues, GetFormatReturnsLastKnownValue) {
96
97 mBuilder.setFormat(AudioFormat::I16);
98 openAndCloseStream();
99 ASSERT_EQ(mStream->getFormat(), AudioFormat::I16);
100 }
101
TEST_F(StreamClosedReturnValues,GetBufferSizeInFramesReturnsLastKnownValue)102 TEST_F(StreamClosedReturnValues, GetBufferSizeInFramesReturnsLastKnownValue) {
103
104 openStream();
105 int32_t bufferSize = mStream->getBufferSizeInFrames();
106 closeStream();
107 ASSERT_EQ(mStream->getBufferSizeInFrames(), bufferSize);
108 }
109
TEST_F(StreamClosedReturnValues,GetBufferCapacityInFramesReturnsLastKnownValue)110 TEST_F(StreamClosedReturnValues, GetBufferCapacityInFramesReturnsLastKnownValue) {
111
112 openStream();
113 int32_t bufferCapacity = mStream->getBufferCapacityInFrames();
114 closeStream();
115 ASSERT_EQ(mStream->getBufferCapacityInFrames(), bufferCapacity);
116 }
117
TEST_F(StreamClosedReturnValues,GetSharingModeReturnsLastKnownValue)118 TEST_F(StreamClosedReturnValues, GetSharingModeReturnsLastKnownValue) {
119
120 openStream();
121 SharingMode s = mStream->getSharingMode();
122 closeStream();
123 ASSERT_EQ(mStream->getSharingMode(), s);
124 }
125
TEST_F(StreamClosedReturnValues,GetPerformanceModeReturnsLastKnownValue)126 TEST_F(StreamClosedReturnValues, GetPerformanceModeReturnsLastKnownValue) {
127
128 openStream();
129 PerformanceMode p = mStream->getPerformanceMode();
130 closeStream();
131 ASSERT_EQ(mStream->getPerformanceMode(), p);
132 }
133
TEST_F(StreamClosedReturnValues,GetDeviceIdReturnsLastKnownValue)134 TEST_F(StreamClosedReturnValues, GetDeviceIdReturnsLastKnownValue) {
135
136 openStream();
137 int32_t d = mStream->getDeviceId();
138 closeStream();
139 ASSERT_EQ(mStream->getDeviceId(), d);
140 }
141
TEST_F(StreamClosedReturnValues,GetCallbackReturnsLastKnownValue)142 TEST_F(StreamClosedReturnValues, GetCallbackReturnsLastKnownValue) {
143
144 AudioStreamCallback *callback = new MyCallback();
145 mBuilder.setCallback(callback);
146 openAndCloseStream();
147
148 AudioStreamCallback *callback2 = mStream->getCallback();
149 ASSERT_EQ(callback, callback2);
150 }
151
TEST_F(StreamClosedReturnValues,GetUsageReturnsLastKnownValue)152 TEST_F(StreamClosedReturnValues, GetUsageReturnsLastKnownValue){
153 openStream();
154 Usage u = mStream->getUsage();
155 closeStream();
156 ASSERT_EQ(mStream->getUsage(), u);
157 }
158
TEST_F(StreamClosedReturnValues,GetContentTypeReturnsLastKnownValue)159 TEST_F(StreamClosedReturnValues, GetContentTypeReturnsLastKnownValue){
160 openStream();
161 ContentType c = mStream->getContentType();
162 closeStream();
163 ASSERT_EQ(mStream->getContentType(), c);
164 }
165
TEST_F(StreamClosedReturnValues,GetInputPresetReturnsLastKnownValue)166 TEST_F(StreamClosedReturnValues, GetInputPresetReturnsLastKnownValue){
167 openStream();
168 auto i = mStream->getInputPreset();
169 closeStream();
170 ASSERT_EQ(mStream->getInputPreset(), i);
171 }
172
TEST_F(StreamClosedReturnValues,GetSessionIdReturnsLastKnownValue)173 TEST_F(StreamClosedReturnValues, GetSessionIdReturnsLastKnownValue){
174 openStream();
175 auto s = mStream->getSessionId();
176 closeStream();
177 ASSERT_EQ(mStream->getSessionId(), s);
178 }
179
TEST_F(StreamClosedReturnValues,StreamStateIsClosed)180 TEST_F(StreamClosedReturnValues, StreamStateIsClosed){
181 openAndCloseStream();
182 ASSERT_EQ(mStream->getState(), StreamState::Closed);
183 }
184
TEST_F(StreamClosedReturnValues,GetXRunCountReturnsLastKnownValue)185 TEST_F(StreamClosedReturnValues, GetXRunCountReturnsLastKnownValue){
186
187 openStream();
188 if (mStream->isXRunCountSupported()){
189 auto i = mStream->getXRunCount();
190 ASSERT_EQ(mStream->getXRunCount(), i);
191 }
192 closeStream();
193 }
194
TEST_F(StreamClosedReturnValues,GetFramesPerBurstReturnsLastKnownValue)195 TEST_F(StreamClosedReturnValues, GetFramesPerBurstReturnsLastKnownValue){
196
197 openStream();
198 auto f = mStream->getFramesPerBurst();
199 closeStream();
200 ASSERT_EQ(mStream->getFramesPerBurst(), f);
201 }
202
TEST_F(StreamClosedReturnValues,GetBytesPerFrameReturnsLastKnownValue)203 TEST_F(StreamClosedReturnValues, GetBytesPerFrameReturnsLastKnownValue){
204 openStream();
205 auto f = mStream->getBytesPerFrame();
206 closeStream();
207 ASSERT_EQ(mStream->getBytesPerFrame(), f);
208 }
209
TEST_F(StreamClosedReturnValues,GetBytesPerSampleReturnsLastKnownValue)210 TEST_F(StreamClosedReturnValues, GetBytesPerSampleReturnsLastKnownValue){
211 openStream();
212 auto f = mStream->getBytesPerSample();
213 closeStream();
214 ASSERT_EQ(mStream->getBytesPerSample(), f);
215 }
216
TEST_F(StreamClosedReturnValues,GetFramesWrittenReturnsLastKnownValue)217 TEST_F(StreamClosedReturnValues, GetFramesWrittenReturnsLastKnownValue){
218 mBuilder.setFormat(AudioFormat::I16);
219 mBuilder.setChannelCount(1);
220 openStream();
221 mStream->start();
222
223 int16_t buffer[4] = { 1, 2, 3, 4 };
224 Result r = mStream->write(&buffer, 4, 0);
225 if (r != Result::OK){
226 FAIL() << "Could not write to audio stream";
227 }
228
229 auto f = mStream->getFramesWritten();
230 ASSERT_EQ(f, 4);
231
232 closeStream();
233 ASSERT_EQ(mStream->getFramesWritten(), f);
234 }
235
236 // TODO: Reading a positive value doesn't work on OpenSL ES in this test - why?
TEST_F(StreamClosedReturnValues,GetFramesReadReturnsLastKnownValue)237 TEST_F(StreamClosedReturnValues, GetFramesReadReturnsLastKnownValue) {
238
239 mBuilder.setDirection(Direction::Input);
240 mBuilder.setFormat(AudioFormat::I16);
241 mBuilder.setChannelCount(1);
242
243 if (openStream()){
244 mStream->start();
245
246 /*
247 int16_t buffer[192];
248 auto r = mStream->read(&buffer, 192, 0);
249 ASSERT_EQ(r.value(), 192);
250 */
251
252 auto f = mStream->getFramesRead();
253 // ASSERT_EQ(f, 192);
254
255 closeStream();
256 ASSERT_EQ(mStream->getFramesRead(), f);
257 };
258 }
259
TEST_F(StreamClosedReturnValues,GetTimestampReturnsErrorClosedIfSupported)260 TEST_F(StreamClosedReturnValues, GetTimestampReturnsErrorClosedIfSupported){
261
262 openStream();
263
264 int64_t framePosition;
265 int64_t presentationTime;
266
267 auto r = mStream->getTimestamp(CLOCK_MONOTONIC, &framePosition, &presentationTime);
268 bool isTimestampSupported = (r == Result::OK);
269
270 closeStream();
271
272 if (isTimestampSupported){
273 ASSERT_EQ(mStream->getTimestamp(CLOCK_MONOTONIC, &framePosition, &presentationTime), Result::ErrorClosed);
274 }
275 }
276
TEST_F(StreamClosedReturnValues,GetAudioApiReturnsLastKnownValue)277 TEST_F(StreamClosedReturnValues, GetAudioApiReturnsLastKnownValue){
278 openStream();
279 AudioApi a = mStream->getAudioApi();
280 closeStream();
281 ASSERT_EQ(mStream->getAudioApi(), a);
282 }
283
TEST_F(StreamClosedReturnValues,GetUsesAAudioReturnsLastKnownValue)284 TEST_F(StreamClosedReturnValues, GetUsesAAudioReturnsLastKnownValue){
285 openStream();
286 bool a = mStream->usesAAudio();
287 closeStream();
288 ASSERT_EQ(mStream->usesAAudio(), a);
289 }
290
TEST_F(StreamClosedReturnValues,StreamStateControlsReturnClosed)291 TEST_F(StreamClosedReturnValues, StreamStateControlsReturnClosed){
292
293 openAndCloseStream();
294 Result r = mStream->close();
295 EXPECT_EQ(r, Result::ErrorClosed) << convertToText(r);
296 r = mStream->start();
297 EXPECT_EQ(r, Result::ErrorClosed) << convertToText(r);
298 EXPECT_EQ(mStream->pause(), Result::ErrorClosed);
299 EXPECT_EQ(mStream->flush(), Result::ErrorClosed);
300 EXPECT_EQ(mStream->stop(), Result::ErrorClosed);
301 EXPECT_EQ(mStream->requestStart(), Result::ErrorClosed);
302 EXPECT_EQ(mStream->requestPause(), Result::ErrorClosed);
303 EXPECT_EQ(mStream->requestFlush(), Result::ErrorClosed);
304 EXPECT_EQ(mStream->requestStop(), Result::ErrorClosed);
305 }
306
TEST_F(StreamClosedReturnValues,WaitForStateChangeReturnsClosed)307 TEST_F(StreamClosedReturnValues, WaitForStateChangeReturnsClosed){
308
309 openAndCloseStream();
310 StreamState next;
311 Result r = mStream->waitForStateChange(StreamState::Open, &next, 0);
312 ASSERT_EQ(r, Result::ErrorClosed) << convertToText(r);
313 }
314
TEST_F(StreamClosedReturnValues,SetBufferSizeInFramesReturnsClosed)315 TEST_F(StreamClosedReturnValues, SetBufferSizeInFramesReturnsClosed){
316
317 openAndCloseStream();
318 auto r = mStream->setBufferSizeInFrames(192);
319 ASSERT_EQ(r.error(), Result::ErrorClosed);
320 }
321
TEST_F(StreamClosedReturnValues,CalculateLatencyInMillisReturnsClosedIfSupported)322 TEST_F(StreamClosedReturnValues, CalculateLatencyInMillisReturnsClosedIfSupported){
323
324 openAndCloseStream();
325
326 if (mStream->getAudioApi() == AudioApi::AAudio){
327 auto r = mStream->calculateLatencyMillis();
328 ASSERT_EQ(r.error(), Result::ErrorClosed);
329 }
330 }
331
TEST_F(StreamClosedReturnValues,ReadReturnsClosed)332 TEST_F(StreamClosedReturnValues, ReadReturnsClosed){
333
334 openAndCloseStream();
335
336 int buffer[8]{0};
337 auto r = mStream->read(buffer, 1, 0);
338 ASSERT_EQ(r.error(), Result::ErrorClosed);
339 }
340
TEST_F(StreamClosedReturnValues,WriteReturnsClosed)341 TEST_F(StreamClosedReturnValues, WriteReturnsClosed){
342
343 openAndCloseStream();
344
345 int buffer[8]{0};
346 auto r = mStream->write(buffer, 1, 0);
347 ASSERT_EQ(r.error(), Result::ErrorClosed);
348 }
349