• 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         Result r = mBuilder.openStream(&mStream);
37         EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r);
38         EXPECT_EQ(mStream->getDirection(), direction) << convertToText(mStream->getDirection());
39         return (r == Result::OK);
40     }
41 
openStream(AudioStreamBuilder & builder)42     bool openStream(AudioStreamBuilder &builder) {
43         Result r = builder.openStream(&mStream);
44         EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r);
45         return (r == Result::OK);
46     }
47 
closeStream()48     void closeStream() {
49         if (mStream != nullptr){
50             Result r = mStream->close();
51             mStream = nullptr;
52             if (r != Result::OK && r != Result::ErrorClosed){
53                 FAIL() << "Failed to close stream. " << convertToText(r);
54             }
55         }
56     }
57 
checkWaitZeroTimeout()58     void checkWaitZeroTimeout() {
59         StreamState next = StreamState::Unknown;
60         int64_t timeout = 0; // don't wait for a state change
61 		Result result = mStream->waitForStateChange(mStream->getState(), &next, timeout);
62 		EXPECT_EQ(Result::ErrorTimeout, result);
63 	}
64 
checkStopWhileWaiting()65     void checkStopWhileWaiting() {
66         StreamState next = StreamState::Unknown;
67         auto r = mStream->requestStart();
68         EXPECT_EQ(r, Result::OK);
69         r = mStream->waitForStateChange(StreamState::Starting, &next, kTimeoutInNanos);
70         EXPECT_EQ(r, Result::OK);
71         EXPECT_EQ(next, StreamState::Started) << "next = " << convertToText(next);
72 
73         AudioStream *str = mStream;
74         std::thread stopper([str] {
75             usleep(200 * 1000);
76             str->requestStop();
77         });
78 
79         r = mStream->waitForStateChange(StreamState::Started, &next, 1000 * kNanosPerMillisecond);
80         stopper.join();
81         EXPECT_EQ(r, Result::OK);
82         // May have caught in stopping transition. Wait for full stop.
83         if (next == StreamState::Stopping) {
84             r = mStream->waitForStateChange(StreamState::Stopping, &next, 1000 * kNanosPerMillisecond);
85             EXPECT_EQ(r, Result::OK);
86         }
87         ASSERT_EQ(next, StreamState::Stopped) << "next = " << convertToText(next);
88     }
89 
checkCloseWhileWaiting()90     void checkCloseWhileWaiting() {
91         StreamState next = StreamState::Unknown;
92         auto r = mStream->requestStart();
93         EXPECT_EQ(r, Result::OK);
94         r = mStream->waitForStateChange(StreamState::Starting, &next, kTimeoutInNanos);
95         EXPECT_EQ(r, Result::OK);
96         EXPECT_EQ(next, StreamState::Started) << "next = " << convertToText(next);
97 
98         AudioStream *str = mStream;
99         std::thread closer([str] {
100             usleep(200 * 1000);
101             str->close();
102         });
103 
104         r = mStream->waitForStateChange(StreamState::Started, &next, 1000 * kNanosPerMillisecond);
105         closer.join();
106         // You might catch this at any point in stopping or closing.
107         EXPECT_TRUE(r == Result::OK || r == Result::ErrorClosed) << "r = " << convertToText(r);
108         ASSERT_TRUE(next == StreamState::Stopping
109                     || next == StreamState::Stopped
110                     || next == StreamState::Pausing
111                     || next == StreamState::Paused
112                     || next == StreamState::Closed) << "next = " << convertToText(next);
113     }
114 
115     AudioStreamBuilder mBuilder;
116     AudioStream *mStream = nullptr;
117     static constexpr int kTimeoutInNanos = 100 * kNanosPerMillisecond;
118 
119 };
120 
TEST_F(TestStreamWaitState,OutputLowWaitZero)121 TEST_F(TestStreamWaitState, OutputLowWaitZero) {
122     openStream(Direction::Output, PerformanceMode::LowLatency);
123     checkWaitZeroTimeout();
124     closeStream();
125 }
126 
TEST_F(TestStreamWaitState,OutputNoneWaitZero)127 TEST_F(TestStreamWaitState, OutputNoneWaitZero) {
128     openStream(Direction::Output, PerformanceMode::None);
129     checkWaitZeroTimeout();
130     closeStream();
131 }
132 
TEST_F(TestStreamWaitState,OutputLowWaitZeroSLES)133 TEST_F(TestStreamWaitState, OutputLowWaitZeroSLES) {
134     AudioStreamBuilder builder;
135     builder.setPerformanceMode(PerformanceMode::LowLatency);
136     builder.setAudioApi(AudioApi::OpenSLES);
137     openStream(builder);
138     checkWaitZeroTimeout();
139     closeStream();
140 }
141 
TEST_F(TestStreamWaitState,OutputNoneWaitZeroSLES)142 TEST_F(TestStreamWaitState, OutputNoneWaitZeroSLES) {
143     AudioStreamBuilder builder;
144     builder.setPerformanceMode(PerformanceMode::None);
145     builder.setAudioApi(AudioApi::OpenSLES);
146     openStream(builder);
147     checkWaitZeroTimeout();
148     closeStream();
149 }
150 
151 
TEST_F(TestStreamWaitState,OutputLowStopWhileWaiting)152 TEST_F(TestStreamWaitState, OutputLowStopWhileWaiting) {
153     openStream(Direction::Output, PerformanceMode::LowLatency);
154     checkStopWhileWaiting();
155     closeStream();
156 }
157 
TEST_F(TestStreamWaitState,OutputNoneStopWhileWaiting)158 TEST_F(TestStreamWaitState, OutputNoneStopWhileWaiting) {
159     openStream(Direction::Output, PerformanceMode::LowLatency);
160     checkStopWhileWaiting();
161     closeStream();
162 }
163 
164 
TEST_F(TestStreamWaitState,OutputLowStopWhileWaitingSLES)165 TEST_F(TestStreamWaitState, OutputLowStopWhileWaitingSLES) {
166     AudioStreamBuilder builder;
167     builder.setPerformanceMode(PerformanceMode::LowLatency);
168     builder.setAudioApi(AudioApi::OpenSLES);
169     openStream(builder);
170     checkStopWhileWaiting();
171     closeStream();
172 }
173 
174 
TEST_F(TestStreamWaitState,OutputLowCloseWhileWaiting)175 TEST_F(TestStreamWaitState, OutputLowCloseWhileWaiting) {
176     openStream(Direction::Output, PerformanceMode::LowLatency);
177     checkCloseWhileWaiting();
178     closeStream();
179 }
180 
TEST_F(TestStreamWaitState,OutputNoneCloseWhileWaiting)181 TEST_F(TestStreamWaitState, OutputNoneCloseWhileWaiting) {
182     openStream(Direction::Output, PerformanceMode::None);
183     checkCloseWhileWaiting();
184     closeStream();
185 }
186 
TEST_F(TestStreamWaitState,InputLowCloseWhileWaiting)187 TEST_F(TestStreamWaitState, InputLowCloseWhileWaiting) {
188     openStream(Direction::Input, PerformanceMode::LowLatency);
189     checkCloseWhileWaiting();
190     closeStream();
191 }
192 
TEST_F(TestStreamWaitState,InputNoneCloseWhileWaiting)193 TEST_F(TestStreamWaitState, InputNoneCloseWhileWaiting) {
194     openStream(Direction::Input, PerformanceMode::None);
195     checkCloseWhileWaiting();
196     closeStream();
197 }
198 
TEST_F(TestStreamWaitState,OutputNoneCloseWhileWaitingSLES)199 TEST_F(TestStreamWaitState, OutputNoneCloseWhileWaitingSLES) {
200     AudioStreamBuilder builder;
201     builder.setPerformanceMode(PerformanceMode::None);
202     builder.setAudioApi(AudioApi::OpenSLES);
203     openStream(builder);
204     checkCloseWhileWaiting();
205     closeStream();
206 }
207 
208 
TEST_F(TestStreamWaitState,OutputLowCloseWhileWaitingSLES)209 TEST_F(TestStreamWaitState, OutputLowCloseWhileWaitingSLES) {
210     AudioStreamBuilder builder;
211     builder.setPerformanceMode(PerformanceMode::LowLatency);
212     builder.setAudioApi(AudioApi::OpenSLES);
213     openStream(builder);
214     checkCloseWhileWaiting();
215     closeStream();
216 }