1 /*
2  * Copyright (C) 2022 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 #include "tests/UsecaseValidator-test.h"
17 
18 #include <gtest/gtest.h>
19 
20 namespace android {
21 namespace media {
22 
23 /**
24  * Helper test functions.
25  */
26 
27 /**
28  * Register a mock stream.
29  */
testRegisterStream(bool outputFlagGame)30 audio_io_handle_t UsecaseValidatorTest::testRegisterStream(bool outputFlagGame) {
31     static int streamId = 0;
32     status_t result;
33     static audio_config_base_t audioConfig = AUDIO_CONFIG_BASE_INITIALIZER;
34     audio_output_flags_t outputFlags = outputFlagGame ? GAME_OUTPUT_FLAGS : MEDIA_OUTPUT_FLAGS;
35 
36     result = m_validator->registerStream(++streamId, audioConfig, outputFlags);
37 
38     return result == OK ? streamId : 0;
39 }
40 
41 /**
42  * Create a mock portId.
43  */
testCreatePortId(audio_io_handle_t streamId)44 audio_port_handle_t UsecaseValidatorTest::testCreatePortId(audio_io_handle_t streamId) {
45     static int portId = 0;
46 
47     return (streamId << 8) | (++portId);
48 }
49 
50 /**
51  * Add a mock portId to a stream and verify.
52  */
testStartClient(audio_io_handle_t streamId,audio_port_handle_t portId,audio_attributes_t attributes)53 error::Result<audio_attributes_t> UsecaseValidatorTest::testStartClient(audio_io_handle_t streamId,
54         audio_port_handle_t portId,
55         audio_attributes_t attributes) {
56     content::AttributionSourceState attributionSource;
57 
58     return m_validator->startClient(streamId, portId, attributionSource, attributes, NULL);
59 }
60 
61 /**
62  * Verify a mock stream.
63  */
testVerifyAudioAttributes(audio_io_handle_t streamId,audio_usage_t usage)64 error::Result<audio_attributes_t> UsecaseValidatorTest::testVerifyAudioAttributes(
65         audio_io_handle_t streamId,
66         audio_usage_t usage) {
67     content::AttributionSourceState attributionSource;
68     audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
69     attributes.usage = usage;
70 
71     return m_validator->verifyAudioAttributes(streamId, attributionSource, attributes);
72 }
73 
74 /**
75  * Test functions.
76  */
77 
78 /**
79  * Test adding and removing streams.
80  */
TEST_F(UsecaseLookupTest,testAddAndRemoveStream)81 TEST_F(UsecaseLookupTest, testAddAndRemoveStream) {
82     addStream(1, false);
83     addStream(2, true);
84 
85     EXPECT_NE(m_streams.find(1), m_streams.end());
86     EXPECT_NE(m_streams.find(2), m_streams.end());
87     EXPECT_EQ(m_streams.find(3), m_streams.end());
88 
89     EXPECT_FALSE(isGameStream(1));
90     EXPECT_TRUE(isGameStream(2));
91     EXPECT_FALSE(isGameStream(3));
92 
93     removeStream(2);
94 
95     EXPECT_FALSE(isGameStream(2));
96 }
97 
98 /**
99  * Verify attributes usage for stream.
100  */
TEST_F(UsecaseValidatorTest,testAttributesUsage)101 TEST_F(UsecaseValidatorTest, testAttributesUsage) {
102     audio_io_handle_t gameStreamId, mediaStreamId;
103 
104     // Register game and media stream.
105     gameStreamId = testRegisterStream(true);
106     mediaStreamId = testRegisterStream(false);
107     EXPECT_NE(gameStreamId, 0);
108     EXPECT_NE(mediaStreamId, 0);
109     EXPECT_NE(gameStreamId, mediaStreamId);
110 
111     // Verify attributes on game stream.
112     auto attr = testVerifyAudioAttributes(gameStreamId, AUDIO_USAGE_GAME);
113     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_GAME);
114 
115     // Verify attributes on media stream.
116     attr = testVerifyAudioAttributes(mediaStreamId, AUDIO_USAGE_MEDIA);
117     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_MEDIA);
118 
119     EXPECT_EQ(m_validator->unregisterStream(gameStreamId), 0);
120     EXPECT_EQ(m_validator->unregisterStream(mediaStreamId), 0);
121 }
122 
123 /**
124  * Test hanging client.
125  */
TEST_F(UsecaseValidatorTest,testHangingClient)126 TEST_F(UsecaseValidatorTest, testHangingClient) {
127     audio_io_handle_t gameStreamId, mediaStreamId;
128     audio_port_handle_t gamePortId, mediaPortId;
129 
130     // Register game and media stream.
131     gameStreamId = testRegisterStream(true);
132     EXPECT_NE(gameStreamId, 0);
133     mediaStreamId = testRegisterStream(false);
134     EXPECT_NE(mediaStreamId, 0);
135 
136     // Assign portId.
137     gamePortId = testCreatePortId(gameStreamId);
138     EXPECT_NE(gamePortId, 0);
139     mediaPortId = testCreatePortId(mediaStreamId);
140     EXPECT_NE(mediaPortId, 0);
141 
142     audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
143     attributes.usage = AUDIO_USAGE_GAME;
144     // Start client on game stream.
145     testStartClient(gameStreamId, gamePortId, attributes);
146 
147     attributes.usage = AUDIO_USAGE_MEDIA;
148     // Start client on media stream.
149     testStartClient(mediaStreamId, mediaPortId, attributes);
150 
151     // Unregister media stream before stopClient.
152     EXPECT_EQ(m_validator->unregisterStream(gameStreamId), 0);
153     EXPECT_EQ(m_validator->unregisterStream(mediaStreamId), 0);
154 }
155 
156 /**
157  * Verify attributes usage does not change.
158  */
TEST_F(UsecaseValidatorTest,testAttributesUsageUnchanged)159 TEST_F(UsecaseValidatorTest, testAttributesUsageUnchanged) {
160     audio_io_handle_t gameStreamId, mediaStreamId;
161     audio_port_handle_t gamePortId, mediaPortId, unknownPortId, voiceCommPortId;
162 
163     // Register game and media stream.
164     gameStreamId = testRegisterStream(true);
165     EXPECT_NE(gameStreamId, 0);
166     mediaStreamId = testRegisterStream(false);
167     EXPECT_NE(mediaStreamId, 0);
168 
169     // Assign portId.
170     gamePortId = testCreatePortId(gameStreamId);
171     EXPECT_NE(gamePortId, 0);
172     mediaPortId = testCreatePortId(mediaStreamId);
173     EXPECT_NE(mediaPortId, 0);
174     unknownPortId = testCreatePortId(mediaStreamId);
175     EXPECT_NE(unknownPortId, 0);
176     voiceCommPortId = testCreatePortId(gameStreamId);
177     EXPECT_NE(voiceCommPortId, 0);
178 
179     audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
180     // Verify attributes on game stream.
181     attributes.usage = AUDIO_USAGE_GAME;
182     auto attr = testStartClient(gameStreamId, gamePortId, attributes);
183     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_GAME);
184 
185     attributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION;
186     attr = testStartClient(gameStreamId, voiceCommPortId, attributes);
187     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_VOICE_COMMUNICATION);
188 
189     // Verify attributes on media stream.
190     attributes.usage = AUDIO_USAGE_MEDIA;
191     attr = testStartClient(mediaStreamId, mediaPortId, attributes);
192     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_MEDIA);
193 
194     attributes.usage = AUDIO_USAGE_UNKNOWN;
195     attr = testStartClient(mediaStreamId, unknownPortId, attributes);
196     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_UNKNOWN);
197 
198     // Stop client on game and media stream.
199     EXPECT_EQ(m_validator->stopClient(gameStreamId, gamePortId), 0);
200     EXPECT_EQ(m_validator->stopClient(mediaStreamId, mediaPortId), 0);
201 
202     // Unregister game and media stream.
203     EXPECT_EQ(m_validator->unregisterStream(gameStreamId), 0);
204     EXPECT_EQ(m_validator->unregisterStream(mediaStreamId), 0);
205 }
206 
207 /**
208  * Verify attributes usage changes.
209  */
TEST_F(UsecaseValidatorTest,testAttributesUsageChanged)210 TEST_F(UsecaseValidatorTest, testAttributesUsageChanged) {
211     audio_io_handle_t gameStreamId;
212     audio_port_handle_t mediaPortId, unknownPortId;
213 
214     // Register game and media stream.
215     gameStreamId = testRegisterStream(true);
216     EXPECT_NE(gameStreamId, 0);
217 
218     // Assign portId.
219     mediaPortId = testCreatePortId(gameStreamId);
220     EXPECT_NE(mediaPortId, 0);
221     unknownPortId = testCreatePortId(gameStreamId);
222     EXPECT_NE(unknownPortId, 0);
223 
224     audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
225     attributes.flags = AUDIO_FLAG_LOW_LATENCY;
226     // Verify attributes on game stream.
227     attributes.usage = AUDIO_USAGE_MEDIA;
228     auto attr = testStartClient(gameStreamId, mediaPortId, attributes);
229     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_GAME);
230 
231     attributes.usage = AUDIO_USAGE_UNKNOWN;
232     attr = testStartClient(gameStreamId, unknownPortId, attributes);
233     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_GAME);
234 
235     // Unregister game stream.
236     EXPECT_EQ(m_validator->unregisterStream(gameStreamId), 0);
237 }
238 
239 /**
240  * Verify attributes usage does not change for non low latency clients.
241  */
TEST_F(UsecaseValidatorTest,testAttributesUsageUnChangedIfNotLowLatency)242 TEST_F(UsecaseValidatorTest, testAttributesUsageUnChangedIfNotLowLatency) {
243     audio_io_handle_t gameStreamId;
244     audio_port_handle_t mediaPortId, unknownPortId;
245 
246     // Register game and media stream.
247     gameStreamId = testRegisterStream(true);
248     EXPECT_NE(gameStreamId, 0);
249 
250     // Assign portId.
251     mediaPortId = testCreatePortId(gameStreamId);
252     EXPECT_NE(mediaPortId, 0);
253     unknownPortId = testCreatePortId(gameStreamId);
254     EXPECT_NE(unknownPortId, 0);
255 
256     audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
257     // Verify attributes on game stream.
258     attributes.usage = AUDIO_USAGE_MEDIA;
259     auto attr = testStartClient(gameStreamId, mediaPortId, attributes);
260     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_MEDIA);
261 
262     attributes.usage = AUDIO_USAGE_UNKNOWN;
263     attr = testStartClient(gameStreamId, unknownPortId, attributes);
264     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_UNKNOWN);
265 
266     // Unregister game stream.
267     EXPECT_EQ(m_validator->unregisterStream(gameStreamId), 0);
268 }
269 
270 /**
271  * Verify attributes usage does not change for content type speech.
272  */
TEST_F(UsecaseValidatorTest,testAttributesUsageUnChangedIfSpeech)273 TEST_F(UsecaseValidatorTest, testAttributesUsageUnChangedIfSpeech) {
274     audio_io_handle_t gameStreamId;
275     audio_port_handle_t mediaPortId, unknownPortId;
276 
277     // Register game and media stream.
278     gameStreamId = testRegisterStream(true);
279     EXPECT_NE(gameStreamId, 0);
280 
281     // Assign portId.
282     mediaPortId = testCreatePortId(gameStreamId);
283     EXPECT_NE(mediaPortId, 0);
284     unknownPortId = testCreatePortId(gameStreamId);
285     EXPECT_NE(unknownPortId, 0);
286 
287     audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
288     // Verify attributes on game stream.
289     attributes.usage = AUDIO_USAGE_MEDIA;
290     attributes.content_type = AUDIO_CONTENT_TYPE_SPEECH;
291     auto attr = testStartClient(gameStreamId, mediaPortId, attributes);
292     EXPECT_EQ(attr.value().usage, AUDIO_USAGE_MEDIA);
293 
294     // Unregister game stream.
295     EXPECT_EQ(m_validator->unregisterStream(gameStreamId), 0);
296 }
297 
298 }  // namespace media
299 }  // namespace android
300