xref: /aosp_15_r20/external/oboe/tests/testStreamStop.cpp (revision 05767d913155b055644481607e6fa1e35e2fe72c)
1*05767d91SRobert Wu /*
2*05767d91SRobert Wu  * Copyright 2022 The Android Open Source Project
3*05767d91SRobert Wu  *
4*05767d91SRobert Wu  * Licensed under the Apache License, Version 2.0 (the "License");
5*05767d91SRobert Wu  * you may not use this file except in compliance with the License.
6*05767d91SRobert Wu  * You may obtain a copy of the License at
7*05767d91SRobert Wu  *
8*05767d91SRobert Wu  *      http://www.apache.org/licenses/LICENSE-2.0
9*05767d91SRobert Wu  *
10*05767d91SRobert Wu  * Unless required by applicable law or agreed to in writing, software
11*05767d91SRobert Wu  * distributed under the License is distributed on an "AS IS" BASIS,
12*05767d91SRobert Wu  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*05767d91SRobert Wu  * See the License for the specific language governing permissions and
14*05767d91SRobert Wu  * limitations under the License.
15*05767d91SRobert Wu  */
16*05767d91SRobert Wu 
17*05767d91SRobert Wu #include <thread>
18*05767d91SRobert Wu 
19*05767d91SRobert Wu #include <gtest/gtest.h>
20*05767d91SRobert Wu 
21*05767d91SRobert Wu #include <oboe/Oboe.h>
22*05767d91SRobert Wu 
23*05767d91SRobert Wu using namespace oboe;
24*05767d91SRobert Wu 
25*05767d91SRobert Wu using TestStreamStopParams = std::tuple<Direction, AudioApi, PerformanceMode>;
26*05767d91SRobert Wu 
27*05767d91SRobert Wu class TestStreamStop : public ::testing::Test,
28*05767d91SRobert Wu                          public ::testing::WithParamInterface<TestStreamStopParams> {
29*05767d91SRobert Wu 
30*05767d91SRobert Wu protected:
31*05767d91SRobert Wu 
SetUp()32*05767d91SRobert Wu     void SetUp(){
33*05767d91SRobert Wu         mBuilder.setPerformanceMode(PerformanceMode::None);
34*05767d91SRobert Wu         mBuilder.setDirection(Direction::Output);
35*05767d91SRobert Wu     }
36*05767d91SRobert Wu 
openStream(Direction direction,AudioApi audioApi,PerformanceMode perfMode)37*05767d91SRobert Wu     bool openStream(Direction direction, AudioApi audioApi, PerformanceMode perfMode) {
38*05767d91SRobert Wu         mBuilder.setDirection(direction);
39*05767d91SRobert Wu         if (mBuilder.isAAudioRecommended()) {
40*05767d91SRobert Wu             mBuilder.setAudioApi(audioApi);
41*05767d91SRobert Wu         }
42*05767d91SRobert Wu         mBuilder.setPerformanceMode(perfMode);
43*05767d91SRobert Wu         mBuilder.setChannelCount(1);
44*05767d91SRobert Wu         mBuilder.setFormat(AudioFormat::I16);
45*05767d91SRobert Wu         Result r = mBuilder.openStream(&mStream);
46*05767d91SRobert Wu         EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r);
47*05767d91SRobert Wu         if (r != Result::OK)
48*05767d91SRobert Wu             return false;
49*05767d91SRobert Wu 
50*05767d91SRobert Wu         Direction d = mStream->getDirection();
51*05767d91SRobert Wu         EXPECT_EQ(d, direction) << convertToText(mStream->getDirection());
52*05767d91SRobert Wu         return (d == direction);
53*05767d91SRobert Wu     }
54*05767d91SRobert Wu 
openStream(AudioStreamBuilder & builder)55*05767d91SRobert Wu     bool openStream(AudioStreamBuilder &builder) {
56*05767d91SRobert Wu         Result r = builder.openStream(&mStream);
57*05767d91SRobert Wu         EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r);
58*05767d91SRobert Wu         return (r == Result::OK);
59*05767d91SRobert Wu     }
60*05767d91SRobert Wu 
stopWhileUsingLargeBuffer()61*05767d91SRobert Wu     void stopWhileUsingLargeBuffer() {
62*05767d91SRobert Wu         StreamState next = StreamState::Unknown;
63*05767d91SRobert Wu         auto r = mStream->requestStart();
64*05767d91SRobert Wu         EXPECT_EQ(r, Result::OK);
65*05767d91SRobert Wu         r = mStream->waitForStateChange(StreamState::Starting, &next, kTimeoutInNanos);
66*05767d91SRobert Wu         EXPECT_EQ(r, Result::OK);
67*05767d91SRobert Wu         EXPECT_EQ(next, StreamState::Started) << "next = " << convertToText(next);
68*05767d91SRobert Wu 
69*05767d91SRobert Wu         AudioStream *str = mStream;
70*05767d91SRobert Wu 
71*05767d91SRobert Wu         int16_t buffer[kFramesToWrite] = {};
72*05767d91SRobert Wu 
73*05767d91SRobert Wu         std::thread stopper([str] {
74*05767d91SRobert Wu             int64_t estimatedCompletionTimeUs = kMicroSecondsPerSecond * kFramesToWrite / str->getSampleRate();
75*05767d91SRobert Wu             usleep(estimatedCompletionTimeUs / 2); // Stop halfway during the read/write
76*05767d91SRobert Wu             EXPECT_EQ(str->close(), Result::OK);
77*05767d91SRobert Wu         });
78*05767d91SRobert Wu 
79*05767d91SRobert Wu         if (mBuilder.getDirection() == Direction::Output) {
80*05767d91SRobert Wu             r = mStream->write(&buffer, kFramesToWrite, kTimeoutInNanos);
81*05767d91SRobert Wu         } else {
82*05767d91SRobert Wu             r = mStream->read(&buffer, kFramesToWrite, kTimeoutInNanos);
83*05767d91SRobert Wu         }
84*05767d91SRobert Wu         if (r != Result::OK) {
85*05767d91SRobert Wu             FAIL() << "Could not read/write to audio stream: " << static_cast<int>(r);
86*05767d91SRobert Wu         }
87*05767d91SRobert Wu 
88*05767d91SRobert Wu         stopper.join();
89*05767d91SRobert Wu         r = mStream->waitForStateChange(StreamState::Started, &next,
90*05767d91SRobert Wu                                         1000 * kNanosPerMillisecond);
91*05767d91SRobert Wu         if ((r != Result::ErrorClosed) && (r != Result::OK)) {
92*05767d91SRobert Wu             FAIL() << "Wrong closed result type: " << static_cast<int>(r);
93*05767d91SRobert Wu         }
94*05767d91SRobert Wu     }
95*05767d91SRobert Wu 
96*05767d91SRobert Wu     AudioStreamBuilder mBuilder;
97*05767d91SRobert Wu     AudioStream *mStream = nullptr;
98*05767d91SRobert Wu     static constexpr int kTimeoutInNanos = 1000 * kNanosPerMillisecond;
99*05767d91SRobert Wu     static constexpr int64_t kMicroSecondsPerSecond = 1000000;
100*05767d91SRobert Wu     static constexpr int kFramesToWrite = 10000;
101*05767d91SRobert Wu 
102*05767d91SRobert Wu };
103*05767d91SRobert Wu 
TEST_P(TestStreamStop,VerifyTestStreamStop)104*05767d91SRobert Wu TEST_P(TestStreamStop, VerifyTestStreamStop) {
105*05767d91SRobert Wu     const Direction direction = std::get<0>(GetParam());
106*05767d91SRobert Wu     const AudioApi audioApi = std::get<1>(GetParam());
107*05767d91SRobert Wu     const PerformanceMode performanceMode = std::get<2>(GetParam());
108*05767d91SRobert Wu 
109*05767d91SRobert Wu     ASSERT_TRUE(openStream(direction, audioApi, performanceMode));
110*05767d91SRobert Wu     stopWhileUsingLargeBuffer();
111*05767d91SRobert Wu }
112*05767d91SRobert Wu 
113*05767d91SRobert Wu INSTANTIATE_TEST_SUITE_P(
114*05767d91SRobert Wu         TestStreamStopTest,
115*05767d91SRobert Wu         TestStreamStop,
116*05767d91SRobert Wu         ::testing::Values(
117*05767d91SRobert Wu                 TestStreamStopParams({Direction::Output, AudioApi::AAudio, PerformanceMode::LowLatency}),
118*05767d91SRobert Wu                 TestStreamStopParams({Direction::Output, AudioApi::AAudio, PerformanceMode::None}),
119*05767d91SRobert Wu                 TestStreamStopParams({Direction::Output, AudioApi::AAudio, PerformanceMode::PowerSaving}),
120*05767d91SRobert Wu                 TestStreamStopParams({Direction::Output, AudioApi::OpenSLES, PerformanceMode::LowLatency}),
121*05767d91SRobert Wu                 TestStreamStopParams({Direction::Output, AudioApi::OpenSLES, PerformanceMode::None}),
122*05767d91SRobert Wu                 TestStreamStopParams({Direction::Output, AudioApi::OpenSLES, PerformanceMode::PowerSaving}),
123*05767d91SRobert Wu                 TestStreamStopParams({Direction::Input, AudioApi::AAudio, PerformanceMode::LowLatency}),
124*05767d91SRobert Wu                 TestStreamStopParams({Direction::Input, AudioApi::AAudio, PerformanceMode::None}),
125*05767d91SRobert Wu                 TestStreamStopParams({Direction::Input, AudioApi::AAudio, PerformanceMode::PowerSaving}),
126*05767d91SRobert Wu                 TestStreamStopParams({Direction::Input, AudioApi::OpenSLES, PerformanceMode::LowLatency}),
127*05767d91SRobert Wu                 TestStreamStopParams({Direction::Input, AudioApi::OpenSLES, PerformanceMode::None}),
128*05767d91SRobert Wu                 TestStreamStopParams({Direction::Input, AudioApi::OpenSLES, PerformanceMode::PowerSaving})
129*05767d91SRobert Wu         )
130*05767d91SRobert Wu );
131