• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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 <thread>
18 
19 #include <gtest/gtest.h>
20 
21 #include <oboe/Oboe.h>
22 
23 using namespace oboe;
24 
25 class TestStreamWaitState : public ::testing::Test {
26 
27 protected:
28 
SetUp()29     void SetUp(){
30         mBuilder.setPerformanceMode(PerformanceMode::None);
31         mBuilder.setDirection(Direction::Output);
32     }
33 
openStream(Direction direction,PerformanceMode perfMode)34     bool openStream(Direction direction, PerformanceMode perfMode) {
35         mBuilder.setDirection(direction);
36         mBuilder.setPerformanceMode(perfMode);
37         Result r = mBuilder.openStream(mStream);
38         EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r);
39         if (r != Result::OK)
40             return false;
41 
42         Direction d = mStream->getDirection();
43         EXPECT_EQ(d, direction) << convertToText(mStream->getDirection());
44         return (d == direction);
45     }
46 
openStream(AudioStreamBuilder & builder)47     bool openStream(AudioStreamBuilder &builder) {
48         Result r = builder.openStream(mStream);
49         EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r);
50         return (r == Result::OK);
51     }
52 
closeStream()53     bool closeStream() {
54         Result r = mStream->close();
55         EXPECT_TRUE(r == Result::OK || r == Result::ErrorClosed) <<
56             "Failed to close stream. " << convertToText(r);
57         return (r == Result::OK || r == Result::ErrorClosed);
58     }
59 
60     // if zero then don't wait for a state change
checkWaitForStateChangeTimeout(int64_t timeout=kTimeoutInNanos)61     void checkWaitForStateChangeTimeout(int64_t timeout = kTimeoutInNanos) {
62         StreamState next = StreamState::Unknown;
63         Result result = mStream->waitForStateChange(mStream->getState(), &next, timeout);
64         EXPECT_EQ(Result::ErrorTimeout, result);
65     }
66 
checkStopWhileWaiting()67     void checkStopWhileWaiting() {
68         StreamState next = StreamState::Unknown;
69         auto r = mStream->requestStart();
70         EXPECT_EQ(r, Result::OK);
71         r = mStream->waitForStateChange(StreamState::Starting, &next, kTimeoutInNanos);
72         EXPECT_EQ(r, Result::OK);
73         EXPECT_EQ(next, StreamState::Started) << "next = " << convertToText(next);
74 
75         std::shared_ptr<AudioStream> str = mStream;
76 
77         std::thread stopper([str] {
78             usleep(200 * 1000);
79             str->requestStop();
80         });
81 
82         r = mStream->waitForStateChange(StreamState::Started, &next, 1000 * kNanosPerMillisecond);
83         stopper.join();
84         EXPECT_EQ(r, Result::OK);
85         // May have caught in stopping transition. Wait for full stop.
86         if (next == StreamState::Stopping) {
87             r = mStream->waitForStateChange(StreamState::Stopping, &next, 1000 * kNanosPerMillisecond);
88             EXPECT_EQ(r, Result::OK);
89         }
90         ASSERT_EQ(next, StreamState::Stopped) << "next = " << convertToText(next);
91     }
92 
checkCloseWhileWaiting()93     void checkCloseWhileWaiting() {
94         StreamState next = StreamState::Unknown;
95         auto r = mStream->requestStart();
96         EXPECT_EQ(r, Result::OK);
97         r = mStream->waitForStateChange(StreamState::Starting, &next, kTimeoutInNanos);
98         EXPECT_EQ(r, Result::OK);
99         EXPECT_EQ(next, StreamState::Started) << "next = " << convertToText(next);
100 
101         std::shared_ptr<AudioStream> str = mStream;
102 
103         std::thread closer([str] {
104             usleep(200 * 1000);
105             str->close();
106         });
107 
108         r = mStream->waitForStateChange(StreamState::Started, &next, 1000 * kNanosPerMillisecond);
109         closer.join();
110         // You might catch this at any point in stopping or closing.
111         EXPECT_TRUE(r == Result::OK || r == Result::ErrorClosed) << "r = " << convertToText(r);
112         ASSERT_TRUE(next == StreamState::Stopping
113                     || next == StreamState::Stopped
114                     || next == StreamState::Pausing
115                     || next == StreamState::Paused
116                     || next == StreamState::Closed) << "next = " << convertToText(next);
117     }
118 
119     AudioStreamBuilder mBuilder;
120     std::shared_ptr<AudioStream> mStream;
121     static constexpr int kTimeoutInNanos = 100 * kNanosPerMillisecond;
122 
123 };
124 
125 // Test return of error timeout when zero passed as the timeoutNanos.
TEST_F(TestStreamWaitState,OutputLowWaitZero)126 TEST_F(TestStreamWaitState, OutputLowWaitZero) {
127     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency));
128     checkWaitForStateChangeTimeout(0);
129     ASSERT_TRUE(closeStream());
130 }
131 
TEST_F(TestStreamWaitState,OutputNoneWaitZero)132 TEST_F(TestStreamWaitState, OutputNoneWaitZero) {
133     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::None));
134     checkWaitForStateChangeTimeout(0);
135     ASSERT_TRUE(closeStream());
136 }
137 
TEST_F(TestStreamWaitState,OutputLowWaitZeroSLES)138 TEST_F(TestStreamWaitState, OutputLowWaitZeroSLES) {
139     AudioStreamBuilder builder;
140     builder.setPerformanceMode(PerformanceMode::LowLatency);
141     builder.setAudioApi(AudioApi::OpenSLES);
142     ASSERT_TRUE(openStream(builder));
143     checkWaitForStateChangeTimeout(0);
144     ASSERT_TRUE(closeStream());
145 }
146 
TEST_F(TestStreamWaitState,OutputNoneWaitZeroSLES)147 TEST_F(TestStreamWaitState, OutputNoneWaitZeroSLES) {
148     AudioStreamBuilder builder;
149     builder.setPerformanceMode(PerformanceMode::None);
150     builder.setAudioApi(AudioApi::OpenSLES);
151     ASSERT_TRUE(openStream(builder));
152     checkWaitForStateChangeTimeout(0);
153     ASSERT_TRUE(closeStream());
154 }
155 
156 // Test actual timeout.
TEST_F(TestStreamWaitState,OutputLowWaitNonZero)157 TEST_F(TestStreamWaitState, OutputLowWaitNonZero) {
158     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency));
159     checkWaitForStateChangeTimeout();
160     ASSERT_TRUE(closeStream());
161 }
162 
TEST_F(TestStreamWaitState,OutputNoneWaitNonZero)163 TEST_F(TestStreamWaitState, OutputNoneWaitNonZero) {
164     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::None));
165     checkWaitForStateChangeTimeout();
166     ASSERT_TRUE(closeStream());
167 }
168 
TEST_F(TestStreamWaitState,OutputLowWaitNonZeroSLES)169 TEST_F(TestStreamWaitState, OutputLowWaitNonZeroSLES) {
170     AudioStreamBuilder builder;
171     builder.setPerformanceMode(PerformanceMode::LowLatency);
172     builder.setAudioApi(AudioApi::OpenSLES);
173     ASSERT_TRUE(openStream(builder));
174     checkWaitForStateChangeTimeout();
175     ASSERT_TRUE(closeStream());
176 }
177 
TEST_F(TestStreamWaitState,OutputNoneWaitNonZeroSLES)178 TEST_F(TestStreamWaitState, OutputNoneWaitNonZeroSLES) {
179     AudioStreamBuilder builder;
180     builder.setPerformanceMode(PerformanceMode::None);
181     builder.setAudioApi(AudioApi::OpenSLES);
182     ASSERT_TRUE(openStream(builder));
183     checkWaitForStateChangeTimeout();
184     ASSERT_TRUE(closeStream());
185 }
186 
TEST_F(TestStreamWaitState,OutputLowStopWhileWaiting)187 TEST_F(TestStreamWaitState, OutputLowStopWhileWaiting) {
188     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency));
189     checkStopWhileWaiting();
190     ASSERT_TRUE(closeStream());
191 }
192 
TEST_F(TestStreamWaitState,OutputNoneStopWhileWaiting)193 TEST_F(TestStreamWaitState, OutputNoneStopWhileWaiting) {
194     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency));
195     checkStopWhileWaiting();
196     ASSERT_TRUE(closeStream());
197 }
198 
199 
TEST_F(TestStreamWaitState,OutputLowStopWhileWaitingSLES)200 TEST_F(TestStreamWaitState, OutputLowStopWhileWaitingSLES) {
201     AudioStreamBuilder builder;
202     builder.setPerformanceMode(PerformanceMode::LowLatency);
203     builder.setAudioApi(AudioApi::OpenSLES);
204     ASSERT_TRUE(openStream(builder));
205     checkStopWhileWaiting();
206     ASSERT_TRUE(closeStream());
207 }
208 
209 
TEST_F(TestStreamWaitState,OutputLowCloseWhileWaiting)210 TEST_F(TestStreamWaitState, OutputLowCloseWhileWaiting) {
211     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency));
212     checkCloseWhileWaiting();
213     ASSERT_TRUE(closeStream());
214 }
215 
TEST_F(TestStreamWaitState,OutputNoneCloseWhileWaiting)216 TEST_F(TestStreamWaitState, OutputNoneCloseWhileWaiting) {
217     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::None));
218     checkCloseWhileWaiting();
219     ASSERT_TRUE(closeStream());
220 }
221 
TEST_F(TestStreamWaitState,InputLowCloseWhileWaiting)222 TEST_F(TestStreamWaitState, InputLowCloseWhileWaiting) {
223     ASSERT_TRUE(openStream(Direction::Input, PerformanceMode::LowLatency));
224     checkCloseWhileWaiting();
225     ASSERT_TRUE(closeStream());
226 }
227 
TEST_F(TestStreamWaitState,InputNoneCloseWhileWaiting)228 TEST_F(TestStreamWaitState, InputNoneCloseWhileWaiting) {
229     ASSERT_TRUE(openStream(Direction::Input, PerformanceMode::None));
230     checkCloseWhileWaiting();
231     ASSERT_TRUE(closeStream());
232 }
233 
TEST_F(TestStreamWaitState,OutputNoneCloseWhileWaitingSLES)234 TEST_F(TestStreamWaitState, OutputNoneCloseWhileWaitingSLES) {
235     AudioStreamBuilder builder;
236     builder.setPerformanceMode(PerformanceMode::None);
237     builder.setAudioApi(AudioApi::OpenSLES);
238     ASSERT_TRUE(openStream(builder));
239     checkCloseWhileWaiting();
240     ASSERT_TRUE(closeStream());
241 }
242 
243 
TEST_F(TestStreamWaitState,OutputLowCloseWhileWaitingSLES)244 TEST_F(TestStreamWaitState, OutputLowCloseWhileWaitingSLES) {
245     AudioStreamBuilder builder;
246     builder.setPerformanceMode(PerformanceMode::LowLatency);
247     builder.setAudioApi(AudioApi::OpenSLES);
248     ASSERT_TRUE(openStream(builder));
249     checkCloseWhileWaiting();
250     ASSERT_TRUE(closeStream());
251 }
252