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