1 // Copyright 2016 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <gtest/gtest.h>
6 #include <stdio.h>
7 #include <syslog.h>
8
9 #include <vector>
10 #include <map>
11
12 extern "C" {
13 #include "cras_observer.c"
14 }
15
16 namespace {
17
18 static size_t cras_alert_destroy_called;
19 static size_t cras_alert_create_called;
20 static std::vector<struct cras_alert *> cras_alert_create_return_values;
21 typedef std::map<struct cras_alert *, void *> alert_callback_map;
22 static alert_callback_map cras_alert_create_prepare_map;
23 static alert_callback_map cras_alert_add_callback_map;
24 typedef std::map<struct cras_alert *, unsigned int> alert_flags_map;
25 static alert_flags_map cras_alert_create_flags_map;
26 static struct cras_alert *cras_alert_pending_alert_value;
27 static void *cras_alert_pending_data_value = NULL;
28 static size_t cras_alert_pending_data_size_value;
29 static size_t cras_iodev_list_update_device_list_called;
30 static std::vector<void *> cb_context;
31 static size_t cb_output_volume_changed_called;
32 static std::vector<int32_t> cb_output_volume_changed_volume;
33 static size_t cb_output_mute_changed_called;
34 static std::vector<int> cb_output_mute_changed_muted;
35 static std::vector<int> cb_output_mute_changed_user_muted;
36 static std::vector<int> cb_output_mute_changed_mute_locked;
37 static size_t cb_capture_gain_changed_called;
38 static std::vector<int32_t> cb_capture_gain_changed_gain;
39 static size_t cb_capture_mute_changed_called;
40 static std::vector<int> cb_capture_mute_changed_muted;
41 static std::vector<int> cb_capture_mute_changed_mute_locked;
42 static size_t cb_nodes_changed_called;
43 static size_t cb_active_node_changed_called;
44 static std::vector<enum CRAS_STREAM_DIRECTION> cb_active_node_changed_dir;
45 static std::vector<cras_node_id_t> cb_active_node_changed_node_id;
46 static size_t cb_output_node_volume_changed_called;
47 static std::vector<cras_node_id_t> cb_output_node_volume_changed_node_id;
48 static std::vector<int32_t> cb_output_node_volume_changed_volume;
49 static size_t cb_node_left_right_swapped_changed_called;
50 static std::vector<cras_node_id_t> cb_node_left_right_swapped_changed_node_id;
51 static std::vector<int> cb_node_left_right_swapped_changed_swapped;
52 static size_t cb_input_node_gain_changed_called;
53 static std::vector<cras_node_id_t> cb_input_node_gain_changed_node_id;
54 static std::vector<int32_t> cb_input_node_gain_changed_gain;
55 static size_t cb_num_active_streams_changed_called;
56 static std::vector<enum CRAS_STREAM_DIRECTION>
57 cb_num_active_streams_changed_dir;
58 static std::vector<uint32_t> cb_num_active_streams_changed_num;
59
ResetStubData()60 static void ResetStubData() {
61 cras_alert_destroy_called = 0;
62 cras_alert_create_called = 0;
63 cras_alert_create_return_values.clear();
64 cras_alert_create_prepare_map.clear();
65 cras_alert_create_flags_map.clear();
66 cras_alert_add_callback_map.clear();
67 cras_alert_pending_alert_value = NULL;
68 cras_alert_pending_data_size_value = 0;
69 if (cras_alert_pending_data_value) {
70 free(cras_alert_pending_data_value);
71 cras_alert_pending_data_value = NULL;
72 }
73 cras_iodev_list_update_device_list_called = 0;
74 cb_context.clear();
75 cb_output_volume_changed_called = 0;
76 cb_output_volume_changed_volume.clear();
77 cb_output_mute_changed_called = 0;
78 cb_output_mute_changed_muted.clear();
79 cb_output_mute_changed_user_muted.clear();
80 cb_output_mute_changed_mute_locked.clear();
81 cb_capture_gain_changed_called = 0;
82 cb_capture_gain_changed_gain.clear();
83 cb_capture_mute_changed_called = 0;
84 cb_capture_mute_changed_muted.clear();
85 cb_capture_mute_changed_mute_locked.clear();
86 cb_nodes_changed_called = 0;
87 cb_active_node_changed_called = 0;
88 cb_active_node_changed_dir.clear();
89 cb_active_node_changed_node_id.clear();
90 cb_output_node_volume_changed_called = 0;
91 cb_output_node_volume_changed_node_id.clear();
92 cb_output_node_volume_changed_volume.clear();
93 cb_node_left_right_swapped_changed_called = 0;
94 cb_node_left_right_swapped_changed_node_id.clear();
95 cb_node_left_right_swapped_changed_swapped.clear();
96 cb_input_node_gain_changed_called = 0;
97 cb_input_node_gain_changed_node_id.clear();
98 cb_input_node_gain_changed_gain.clear();
99 cb_num_active_streams_changed_called = 0;
100 cb_num_active_streams_changed_dir.clear();
101 cb_num_active_streams_changed_num.clear();
102 }
103
104 /* System output volume changed. */
cb_output_volume_changed(void * context,int32_t volume)105 void cb_output_volume_changed(void *context, int32_t volume) {
106 cb_output_volume_changed_called++;
107 cb_context.push_back(context);
108 cb_output_volume_changed_volume.push_back(volume);
109 }
110 /* System output mute changed. */
cb_output_mute_changed(void * context,int muted,int user_muted,int mute_locked)111 void cb_output_mute_changed(void *context,
112 int muted, int user_muted, int mute_locked) {
113 cb_output_mute_changed_called++;
114 cb_context.push_back(context);
115 cb_output_mute_changed_muted.push_back(muted);
116 cb_output_mute_changed_user_muted.push_back(user_muted);
117 cb_output_mute_changed_mute_locked.push_back(mute_locked);
118 }
119 /* System input/capture gain changed. */
cb_capture_gain_changed(void * context,int32_t gain)120 void cb_capture_gain_changed(void *context, int32_t gain) {
121 cb_capture_gain_changed_called++;
122 cb_context.push_back(context);
123 cb_capture_gain_changed_gain.push_back(gain);
124 }
125
126 /* System input/capture mute changed. */
cb_capture_mute_changed(void * context,int muted,int mute_locked)127 void cb_capture_mute_changed(void *context, int muted, int mute_locked) {
128 cb_capture_mute_changed_called++;
129 cb_context.push_back(context);
130 cb_capture_mute_changed_muted.push_back(muted);
131 cb_capture_mute_changed_mute_locked.push_back(mute_locked);
132 }
133
134 /* Device or node topology changed. */
cb_nodes_changed(void * context)135 void cb_nodes_changed(void *context) {
136 cb_nodes_changed_called++;
137 cb_context.push_back(context);
138 }
139
140 /* Active node changed. A notification is sent for every change.
141 * When there is no active node, node_id is 0. */
cb_active_node_changed(void * context,enum CRAS_STREAM_DIRECTION dir,cras_node_id_t node_id)142 void cb_active_node_changed(void *context,
143 enum CRAS_STREAM_DIRECTION dir,
144 cras_node_id_t node_id) {
145 cb_active_node_changed_called++;
146 cb_context.push_back(context);
147 cb_active_node_changed_dir.push_back(dir);
148 cb_active_node_changed_node_id.push_back(node_id);
149 }
150
151 /* Output node volume changed. */
cb_output_node_volume_changed(void * context,cras_node_id_t node_id,int32_t volume)152 void cb_output_node_volume_changed(void *context,
153 cras_node_id_t node_id,
154 int32_t volume) {
155 cb_output_node_volume_changed_called++;
156 cb_context.push_back(context);
157 cb_output_node_volume_changed_node_id.push_back(node_id);
158 cb_output_node_volume_changed_volume.push_back(volume);
159 }
160
161 /* Node left/right swapped state change. */
cb_node_left_right_swapped_changed(void * context,cras_node_id_t node_id,int swapped)162 void cb_node_left_right_swapped_changed(void *context,
163 cras_node_id_t node_id,
164 int swapped) {
165 cb_node_left_right_swapped_changed_called++;
166 cb_context.push_back(context);
167 cb_node_left_right_swapped_changed_node_id.push_back(node_id);
168 cb_node_left_right_swapped_changed_swapped.push_back(swapped);
169 }
170
171 /* Input gain changed. */
cb_input_node_gain_changed(void * context,cras_node_id_t node_id,int32_t gain)172 void cb_input_node_gain_changed(void *context,
173 cras_node_id_t node_id,
174 int32_t gain) {
175 cb_input_node_gain_changed_called++;
176 cb_context.push_back(context);
177 cb_input_node_gain_changed_node_id.push_back(node_id);
178 cb_input_node_gain_changed_gain.push_back(gain);
179 }
180
181 /* Number of active streams changed. */
cb_num_active_streams_changed(void * context,enum CRAS_STREAM_DIRECTION dir,uint32_t num_active_streams)182 void cb_num_active_streams_changed(void *context,
183 enum CRAS_STREAM_DIRECTION dir,
184 uint32_t num_active_streams) {
185 cb_num_active_streams_changed_called++;
186 cb_context.push_back(context);
187 cb_num_active_streams_changed_dir.push_back(dir);
188 cb_num_active_streams_changed_num.push_back(num_active_streams);
189 }
190
191 class ObserverTest : public testing::Test {
192 protected:
SetUp()193 virtual void SetUp() {
194 int rc;
195
196 ResetStubData();
197 rc = cras_observer_server_init();
198 ASSERT_EQ(0, rc);
199 EXPECT_EQ(15, cras_alert_create_called);
200 EXPECT_EQ(reinterpret_cast<void *>(output_volume_alert),
201 cras_alert_add_callback_map[g_observer->alerts.output_volume]);
202 EXPECT_EQ(reinterpret_cast<void *>(output_mute_alert),
203 cras_alert_add_callback_map[g_observer->alerts.output_mute]);
204 EXPECT_EQ(reinterpret_cast<void *>(capture_gain_alert),
205 cras_alert_add_callback_map[g_observer->alerts.capture_gain]);
206 EXPECT_EQ(reinterpret_cast<void *>(capture_mute_alert),
207 cras_alert_add_callback_map[g_observer->alerts.capture_mute]);
208 EXPECT_EQ(reinterpret_cast<void *>(nodes_alert),
209 cras_alert_add_callback_map[g_observer->alerts.nodes]);
210 EXPECT_EQ(reinterpret_cast<void *>(nodes_prepare),
211 cras_alert_create_prepare_map[g_observer->alerts.nodes]);
212 EXPECT_EQ(reinterpret_cast<void *>(active_node_alert),
213 cras_alert_add_callback_map[g_observer->alerts.active_node]);
214 EXPECT_EQ(CRAS_ALERT_FLAG_KEEP_ALL_DATA,
215 cras_alert_create_flags_map[g_observer->alerts.active_node]);
216 EXPECT_EQ(reinterpret_cast<void *>(output_node_volume_alert),
217 cras_alert_add_callback_map[g_observer->alerts.output_node_volume]);
218 EXPECT_EQ(reinterpret_cast<void *>(node_left_right_swapped_alert),
219 cras_alert_add_callback_map[g_observer->alerts.node_left_right_swapped]);
220 EXPECT_EQ(reinterpret_cast<void *>(input_node_gain_alert),
221 cras_alert_add_callback_map[g_observer->alerts.input_node_gain]);
222 EXPECT_EQ(reinterpret_cast<void *>(num_active_streams_alert),
223 cras_alert_add_callback_map[g_observer->alerts.num_active_streams[
224 CRAS_STREAM_OUTPUT]]);
225 EXPECT_EQ(reinterpret_cast<void *>(num_active_streams_alert),
226 cras_alert_add_callback_map[g_observer->alerts.num_active_streams[
227 CRAS_STREAM_INPUT]]);
228 EXPECT_EQ(reinterpret_cast<void *>(num_active_streams_alert),
229 cras_alert_add_callback_map[g_observer->alerts.num_active_streams[
230 CRAS_STREAM_POST_MIX_PRE_DSP]]);
231 EXPECT_EQ(reinterpret_cast<void *>(suspend_changed_alert),
232 cras_alert_add_callback_map[g_observer->alerts.suspend_changed]);
233 EXPECT_EQ(reinterpret_cast<void *>(hotword_triggered_alert),
234 cras_alert_add_callback_map[g_observer->alerts.hotword_triggered]);
235 EXPECT_EQ(reinterpret_cast<void *>(non_empty_audio_state_changed_alert),
236 cras_alert_add_callback_map[
237 g_observer->alerts.non_empty_audio_state_changed]);
238
239 cras_observer_get_ops(NULL, &ops1_);
240 EXPECT_NE(0, cras_observer_ops_are_empty(&ops1_));
241
242 cras_observer_get_ops(NULL, &ops2_);
243 EXPECT_NE(0, cras_observer_ops_are_empty(&ops2_));
244
245 context1_ = reinterpret_cast<void *>(1);
246 context2_ = reinterpret_cast<void *>(2);
247 }
248
TearDown()249 virtual void TearDown() {
250 cras_observer_server_free();
251 EXPECT_EQ(15, cras_alert_destroy_called);
252 ResetStubData();
253 }
254
DoObserverAlert(cras_alert_cb alert,void * data)255 void DoObserverAlert(cras_alert_cb alert, void *data) {
256 client1_ = cras_observer_add(&ops1_, context1_);
257 client2_ = cras_observer_add(&ops2_, context2_);
258 ASSERT_NE(client1_, reinterpret_cast<struct cras_observer_client *>(NULL));
259 ASSERT_NE(client2_, reinterpret_cast<struct cras_observer_client *>(NULL));
260
261 ASSERT_NE(alert, reinterpret_cast<cras_alert_cb>(NULL));
262 alert(NULL, data);
263
264 EXPECT_EQ(cb_context[0], context1_);
265 EXPECT_EQ(cb_context[1], context2_);
266 }
267
DoObserverRemoveClear(cras_alert_cb alert,void * data)268 void DoObserverRemoveClear(cras_alert_cb alert, void *data) {
269 ASSERT_NE(alert, reinterpret_cast<cras_alert_cb>(NULL));
270 ASSERT_NE(client1_, reinterpret_cast<struct cras_observer_client *>(NULL));
271 ASSERT_NE(client2_, reinterpret_cast<struct cras_observer_client *>(NULL));
272
273 // Test observer removal.
274 cras_observer_remove(client1_);
275 cb_context.clear();
276 alert(NULL, data);
277 EXPECT_EQ(cb_context[0], context2_);
278 EXPECT_EQ(cb_context.size(), 1);
279
280 // Clear out ops1_.
281 cras_observer_get_ops(NULL, &ops1_);
282 EXPECT_NE(0, cras_observer_ops_are_empty(&ops1_));
283
284 // Get the current value of ops2_ into ops1_.
285 cras_observer_get_ops(client2_, &ops1_);
286 EXPECT_EQ(0, memcmp((void *)&ops1_, (void *)&ops2_, sizeof(ops1_)));
287
288 // Clear out opts for client2.
289 cras_observer_get_ops(NULL, &ops2_);
290 EXPECT_NE(0, cras_observer_ops_are_empty(&ops2_));
291 cras_observer_set_ops(client2_, &ops2_);
292
293 cras_observer_remove(client2_);
294 cb_context.clear();
295 alert(NULL, data);
296 // No callbacks executed.
297 EXPECT_EQ(cb_context.size(), 0);
298 }
299
300 struct cras_observer_client *client1_;
301 struct cras_observer_client *client2_;
302 struct cras_observer_ops ops1_;
303 struct cras_observer_ops ops2_;
304 void *context1_;
305 void *context2_;
306 };
307
TEST_F(ObserverTest,NotifyOutputVolume)308 TEST_F(ObserverTest, NotifyOutputVolume) {
309 struct cras_observer_alert_data_volume *data;
310 const int32_t volume = 100;
311
312 cras_observer_notify_output_volume(volume);
313 EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.output_volume);
314 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
315 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
316 data = reinterpret_cast<struct cras_observer_alert_data_volume *>(
317 cras_alert_pending_data_value);
318 EXPECT_EQ(data->volume, volume);
319
320 ops1_.output_volume_changed = cb_output_volume_changed;
321 ops2_.output_volume_changed = cb_output_volume_changed;
322 DoObserverAlert(output_volume_alert, data);
323 ASSERT_EQ(2, cb_output_volume_changed_called);
324 EXPECT_EQ(cb_output_volume_changed_volume[0], volume);
325 EXPECT_EQ(cb_output_volume_changed_volume[1], volume);
326
327 DoObserverRemoveClear(output_volume_alert, data);
328 };
329
TEST_F(ObserverTest,NotifyOutputMute)330 TEST_F(ObserverTest, NotifyOutputMute) {
331 struct cras_observer_alert_data_mute *data;
332 const int muted = 1;
333 const int user_muted = 0;
334 const int mute_locked = 0;
335
336 cras_observer_notify_output_mute(muted, user_muted, mute_locked);
337 EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.output_mute);
338 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
339 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
340 data = reinterpret_cast<struct cras_observer_alert_data_mute *>(
341 cras_alert_pending_data_value);
342 EXPECT_EQ(data->muted, muted);
343 EXPECT_EQ(data->user_muted, user_muted);
344 EXPECT_EQ(data->mute_locked, mute_locked);
345
346 ops1_.output_mute_changed = cb_output_mute_changed;
347 ops2_.output_mute_changed = cb_output_mute_changed;
348 DoObserverAlert(output_mute_alert, data);
349 ASSERT_EQ(2, cb_output_mute_changed_called);
350 EXPECT_EQ(cb_output_mute_changed_muted[0], muted);
351 EXPECT_EQ(cb_output_mute_changed_muted[1], muted);
352 EXPECT_EQ(cb_output_mute_changed_user_muted[0], user_muted);
353 EXPECT_EQ(cb_output_mute_changed_user_muted[1], user_muted);
354 EXPECT_EQ(cb_output_mute_changed_mute_locked[0], mute_locked);
355 EXPECT_EQ(cb_output_mute_changed_mute_locked[1], mute_locked);
356
357 DoObserverRemoveClear(output_mute_alert, data);
358 };
359
TEST_F(ObserverTest,NotifyCaptureGain)360 TEST_F(ObserverTest, NotifyCaptureGain) {
361 struct cras_observer_alert_data_volume *data;
362 const int32_t gain = -20;
363
364 cras_observer_notify_capture_gain(gain);
365 EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.capture_gain);
366 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
367 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
368 data = reinterpret_cast<struct cras_observer_alert_data_volume *>(
369 cras_alert_pending_data_value);
370 EXPECT_EQ(data->volume, gain);
371
372 ops1_.capture_gain_changed = cb_capture_gain_changed;
373 ops2_.capture_gain_changed = cb_capture_gain_changed;
374 DoObserverAlert(capture_gain_alert, data);
375 ASSERT_EQ(2, cb_capture_gain_changed_called);
376 EXPECT_EQ(cb_capture_gain_changed_gain[0], gain);
377 EXPECT_EQ(cb_capture_gain_changed_gain[1], gain);
378
379 DoObserverRemoveClear(capture_gain_alert, data);
380 };
381
TEST_F(ObserverTest,NotifyCaptureMute)382 TEST_F(ObserverTest, NotifyCaptureMute) {
383 struct cras_observer_alert_data_mute *data;
384 const int muted = 1;
385 const int mute_locked = 0;
386
387 cras_observer_notify_capture_mute(muted, mute_locked);
388 EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.capture_mute);
389 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
390 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
391 data = reinterpret_cast<struct cras_observer_alert_data_mute *>(
392 cras_alert_pending_data_value);
393 EXPECT_EQ(data->muted, muted);
394 EXPECT_EQ(data->mute_locked, mute_locked);
395
396 ops1_.capture_mute_changed = cb_capture_mute_changed;
397 ops2_.capture_mute_changed = cb_capture_mute_changed;
398 DoObserverAlert(capture_mute_alert, data);
399 ASSERT_EQ(2, cb_capture_mute_changed_called);
400 EXPECT_EQ(cb_capture_mute_changed_muted[0], muted);
401 EXPECT_EQ(cb_capture_mute_changed_muted[1], muted);
402 EXPECT_EQ(cb_capture_mute_changed_mute_locked[0], mute_locked);
403 EXPECT_EQ(cb_capture_mute_changed_mute_locked[1], mute_locked);
404
405 DoObserverRemoveClear(capture_mute_alert, data);
406 };
407
TEST_F(ObserverTest,NotifyNodes)408 TEST_F(ObserverTest, NotifyNodes) {
409 cras_observer_notify_nodes();
410 EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.nodes);
411
412 ops1_.nodes_changed = cb_nodes_changed;
413 ops2_.nodes_changed = cb_nodes_changed;
414 DoObserverAlert(nodes_alert, NULL);
415 ASSERT_EQ(2, cb_nodes_changed_called);
416
417 DoObserverRemoveClear(nodes_alert, NULL);
418 };
419
TEST_F(ObserverTest,NotifyActiveNode)420 TEST_F(ObserverTest, NotifyActiveNode) {
421 struct cras_observer_alert_data_active_node *data;
422 const enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_INPUT;
423 const cras_node_id_t node_id = 0x0001000100020002;
424
425 cras_observer_notify_active_node(dir, node_id);
426 EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.active_node);
427 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
428 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
429 data = reinterpret_cast<struct cras_observer_alert_data_active_node *>(
430 cras_alert_pending_data_value);
431 EXPECT_EQ(data->node_id, node_id);
432 EXPECT_EQ(data->direction, dir);
433
434 ops1_.active_node_changed = cb_active_node_changed;
435 ops2_.active_node_changed = cb_active_node_changed;
436 DoObserverAlert(active_node_alert, data);
437 ASSERT_EQ(2, cb_active_node_changed_called);
438 EXPECT_EQ(cb_active_node_changed_dir[0], dir);
439 EXPECT_EQ(cb_active_node_changed_dir[1], dir);
440 EXPECT_EQ(cb_active_node_changed_node_id[0], node_id);
441 EXPECT_EQ(cb_active_node_changed_node_id[1], node_id);
442
443 DoObserverRemoveClear(active_node_alert, data);
444 };
445
TEST_F(ObserverTest,NotifyOutputNodeVolume)446 TEST_F(ObserverTest, NotifyOutputNodeVolume) {
447 struct cras_observer_alert_data_node_volume *data;
448 const cras_node_id_t node_id = 0x0001000100020002;
449 const int32_t volume = 100;
450
451 cras_observer_notify_output_node_volume(node_id, volume);
452 EXPECT_EQ(cras_alert_pending_alert_value,
453 g_observer->alerts.output_node_volume);
454 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
455 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
456 data = reinterpret_cast<struct cras_observer_alert_data_node_volume *>(
457 cras_alert_pending_data_value);
458 EXPECT_EQ(data->node_id, node_id);
459 EXPECT_EQ(data->volume, volume);
460
461 ops1_.output_node_volume_changed = cb_output_node_volume_changed;
462 ops2_.output_node_volume_changed = cb_output_node_volume_changed;
463 DoObserverAlert(output_node_volume_alert, data);
464 ASSERT_EQ(2, cb_output_node_volume_changed_called);
465 EXPECT_EQ(cb_output_node_volume_changed_volume[0], volume);
466 EXPECT_EQ(cb_output_node_volume_changed_volume[1], volume);
467 EXPECT_EQ(cb_output_node_volume_changed_node_id[0], node_id);
468 EXPECT_EQ(cb_output_node_volume_changed_node_id[1], node_id);
469
470 DoObserverRemoveClear(output_node_volume_alert, data);
471 };
472
TEST_F(ObserverTest,NotifyNodeLeftRightSwapped)473 TEST_F(ObserverTest, NotifyNodeLeftRightSwapped) {
474 struct cras_observer_alert_data_node_lr_swapped *data;
475 const cras_node_id_t node_id = 0x0001000100020002;
476 const int swapped = 1;
477
478 cras_observer_notify_node_left_right_swapped(node_id, swapped);
479 EXPECT_EQ(cras_alert_pending_alert_value,
480 g_observer->alerts.node_left_right_swapped);
481 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
482 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
483 data = reinterpret_cast<struct cras_observer_alert_data_node_lr_swapped *>(
484 cras_alert_pending_data_value);
485 EXPECT_EQ(data->node_id, node_id);
486 EXPECT_EQ(data->swapped, swapped);
487
488 ops1_.node_left_right_swapped_changed = cb_node_left_right_swapped_changed;
489 ops2_.node_left_right_swapped_changed = cb_node_left_right_swapped_changed;
490 DoObserverAlert(node_left_right_swapped_alert, data);
491 ASSERT_EQ(2, cb_node_left_right_swapped_changed_called);
492 EXPECT_EQ(cb_node_left_right_swapped_changed_swapped[0], swapped);
493 EXPECT_EQ(cb_node_left_right_swapped_changed_swapped[1], swapped);
494 EXPECT_EQ(cb_node_left_right_swapped_changed_node_id[0], node_id);
495 EXPECT_EQ(cb_node_left_right_swapped_changed_node_id[1], node_id);
496
497 DoObserverRemoveClear(node_left_right_swapped_alert, data);
498 };
499
TEST_F(ObserverTest,NotifyInputNodeGain)500 TEST_F(ObserverTest, NotifyInputNodeGain) {
501 struct cras_observer_alert_data_node_volume *data;
502 const cras_node_id_t node_id = 0x0001000100020002;
503 const int32_t gain = -20;
504
505 cras_observer_notify_input_node_gain(node_id, gain);
506 EXPECT_EQ(cras_alert_pending_alert_value,
507 g_observer->alerts.input_node_gain);
508 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
509 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
510 data = reinterpret_cast<struct cras_observer_alert_data_node_volume *>(
511 cras_alert_pending_data_value);
512 EXPECT_EQ(data->node_id, node_id);
513 EXPECT_EQ(data->volume, gain);
514
515 ops1_.input_node_gain_changed = cb_input_node_gain_changed;
516 ops2_.input_node_gain_changed = cb_input_node_gain_changed;
517 DoObserverAlert(input_node_gain_alert, data);
518 ASSERT_EQ(2, cb_input_node_gain_changed_called);
519 EXPECT_EQ(cb_input_node_gain_changed_gain[0], gain);
520 EXPECT_EQ(cb_input_node_gain_changed_gain[1], gain);
521 EXPECT_EQ(cb_input_node_gain_changed_node_id[0], node_id);
522 EXPECT_EQ(cb_input_node_gain_changed_node_id[1], node_id);
523
524 DoObserverRemoveClear(input_node_gain_alert, data);
525 };
526
TEST_F(ObserverTest,NotifySuspendChanged)527 TEST_F(ObserverTest, NotifySuspendChanged) {
528 struct cras_observer_alert_data_suspend *data;
529
530 cras_observer_notify_suspend_changed(1);
531 EXPECT_EQ(cras_alert_pending_alert_value,
532 g_observer->alerts.suspend_changed);
533 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
534 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
535 data = reinterpret_cast<struct cras_observer_alert_data_suspend *>(
536 cras_alert_pending_data_value);
537 EXPECT_EQ(data->suspended, 1);
538
539 cras_observer_notify_suspend_changed(0);
540 EXPECT_EQ(cras_alert_pending_alert_value,
541 g_observer->alerts.suspend_changed);
542 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
543 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
544 data = reinterpret_cast<struct cras_observer_alert_data_suspend *>(
545 cras_alert_pending_data_value);
546 EXPECT_EQ(data->suspended, 0);
547 }
548
TEST_F(ObserverTest,NotifyNumActiveStreams)549 TEST_F(ObserverTest, NotifyNumActiveStreams) {
550 struct cras_observer_alert_data_streams *data;
551 const enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_INPUT;
552 const uint32_t active_streams = 10;
553
554 cras_observer_notify_num_active_streams(dir, active_streams);
555 EXPECT_EQ(cras_alert_pending_alert_value,
556 g_observer->alerts.num_active_streams[CRAS_STREAM_INPUT]);
557 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
558 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
559 data = reinterpret_cast<struct cras_observer_alert_data_streams *>(
560 cras_alert_pending_data_value);
561 EXPECT_EQ(data->num_active_streams, active_streams);
562 EXPECT_EQ(data->direction, dir);
563
564 ops1_.num_active_streams_changed = cb_num_active_streams_changed;
565 ops2_.num_active_streams_changed = cb_num_active_streams_changed;
566 DoObserverAlert(num_active_streams_alert, data);
567 ASSERT_EQ(2, cb_num_active_streams_changed_called);
568 EXPECT_EQ(cb_num_active_streams_changed_dir[0], dir);
569 EXPECT_EQ(cb_num_active_streams_changed_dir[1], dir);
570 EXPECT_EQ(cb_num_active_streams_changed_num[0], active_streams);
571 EXPECT_EQ(cb_num_active_streams_changed_num[1], active_streams);
572
573 DoObserverRemoveClear(num_active_streams_alert, data);
574 };
575
TEST_F(ObserverTest,NotifyHotwordTriggered)576 TEST_F(ObserverTest, NotifyHotwordTriggered) {
577 struct cras_observer_alert_data_hotword_triggered *data;
578
579 cras_observer_notify_hotword_triggered(100, 200);
580 EXPECT_EQ(cras_alert_pending_alert_value,
581 g_observer->alerts.hotword_triggered);
582 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
583 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
584 data = reinterpret_cast<struct cras_observer_alert_data_hotword_triggered *>(
585 cras_alert_pending_data_value);
586 EXPECT_EQ(data->tv_sec, 100);
587 EXPECT_EQ(data->tv_nsec, 200);
588 }
589
TEST_F(ObserverTest,NonEmpyAudioStateChanged)590 TEST_F(ObserverTest, NonEmpyAudioStateChanged) {
591 struct cras_observer_non_empty_audio_state *data;
592
593 cras_observer_notify_non_empty_audio_state_changed(1);
594 EXPECT_EQ(cras_alert_pending_alert_value,
595 g_observer->alerts.non_empty_audio_state_changed);
596 ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
597 ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
598 data = reinterpret_cast<struct cras_observer_non_empty_audio_state *>(
599 cras_alert_pending_data_value);
600 EXPECT_EQ(data->non_empty, 1);
601 }
602
603 // Stubs
604 extern "C" {
605
cras_alert_destroy(struct cras_alert * alert)606 void cras_alert_destroy(struct cras_alert *alert) {
607 cras_alert_destroy_called++;
608 }
609
cras_alert_create(cras_alert_prepare prepare,unsigned int flags)610 struct cras_alert *cras_alert_create(cras_alert_prepare prepare,
611 unsigned int flags) {
612 struct cras_alert *alert = NULL;
613
614 cras_alert_create_called++;
615 alert = reinterpret_cast<struct cras_alert*>(cras_alert_create_called);
616 cras_alert_create_return_values.push_back(alert);
617 cras_alert_create_flags_map[alert] = flags;
618 cras_alert_create_prepare_map[alert] = reinterpret_cast<void *>(prepare);
619 return alert;
620 }
621
cras_alert_add_callback(struct cras_alert * alert,cras_alert_cb cb,void * arg)622 int cras_alert_add_callback(struct cras_alert *alert, cras_alert_cb cb,
623 void *arg) {
624 cras_alert_add_callback_map[alert] = reinterpret_cast<void *>(cb);
625 return 0;
626 }
627
cras_alert_pending(struct cras_alert * alert)628 void cras_alert_pending(struct cras_alert *alert) {
629 cras_alert_pending_alert_value = alert;
630 }
631
cras_alert_pending_data(struct cras_alert * alert,void * data,size_t data_size)632 void cras_alert_pending_data(struct cras_alert *alert,
633 void *data, size_t data_size) {
634 cras_alert_pending_alert_value = alert;
635 cras_alert_pending_data_size_value = data_size;
636 if (cras_alert_pending_data_value)
637 free(cras_alert_pending_data_value);
638 if (data) {
639 cras_alert_pending_data_value = malloc(data_size);
640 memcpy(cras_alert_pending_data_value, data, data_size);
641 }
642 else
643 cras_alert_pending_data_value = NULL;
644 }
645
cras_iodev_list_update_device_list()646 void cras_iodev_list_update_device_list() {
647 cras_iodev_list_update_device_list_called++;
648 }
649
650 } // extern "C"
651
652 } // namespace
653
main(int argc,char ** argv)654 int main(int argc, char **argv) {
655 ::testing::InitGoogleTest(&argc, argv);
656 openlog(NULL, LOG_PERROR, LOG_USER);
657 return RUN_ALL_TESTS();
658 }
659