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